59 const G4int nPerDecade = 10;
65 fLowestKineticEnergy = std::max(tmin, lowestTkin);
66 fHighestKineticEnergy = tmax;
67 if(tmax < 10*fLowestKineticEnergy) {
68 fHighestKineticEnergy = 10*fLowestKineticEnergy;
69 }
else if(tmax > highestTkin) {
70 fHighestKineticEnergy = std::max(highestTkin, 10*fLowestKineticEnergy);
72 fTotBin = (
G4int)(nPerDecade*
73 std::log10(fHighestKineticEnergy/fLowestKineticEnergy));
76 fHighestKineticEnergy,
79 G4cout <<
"### G4PAIModelData: Nbins= " << fTotBin
80 <<
" Tlowest(keV)= " << lowestTkin/keV
81 <<
" Tmin(keV)= " << fLowestKineticEnergy/keV
82 <<
" Tmax(GeV)= " << fHighestKineticEnergy/GeV
91 size_t n = fPAIxscBank.size();
93 for(
size_t i=0; i<n; ++i) {
95 fPAIxscBank[i]->clearAndDestroy();
96 delete fPAIxscBank[i];
99 fPAIdEdxBank[i]->clearAndDestroy();
100 delete fPAIdEdxBank[i];
102 delete fdEdxTable[i];
105 delete fParticleEnergyVector;
120 fHighestKineticEnergy,
126 static const G4double deltaLow = 100.*eV;
128 for (
G4int i = 0; i <= fTotBin; ++i) {
132 G4double tau = kinEnergy/proton_mass_c2;
135 if (Tmax < Tmin + deltaLow ) { Tmax = Tmin + deltaLow; }
137 fPAIySection.
Initialize(mat, Tmax, bg2, &fSandia);
144 for(
G4int k = 0; k < n; ++k) {
158 for(
G4int k = kmin; k < n; ++k)
166 transferVector->
PutValue(k, t, t*tr);
176 if(ionloss < 0.0) ionloss = 0.0;
178 dEdxMeanVector->
PutValue(i,ionloss);
180 PAItransferTable->
insertAt(i,transferVector);
181 PAIdEdxTable->
insertAt(i,dEdxVector);
189 fPAIxscBank.push_back(PAItransferTable);
190 fPAIdEdxBank.push_back(PAIdEdxTable);
197 fdEdxTable.push_back(dEdxMeanVector);
207 size_t iPlace = fParticleEnergyVector->
FindBin(scaledTkin, 0);
215 if(scaledTkin >= fParticleEnergyVector->
Energy(nPlace)) { iPlace = nPlace; }
216 else if(scaledTkin > fParticleEnergyVector->
Energy(0)) {
221 G4double dEdx = fdEdxTable[coupleIndex]->Value(scaledTkin);
222 G4double del = (*(fPAIdEdxBank[coupleIndex]))(iPlace)->Value(cut);
225 G4double del2 = (*(fPAIdEdxBank[coupleIndex]))(iPlace+1)->Value(cut);
237 dEdx = std::max(dEdx, 0.);
251 size_t iPlace = fParticleEnergyVector->
FindBin(scaledTkin, 0);
255 if(scaledTkin >= fParticleEnergyVector->
Energy(nPlace)) { iPlace = nPlace; }
256 else if(scaledTkin > fParticleEnergyVector->
Energy(0)) {
263 cross1 = (*table)(iPlace)->Value(tmax)/tmax;
265 cross2 = (*table)(iPlace)->Value(tcut)/tcut;
267 cross = (cross2-cross1);
270 cross2 = (*table)(iPlace+1)->Value(tcut)/tcut
271 - (*table)(iPlace+1)->Value(tmax)/tmax;
282 cross = std::max(cross, 0.0);
297 size_t iPlace = fParticleEnergyVector->
FindBin(scaledTkin, 0);
301 if(scaledTkin >= fParticleEnergyVector->
Energy(nPlace)) { iPlace = nPlace; }
302 else if(scaledTkin > fParticleEnergyVector->
Energy(0)) {
319 meanN11 = (*v1)[0]/e1;
320 meanN12 = v1->
Value(e2)/e2;
321 meanNumber = (meanN11 - meanN12)*stepFactor;
329 v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+1);
334 meanN21 = (*v2)[0]/e1;
335 meanN22 = v2->
Value(e2)/e2;
339 W1 = (E2 - scaledTkin)*W;
340 W2 = (scaledTkin - E1)*W;
342 meanNumber += (meanN21 - meanN22)*stepFactor*W2;
346 if(meanNumber < 0.0) {
return loss; }
351 if(0 == numOfCollisions) {
return loss; }
354 for(
G4int i=0; i< numOfCollisions; ++i) {
356 position = meanN12 + (meanN11 - meanN12)*rand;
357 omega = GetEnergyTransfer(coupleIndex, iPlace,
position);
360 position = meanN22 + (meanN21 - meanN22)*rand;
361 omega2 = GetEnergyTransfer(coupleIndex, iPlace+1,
position);
368 if(loss > kinEnergy) {
break; }
372 if(loss > kinEnergy) { loss = kinEnergy; }
373 else if(loss < 0.) { loss = 0.; }
393 size_t iPlace = fParticleEnergyVector->
FindBin(scaledTkin, 0);
396 if(scaledTkin >= fParticleEnergyVector->
Energy(nPlace)) { iPlace = nPlace; }
397 else if(scaledTkin > fParticleEnergyVector->
Energy(0)) {
405 if(emax < emin) {
return transfer; }
416 transfer = GetEnergyTransfer(coupleIndex, iPlace,
position);
424 emin = std::max(tmin, v2->
Energy(0));
427 dNdx1 = v2->
Value(emin)/emin;
428 dNdx2 = v2->
Value(emax)/emax;
442 position = dNdx2 + (dNdx1 - dNdx2)*rand;
453 transfer = std::max(transfer, 0.0);
472 G4double x1(0.0), x2(0.0), y1(0.0), y2(0.0), energyTransfer;
475 for(iTransfer=1; iTransfer<=iTransferMax; ++iTransfer) {
476 x2 = v->
Energy(iTransfer);
477 y2 = (*v)[iTransfer]/x2;
479 if(iTransfer == iTransferMax) {
return v->
GetMaxEnergy(); }
482 x1 = v->
Energy(iTransfer-1);
483 y1 = (*v)[iTransfer-1]/x1;
495 const G4int nbins = 5;
498 for(
G4int i=1; i<=nbins; ++i) {
500 y2 = v->
Value(x2)/x2;
510 energyTransfer = (y2 - y1)*x1*x2/(
position*(x1 - x2) - y1*x1 + y2*x2);
516 return energyTransfer;
G4long G4Poisson(G4double mean)
G4GLOB_DLL std::ostream G4cout
const G4Material * GetMaterial() const
G4double DEDXPerVolume(G4int coupleIndex, G4double scaledTkin, G4double cut) const
void Initialise(const G4MaterialCutsCouple *, G4PAIModel *)
G4double SamplePostStepTransfer(G4int coupleIndex, G4double scaledTkin, G4double tmin, G4double tmax) const
G4PAIModelData(G4double tmin, G4double tmax, G4int verbose)
G4double SampleAlongStepTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double tmax, G4double stepFactor) const
G4double CrossSectionPerVolume(G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
G4double ComputeMaxEnergy(G4double scaledEnergy)
G4double GetSplineEnergy(G4int i) const
G4double GetIntegralPAIdEdx(G4int i) const
G4double GetMeanEnergyLoss() const
G4double GetIntegralPAIySection(G4int i) const
G4int GetSplineSize() const
void Initialize(const G4Material *material, G4double maxEnergyTransfer, G4double betaGammaSq, G4SandiaTable *)
void PutValue(std::size_t index, G4double energy, G4double dValue)
void insertAt(std::size_t, G4PhysicsVector *)
G4double Energy(std::size_t index) const
G4double Value(G4double theEnergy, std::size_t &lastidx) const
G4double GetMaxEnergy() const
std::size_t FindBin(const G4double energy, const std::size_t idx) const
void PutValue(std::size_t index, G4double theValue)
std::size_t GetVectorLength() const
void Initialize(const G4Material *)
G4double GetSandiaMatTablePAI(G4int, G4int) const