Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4eDPWAElasticDCS Class Reference

#include <G4eDPWAElasticDCS.hh>

Public Member Functions

 G4eDPWAElasticDCS (G4bool iselectron=true, G4bool isrestricted=false)
 
 ~G4eDPWAElasticDCS ()
 
void InitialiseForZ (std::size_t iz)
 
void ComputeCSPerAtom (G4int iz, G4double ekin, G4double &elcs, G4double &tr1cs, G4double &tr2cs, G4double mumin=0.0, G4double mumax=1.0)
 
G4double SampleCosineTheta (std::size_t iz, G4double lekin, G4double r1, G4double r2, G4double r3)
 
G4double SampleCosineThetaRestricted (std::size_t iz, G4double lekin, G4double r1, G4double r2, G4double costMax, G4double costMin)
 
G4double ComputeScatteringPowerCorrection (const G4MaterialCutsCouple *matcut, G4double ekin)
 
void InitSCPCorrection (G4double lowEnergyLimit, G4double highEnergyLimit)
 

Detailed Description

Definition at line 106 of file G4eDPWAElasticDCS.hh.

Constructor & Destructor Documentation

◆ G4eDPWAElasticDCS()

G4eDPWAElasticDCS::G4eDPWAElasticDCS ( G4bool  iselectron = true,
G4bool  isrestricted = false 
)

Definition at line 82 of file G4eDPWAElasticDCS.cc.

83: fIsRestrictedSamplingRequired(isrestricted), fIsElectron(iselectron) {
84 fDCS.resize(gMaxZ+1, nullptr);
85 fDCSLow.resize(gMaxZ+1, nullptr);
86 fSamplingTables.resize(gMaxZ+1, nullptr);
87}

◆ ~G4eDPWAElasticDCS()

G4eDPWAElasticDCS::~G4eDPWAElasticDCS ( )

Definition at line 91 of file G4eDPWAElasticDCS.cc.

91 {
92 for (std::size_t i=0; i<fDCS.size(); ++i) {
93 if (fDCS[i]) delete fDCS[i];
94 }
95 for (std::size_t i=0; i<fDCSLow.size(); ++i) {
96 if (fDCSLow[i]) delete fDCSLow[i];
97 }
98 for (std::size_t i=0; i<fSamplingTables.size(); ++i) {
99 if (fSamplingTables[i]) delete fSamplingTables[i];
100 }
101 // clear scp correction data
102 for (std::size_t imc=0; imc<fSCPCPerMatCuts.size(); ++imc) {
103 if (fSCPCPerMatCuts[imc]) {
104 fSCPCPerMatCuts[imc]->fVSCPC.clear();
105 delete fSCPCPerMatCuts[imc];
106 }
107 }
108 fSCPCPerMatCuts.clear();
109}

Member Function Documentation

◆ ComputeCSPerAtom()

void G4eDPWAElasticDCS::ComputeCSPerAtom ( G4int  iz,
G4double  ekin,
G4double elcs,
G4double tr1cs,
G4double tr2cs,
G4double  mumin = 0.0,
G4double  mumax = 1.0 
)

Definition at line 270 of file G4eDPWAElasticDCS.cc.

272 {
273 // init all cross section values to zero;
274 elcs = 0.0;
275 tr1cs = 0.0;
276 tr2cs = 0.0;
277 // make sure that mu(theta) = 0.5[1-cos(theta)] limits have appropriate vals
278 mumin = std::max(0.0, std::min(1.0, mumin));
279 mumax = std::max(0.0, std::min(1.0, mumax));
280 if (mumin>=mumax) return;
281 // make sure that kin. energy is within the available range (10 eV-100MeV)
282 const G4double lekin = std::max(gTheEnergies[0], std::min(gTheEnergies[gNumEnergies-1], G4Log(ekin)));
283 // if the lower, denser in theta, DCS set should be used
284 const G4bool isLowerGrid = (fIsElectron && lekin<gTheEnergies[gIndxEnergyLim]);
285 const std::vector<G4double>& theMuVector = (isLowerGrid) ? gTheMus1 : gTheMus2;
286 const G4Physics2DVector* the2DDCS = (isLowerGrid) ? fDCSLow[iz] : fDCS[iz];
287 // find lower/upper mu bin of integration:
288 // 0.0 <= mumin < 1.0 for sure here
289 const std::size_t iMuStart = (mumin == 0.0) ? 0 : std::distance( theMuVector.begin(), std::upper_bound(theMuVector.begin(), theMuVector.end(), mumin) )-1 ;
290 // 0.0 < mumax <= 1.0 for sure here
291 const std::size_t iMuEnd = (mumax == 1.0) ? theMuVector.size()-2 : std::distance( theMuVector.begin(), std::upper_bound(theMuVector.begin(), theMuVector.end(), mumax) )-1 ;
292 // perform numerical integration of the DCS over the given [mumin, mumax]
293 // interval (where mu(theta) = 0.5[1-cos(theta)]) to get the elastic, first
294 std::size_t ix = 0;
295 std::size_t iy = 0;
296 for (std::size_t imu=iMuStart; imu<=iMuEnd; ++imu) {
297 G4double elcsPar = 0.0;
298 G4double tr1csPar = 0.0;
299 G4double tr2csPar = 0.0;
300 const G4double low = (imu==iMuStart) ? mumin : theMuVector[imu];
301 const G4double del = (imu==iMuEnd) ? mumax-low : theMuVector[imu+1]-low;
302 ix = imu;
303 for (std::size_t igl=0; igl<8; ++igl) {
304 const double mu = low + del*gXGL[igl];
305 const double dcs = G4Exp(the2DDCS->Value(mu, lekin, ix, iy));
306 elcsPar += gWGL[igl]*dcs; // elastic
307 tr1csPar += gWGL[igl]*dcs*mu; // first transport
308 tr2csPar += gWGL[igl]*dcs*mu*(1.0-mu); // second transport
309 }
310 elcs += del*elcsPar;
311 tr1cs += del*tr1csPar;
312 tr2cs += del*tr2csPar;
313 }
314 elcs *= 2.0*CLHEP::twopi;
315 tr1cs *= 4.0*CLHEP::twopi;
316 tr2cs *= 12.0*CLHEP::twopi;
317}
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
G4double G4Log(G4double x)
Definition: G4Log.hh:227
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
G4double Value(G4double x, G4double y, std::size_t &lastidx, std::size_t &lastidy) const

Referenced by G4eDPWACoulombScatteringModel::ComputeCrossSectionPerAtom().

◆ ComputeScatteringPowerCorrection()

G4double G4eDPWAElasticDCS::ComputeScatteringPowerCorrection ( const G4MaterialCutsCouple matcut,
G4double  ekin 
)

Definition at line 573 of file G4eDPWAElasticDCS.cc.

574 {
575 const G4int imc = matcut->GetIndex();
576 G4double corFactor = 1.0;
577 if (!(fSCPCPerMatCuts[imc]->fIsUse) || ekin<=fSCPCPerMatCuts[imc]->fPrCut) {
578 return corFactor;
579 }
580 // get the scattering power correction factor
581 const G4double lekin = G4Log(ekin);
582 G4double remaining = (lekin-fSCPCPerMatCuts[imc]->fLEmin)*fSCPCPerMatCuts[imc]->fILDel;
583 std::size_t lindx = (G4int)remaining;
584 remaining -= lindx;
585 std::size_t imax = fSCPCPerMatCuts[imc]->fVSCPC.size()-1;
586 if (lindx>=imax) {
587 corFactor = fSCPCPerMatCuts[imc]->fVSCPC[imax];
588 } else {
589 corFactor = fSCPCPerMatCuts[imc]->fVSCPC[lindx] + remaining*(fSCPCPerMatCuts[imc]->fVSCPC[lindx+1]-fSCPCPerMatCuts[imc]->fVSCPC[lindx]);
590 }
591 return corFactor;
592}
int G4int
Definition: G4Types.hh:85

Referenced by G4eDPWACoulombScatteringModel::ComputeCrossSectionPerAtom().

◆ InitialiseForZ()

void G4eDPWAElasticDCS::InitialiseForZ ( std::size_t  iz)

Definition at line 114 of file G4eDPWAElasticDCS.cc.

114 {
115 if (!gIsGridLoaded) {
116 LoadGrid();
117 }
118 LoadDCSForZ((G4int)iz);
119 BuildSmplingTableForZ((G4int)iz);
120}

Referenced by G4eDPWACoulombScatteringModel::Initialise().

◆ InitSCPCorrection()

void G4eDPWAElasticDCS::InitSCPCorrection ( G4double  lowEnergyLimit,
G4double  highEnergyLimit 
)

Definition at line 595 of file G4eDPWAElasticDCS.cc.

596 {
597 // get the material-cuts table
599 std::size_t numMatCuts = thePCTable->GetTableSize();
600 // clear container if any
601 for (std::size_t imc=0; imc<fSCPCPerMatCuts.size(); ++imc) {
602 if (fSCPCPerMatCuts[imc]) {
603 fSCPCPerMatCuts[imc]->fVSCPC.clear();
604 delete fSCPCPerMatCuts[imc];
605 fSCPCPerMatCuts[imc] = nullptr;
606 }
607 }
608 //
609 // set size of the container and create the corresponding data structures
610 fSCPCPerMatCuts.resize(numMatCuts,nullptr);
611 // loop over the material-cuts and create scattering power correction data structure for each
612 for (G4int imc=0; imc<(G4int)numMatCuts; ++imc) {
613 const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
614 const G4Material* mat = matCut->GetMaterial();
615 // get e- production cut in the current material-cuts in energy
616 const G4double ecut = (*(thePCTable->GetEnergyCutsVector(idxG4ElectronCut)))[matCut->GetIndex()];
617 const G4double limit = fIsElectron ? 2.0*ecut : ecut;
618 const G4double min = std::max(limit,lowEnergyLimit);
619 const G4double max = highEnergyLimit;
620 if (min>=max) {
621 fSCPCPerMatCuts[imc] = new SCPCorrection();
622 fSCPCPerMatCuts[imc]->fIsUse = false;
623 fSCPCPerMatCuts[imc]->fPrCut = min;
624 continue;
625 }
626 G4int numEbins = fNumSPCEbinPerDec*G4lrint(std::log10(max/min));
627 numEbins = std::max(numEbins,3);
628 const G4double lmin = G4Log(min);
629 const G4double ldel = G4Log(max/min)/(numEbins-1.0);
630 fSCPCPerMatCuts[imc] = new SCPCorrection();
631 fSCPCPerMatCuts[imc]->fVSCPC.resize(numEbins,1.0);
632 fSCPCPerMatCuts[imc]->fIsUse = true;
633 fSCPCPerMatCuts[imc]->fPrCut = min;
634 fSCPCPerMatCuts[imc]->fLEmin = lmin;
635 fSCPCPerMatCuts[imc]->fILDel = 1./ldel;
636 // compute Moliere material dependet parameetrs
637 G4double moliereBc = 0.0;
638 G4double moliereXc2 = 0.0;
639 ComputeMParams(mat, moliereBc, moliereXc2);
640 // compute scattering power correction over the enrgy grid
641 for (G4int ie=0; ie<numEbins; ++ie) {
642 const G4double ekin = G4Exp(lmin+ie*ldel);
643 G4double scpCorr = 1.0;
644 // compute correction factor: I.Kawrakow, Med.Phys.24,505-517(1997)(Eqs(32-37)
645 if (ie>0) {
646 const G4double tau = ekin/CLHEP::electron_mass_c2;
647 const G4double tauCut = ecut/CLHEP::electron_mass_c2;
648 // Moliere's screening parameter
649 const G4double A = moliereXc2/(4.0*tau*(tau+2.)*moliereBc);
650 const G4double gr = (1.+2.*A)*G4Log(1.+1./A)-2.;
651 const G4double dum0 = (tau+2.)/(tau+1.);
652 const G4double dum1 = tau+1.;
653 G4double gm = G4Log(0.5*tau/tauCut) + (1.+dum0*dum0)*G4Log(2.*(tau-tauCut+2.)/(tau+4.))
654 - 0.25*(tau+2.)*( tau+2.+2.*(2.*tau+1.)/(dum1*dum1))*
655 G4Log((tau+4.)*(tau-tauCut)/tau/(tau-tauCut+2.))
656 + 0.5*(tau-2*tauCut)*(tau+2.)*(1./(tau-tauCut)-1./(dum1*dum1));
657 if (gm<gr) {
658 gm = gm/gr;
659 } else {
660 gm = 1.;
661 }
662 const G4double z0 = matCut->GetMaterial()->GetIonisation()->GetZeffective();
663 scpCorr = 1.-gm*z0/(z0*(z0+1.));
664 }
665 fSCPCPerMatCuts[imc]->fVSCPC[ie] = scpCorr;
666 }
667 }
668}
@ idxG4ElectronCut
const G4double A[17]
G4double GetZeffective() const
const G4Material * GetMaterial() const
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:221
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
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
int G4lrint(double ad)
Definition: templates.hh:134

Referenced by G4eDPWACoulombScatteringModel::Initialise().

◆ SampleCosineTheta()

G4double G4eDPWAElasticDCS::SampleCosineTheta ( std::size_t  iz,
G4double  lekin,
G4double  r1,
G4double  r2,
G4double  r3 
)

Definition at line 405 of file G4eDPWAElasticDCS.cc.

406 {
407 lekin = std::max(gTheEnergies[0], std::min(gTheEnergies[gNumEnergies-1], lekin));
408 // determine the discrete ekin sampling table to be used:
409 // - statistical interpolation (i.e. linear) on log energy scale
410 const G4double rem = (lekin-gLogMinEkin)*gInvDelLogEkin;
411 const auto k = (std::size_t)rem;
412 const std::size_t iekin = (r1 < rem-k) ? k+1 : k;
413 // sample the mu(t)=0.5(1-cos(t))
414 const double mu = SampleMu(iz, iekin, r2, r3);
415 return std::max(-1.0, std::min(1.0, 1.0-2.0*mu));
416}

Referenced by G4eDPWACoulombScatteringModel::SampleSecondaries().

◆ SampleCosineThetaRestricted()

G4double G4eDPWAElasticDCS::SampleCosineThetaRestricted ( std::size_t  iz,
G4double  lekin,
G4double  r1,
G4double  r2,
G4double  costMax,
G4double  costMin 
)

Definition at line 428 of file G4eDPWAElasticDCS.cc.

430 {
431 // costMin corresponds to mu-max while costMax to mu-min: mu(t)=0.5[1-cos(t)]
432 lekin = std::max(gTheEnergies[0], std::min(gTheEnergies[gNumEnergies-1], lekin));
433 // determine the discrete ekin sampling table to be used:
434 // - statistical interpolation (i.e. linear) on log energy scale
435 const G4double rem = (lekin-gLogMinEkin)*gInvDelLogEkin;
436 const auto k = (size_t)rem;
437 const std::size_t iekin = (r1 < rem-k) ? k : k+1;
438 // sample the mu(t)=0.5(1-cos(t))
439 const G4double mu = SampleMu(iz, iekin, r2, 0.5*(1.0-costMax), 0.5*(1.0-costMin));
440 return std::max(-1.0, std::min(1.0, 1.0-2.0*mu));
441}

Referenced by G4eDPWACoulombScatteringModel::SampleSecondaries().


The documentation for this class was generated from the following files: