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);
468 if(position*v->
Energy(0) >= (*v)[0]) {
return v->
Energy(0); }
476 for(iTransfer=1; iTransfer<=iTransferMax; ++iTransfer) {
478 y2 = (*v)[iTransfer]/
x2;
479 if(position >=
y2) {
break; }
480 if(iTransfer == iTransferMax) {
return v->
GetMaxEnergy(); }
484 y1 = (*v)[iTransfer-1]/
x1;
496 const G4int nbins = 5;
499 for(
G4int i=1; i<=nbins; ++i) {
517 return energyTransfer;
G4double Energy(size_t index) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
Float_t y1[n_points_granero]
static constexpr double keV
Float_t x1[n_points_granero]
static const G4double emax
G4double SamplePostStepTransfer(G4int coupleIndex, G4double scaledTkin, G4double tmin, G4double tmax) const
void insertAt(size_t, G4PhysicsVector *)
G4double Value(G4double theEnergy, size_t &lastidx) const
G4double GetEnergyTransfer(G4int coupleIndex, size_t iPlace, G4double position) const
Float_t y2[n_points_geant4]
static constexpr double proton_mass_c2
static constexpr double TeV
G4double DEDXPerVolume(G4int coupleIndex, G4double scaledTkin, G4double cut) const
void Initialise(const G4MaterialCutsCouple *, G4PAIModel *)
G4double ComputeMaxEnergy(G4double scaledEnergy)
G4PAIModelData(G4double tmin, G4double tmax, G4int verbose)
G4double CrossSectionPerVolume(G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
static constexpr double eV
G4double SampleAlongStepTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double tmax, G4double stepFactor) const
G4double GetMaxEnergy() const
G4GLOB_DLL std::ostream G4cout
G4long G4Poisson(G4double mean)
const G4Material * GetMaterial() const
void PutValue(size_t index, G4double energy, G4double dataValue)
Float_t x2[n_points_geant4]
const XML_Char XML_Content * model
static constexpr double GeV
void PutValue(size_t index, G4double theValue)
size_t GetVectorLength() const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments