60 const G4int nPerDecade = 10;
64 fPAIySection.SetVerbose(ver);
66 fLowestKineticEnergy =
std::max(tmin, lowestTkin);
67 fHighestKineticEnergy = tmax;
68 if(tmax < 10*fLowestKineticEnergy) {
69 fHighestKineticEnergy = 10*fLowestKineticEnergy;
70 }
else if(tmax > highestTkin) {
71 fHighestKineticEnergy =
std::max(highestTkin, 10*fLowestKineticEnergy);
73 fTotBin = (
G4int)(nPerDecade*
74 std::log10(fHighestKineticEnergy/fLowestKineticEnergy));
77 fHighestKineticEnergy,
80 G4cout <<
"### G4PAIModelData: Nbins= " << fTotBin
81 <<
" Tlowest(keV)= " << lowestTkin/
keV
82 <<
" Tmin(keV)= " << fLowestKineticEnergy/
keV
83 <<
" Tmax(GeV)= " << fHighestKineticEnergy/
GeV
92 size_t n = fPAIxscBank.size();
94 for(
size_t i=0; i<
n; ++i) {
96 fPAIxscBank[i]->clearAndDestroy();
97 delete fPAIxscBank[i];
100 fPAIdEdxBank[i]->clearAndDestroy();
101 delete fPAIdEdxBank[i];
103 delete fdEdxTable[i];
106 delete fParticleEnergyVector;
115 fSandia.Initialize(const_cast<G4Material*>(mat));
121 fHighestKineticEnergy,
124 G4double Tmin = fSandia.GetSandiaMatTablePAI(0,0);
129 for (
G4int i = 0; i <= fTotBin; ++i) {
131 G4double kinEnergy = fParticleEnergyVector->Energy(i);
136 if (Tmax < Tmin + deltaLow ) { Tmax = Tmin + deltaLow; }
138 fPAIySection.Initialize(mat, Tmax, bg2, &fSandia);
143 G4int n = fPAIySection.GetSplineSize();
145 for(
G4int k = 0; k <
n; ++k) {
146 if(fPAIySection.GetIntegralPAIySection(k+1) <= 0.0) {
159 for(
G4int k = kmin; k <
n; ++k)
161 G4double t = fPAIySection.GetSplineEnergy(k+1);
162 tr = fPAIySection.GetIntegralPAIySection(k+1);
167 transferVector->
PutValue(k, t, t*tr);
168 dEdxVector->
PutValue(k, t, fPAIySection.GetIntegralPAIdEdx(k+1));
175 G4double ionloss = fPAIySection.GetMeanEnergyLoss();
177 if(ionloss < 0.0) ionloss = 0.0;
179 dEdxMeanVector->
PutValue(i,ionloss);
181 PAItransferTable->
insertAt(i,transferVector);
182 PAIdEdxTable->
insertAt(i,dEdxVector);
190 fPAIxscBank.push_back(PAItransferTable);
191 fPAIdEdxBank.push_back(PAIdEdxTable);
198 fdEdxTable.push_back(dEdxMeanVector);
208 size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
209 size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
216 if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
217 else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
222 G4double dEdx = fdEdxTable[coupleIndex]->Value(scaledTkin);
223 G4double del = (*(fPAIdEdxBank[coupleIndex]))(iPlace)->Value(cut);
226 G4double del2 = (*(fPAIdEdxBank[coupleIndex]))(iPlace+1)->Value(cut);
227 G4double E1 = fParticleEnergyVector->Energy(iPlace);
228 G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
252 size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
253 size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
256 if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
257 else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
264 cross1 = (*table)(iPlace)->Value(tmax)/tmax;
266 cross2 = (*table)(iPlace)->Value(tcut)/tcut;
268 cross = (cross2-cross1);
271 cross2 = (*table)(iPlace+1)->Value(tcut)/tcut
272 - (*table)(iPlace+1)->Value(tmax)/tmax;
274 G4double E1 = fParticleEnergyVector->Energy(iPlace);
275 G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
298 size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
299 size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
302 if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
303 else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
320 meanN11 = (*v1)[0]/e1;
321 meanN12 = v1->
Value(e2)/e2;
322 meanNumber = (meanN11 - meanN12)*stepFactor;
330 v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+1);
335 meanN21 = (*v2)[0]/e1;
336 meanN22 = v2->
Value(e2)/e2;
337 G4double E1 = fParticleEnergyVector->Energy(iPlace);
338 G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
340 W1 = (E2 - scaledTkin)*W;
341 W2 = (scaledTkin - E1)*W;
343 meanNumber += (meanN21 - meanN22)*stepFactor*W2;
347 if(meanNumber < 0.0) {
return loss; }
352 if(0 == numOfCollisions) {
return loss; }
355 for(
G4int i=0; i< numOfCollisions; ++i) {
357 position = meanN12 + (meanN11 - meanN12)*rand;
358 omega = GetEnergyTransfer(coupleIndex, iPlace, position);
361 position = meanN22 + (meanN21 - meanN22)*rand;
362 omega2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
369 if(loss > kinEnergy) {
break; }
373 if(loss > kinEnergy) { loss = kinEnergy; }
374 else if(loss < 0.) { loss = 0.; }
393 size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
394 size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
397 if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
398 else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
406 if(emax < emin) {
return transfer; }
417 transfer = GetEnergyTransfer(coupleIndex, iPlace, position);
428 dNdx1 = v2->
Value(emin)/emin;
434 G4double E1 = fParticleEnergyVector->Energy(iPlace);
435 G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
443 position = dNdx2 + (dNdx1 - dNdx2)*rand;
444 G4double tr2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
463 G4double G4PAIModelData::GetEnergyTransfer(
G4int coupleIndex,
468 if(position*v->
Energy(0) >= (*v)[0]) {
return v->
Energy(0); }
473 G4double x1(0.0), x2(0.0), y1(0.0), y2(0.0), energyTransfer;
476 for(iTransfer=1; iTransfer<=iTransferMax; ++iTransfer) {
477 x2 = v->
Energy(iTransfer);
478 y2 = (*v)[iTransfer]/x2;
479 if(position >= y2) {
break; }
480 if(iTransfer == iTransferMax) {
return v->
GetMaxEnergy(); }
483 x1 = v->
Energy(iTransfer-1);
484 y1 = (*v)[iTransfer-1]/x1;
496 const G4int nbins = 5;
499 for(
G4int i=1; i<=nbins; ++i) {
501 y2 = v->
Value(x2)/x2;
511 energyTransfer = (y2 - y1)*x1*x2/(position*(x1 - x2) - y1*x1 + y2*x2);
517 return energyTransfer;
G4long G4Poisson(G4double mean)
G4double GetMaxEnergy() const
static constexpr double proton_mass_c2
void PutValue(size_t index, G4double energy, G4double dataValue)
size_t GetVectorLength() const
G4double SampleAlongStepTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double tmax, G4double stepFactor) const
static constexpr double TeV
G4double DEDXPerVolume(G4int coupleIndex, G4double scaledTkin, G4double cut) const
G4GLOB_DLL std::ostream G4cout
void PutValue(size_t index, G4double theValue)
static constexpr double eV
G4double Energy(size_t index) const
G4double Value(G4double theEnergy, size_t &lastidx) const
static const G4double emax
G4double CrossSectionPerVolume(G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static constexpr double GeV
void insertAt(size_t, G4PhysicsVector *)
G4double SamplePostStepTransfer(G4int coupleIndex, G4double scaledTkin, G4double tmin, G4double tmax) const
void Initialise(const G4MaterialCutsCouple *, G4PAIModel *)
static constexpr double keV
const XML_Char XML_Content * model
G4PAIModelData(G4double tmin, G4double tmax, G4int verbose)
G4double ComputeMaxEnergy(G4double scaledEnergy)
const G4Material * GetMaterial() const