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

#include <G4GoudsmitSaundersonTable.hh>

Classes

struct  GSMSCAngularDtr
 

Public Member Functions

 G4GoudsmitSaundersonTable (G4bool iselectron)
 
 ~G4GoudsmitSaundersonTable ()
 
void Initialise (G4double lownergylimit, G4double highenergylimit)
 
void LoadMSCData ()
 
G4bool Sampling (G4double lambdaval, G4double qval, G4double scra, G4double &cost, G4double &sint, G4double lekin, G4double beta2, G4int matindx, GSMSCAngularDtr **gsDtr, G4int &mcekini, G4int &mcdelti, G4double &transfPar, G4bool isfirst)
 
G4double SampleCosTheta (G4double lambdaval, G4double qval, G4double scra, G4double lekin, G4double beta2, G4int matindx, GSMSCAngularDtr **gsDtr, G4int &mcekini, G4int &mcdelti, G4double &transfPar, G4bool isfirst)
 
G4double SampleGSSRCosTheta (const GSMSCAngularDtr *gsDrt, G4double transfpar)
 
G4double SingleScattering (G4double lambdaval, G4double scra, G4double lekin, G4double beta2, G4int matindx)
 
GSMSCAngularDtrGetGSAngularDtr (G4double scra, G4double &lambdaval, G4double &qval, G4double &transfpar)
 
G4double GetMoliereBc (G4int matindx)
 
G4double GetMoliereXc2 (G4int matindx)
 
void GetMottCorrectionFactors (G4double logekin, G4double beta2, G4int matindx, G4double &mcToScr, G4double &mcToQ1, G4double &mcToG2PerG1)
 
void SetOptionMottCorrection (G4bool val)
 
void SetOptionPWACorrection (G4bool val)
 
G4double ComputeScatteringPowerCorrection (const G4MaterialCutsCouple *matcut, G4double ekin)
 
void InitSCPCorrection ()
 

Detailed Description

Definition at line 83 of file G4GoudsmitSaundersonTable.hh.

Constructor & Destructor Documentation

◆ G4GoudsmitSaundersonTable()

G4GoudsmitSaundersonTable::G4GoudsmitSaundersonTable ( G4bool  iselectron)

Definition at line 111 of file G4GoudsmitSaundersonTable.cc.

111 {
112 fIsElectron = iselectron;
113 // set initial values: final values will be set in the Initialize method
114 fLogLambda0 = 0.; // will be set properly at init.
115 fLogDeltaLambda = 0.; // will be set properly at init.
116 fInvLogDeltaLambda = 0.; // will be set properly at init.
117 fInvDeltaQ1 = 0.; // will be set properly at init.
118 fDeltaQ2 = 0.; // will be set properly at init.
119 fInvDeltaQ2 = 0.; // will be set properly at init.
120 //
121 fLowEnergyLimit = 0.1*CLHEP::keV; // will be set properly at init.
122 fHighEnergyLimit = 100.0*CLHEP::MeV; // will be set properly at init.
123 //
124 fIsMottCorrection = false; // will be set properly at init.
125 fIsPWACorrection = false; // will be set properly at init.
126 fMottCorrection = nullptr;
127 //
128 fNumSPCEbinPerDec = 3;
129}

◆ ~G4GoudsmitSaundersonTable()

G4GoudsmitSaundersonTable::~G4GoudsmitSaundersonTable ( )

Definition at line 131 of file G4GoudsmitSaundersonTable.cc.

131 {
132 for (size_t i=0; i<gGSMSCAngularDistributions1.size(); ++i) {
133 if (gGSMSCAngularDistributions1[i]) {
134 delete [] gGSMSCAngularDistributions1[i]->fUValues;
135 delete [] gGSMSCAngularDistributions1[i]->fParamA;
136 delete [] gGSMSCAngularDistributions1[i]->fParamB;
137 delete gGSMSCAngularDistributions1[i];
138 }
139 }
140 gGSMSCAngularDistributions1.clear();
141 for (size_t i=0; i<gGSMSCAngularDistributions2.size(); ++i) {
142 if (gGSMSCAngularDistributions2[i]) {
143 delete [] gGSMSCAngularDistributions2[i]->fUValues;
144 delete [] gGSMSCAngularDistributions2[i]->fParamA;
145 delete [] gGSMSCAngularDistributions2[i]->fParamB;
146 delete gGSMSCAngularDistributions2[i];
147 }
148 }
149 gGSMSCAngularDistributions2.clear();
150 if (fMottCorrection) {
151 delete fMottCorrection;
152 fMottCorrection = nullptr;
153 }
154 // clear scp correction data
155 for (size_t imc=0; imc<fSCPCPerMatCuts.size(); ++imc) {
156 if (fSCPCPerMatCuts[imc]) {
157 fSCPCPerMatCuts[imc]->fVSCPC.clear();
158 delete fSCPCPerMatCuts[imc];
159 }
160 }
161 fSCPCPerMatCuts.clear();
162 //
163 gIsInitialised = false;
164}

Member Function Documentation

◆ ComputeScatteringPowerCorrection()

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

Definition at line 611 of file G4GoudsmitSaundersonTable.cc.

611 {
612 G4int imc = matcut->GetIndex();
613 G4double corFactor = 1.0;
614 if (!(fSCPCPerMatCuts[imc]->fIsUse) || ekin<=fSCPCPerMatCuts[imc]->fPrCut) {
615 return corFactor;
616 }
617 // get the scattering power correction factor
618 G4double lekin = G4Log(ekin);
619 G4double remaining = (lekin-fSCPCPerMatCuts[imc]->fLEmin)*fSCPCPerMatCuts[imc]->fILDel;
620 G4int lindx = (G4int)remaining;
621 remaining -= lindx;
622 G4int imax = fSCPCPerMatCuts[imc]->fVSCPC.size()-1;
623 if (lindx>=imax) {
624 corFactor = fSCPCPerMatCuts[imc]->fVSCPC[imax];
625 } else {
626 corFactor = fSCPCPerMatCuts[imc]->fVSCPC[lindx] + remaining*(fSCPCPerMatCuts[imc]->fVSCPC[lindx+1]-fSCPCPerMatCuts[imc]->fVSCPC[lindx]);
627 }
628 return corFactor;
629}
G4double G4Log(G4double x)
Definition: G4Log.hh:226
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85

Referenced by G4GoudsmitSaundersonMscModel::GetTransportMeanFreePath().

◆ GetGSAngularDtr()

G4GoudsmitSaundersonTable::GSMSCAngularDtr * G4GoudsmitSaundersonTable::GetGSAngularDtr ( G4double  scra,
G4double lambdaval,
G4double qval,
G4double transfpar 
)

Definition at line 359 of file G4GoudsmitSaundersonTable.cc.

360 {
361 GSMSCAngularDtr *dtr = nullptr;
362 G4bool first = false;
363 // isotropic cost above gQMAX2 (i.e. dtr stays nullptr)
364 if (qval<gQMAX2) {
365 G4int lamIndx = -1; // lambda value index
366 G4int qIndx = -1; // lambda value index
367 // init to second grid Q values
368 G4int numQVal = gQNUM2;
369 G4double minQVal = gQMIN2;
370 G4double invDelQ = fInvDeltaQ2;
371 G4double pIndxH = 0.; // probability of taking higher index
372 // check if first or second grid needs to be used
373 if (qval<gQMIN2) { // first grid
374 first = true;
375 // protect against qval<gQMIN1
376 if (qval<gQMIN1) {
377 qval = gQMIN1;
378 qIndx = 0;
379 //pIndxH = 0.;
380 }
381 // set to first grid Q values
382 numQVal = gQNUM1;
383 minQVal = gQMIN1;
384 invDelQ = fInvDeltaQ1;
385 }
386 // make sure that lambda = s/lambda_el is in [gLAMBMIN,gLAMBMAX)
387 // lambda<gLAMBMIN=1 is already handeled before so lambda>= gLAMBMIN for sure
388 if (lambdaval>=gLAMBMAX) {
389 lambdaval = gLAMBMAX-1.e-8;
390 lamIndx = gLAMBNUM-1;
391 }
392 G4double lLambda = G4Log(lambdaval);
393 //
394 // determine lower lambda (=s/lambda_el) index: linear interp. on log(lambda) scale
395 if (lamIndx<0) {
396 pIndxH = (lLambda-fLogLambda0)*fInvLogDeltaLambda;
397 lamIndx = (G4int)(pIndxH); // lower index of the lambda bin
398 pIndxH = pIndxH-lamIndx; // probability of taking the higher index distribution
399 if (G4UniformRand()<pIndxH) {
400 ++lamIndx;
401 }
402 }
403 //
404 // determine lower Q (=s/lambda_el G1) index: linear interp. on Q
405 if (qIndx<0) {
406 pIndxH = (qval-minQVal)*invDelQ;
407 qIndx = (G4int)(pIndxH); // lower index of the Q bin
408 pIndxH = pIndxH-qIndx;
409 if (G4UniformRand()<pIndxH) {
410 ++qIndx;
411 }
412 }
413 // set indx
414 G4int indx = lamIndx*numQVal+qIndx;
415 if (first) {
416 dtr = gGSMSCAngularDistributions1[indx];
417 } else {
418 dtr = gGSMSCAngularDistributions2[indx];
419 }
420 // dtr might be nullptr that indicates isotropic cot distribution because:
421 // - if the selected lamIndx, qIndx correspond to L(=s/lambda_el) and Q(=s/lambda_el G1) such that G1(=Q/L) > 1
422 // G1 should always be < 1 and if G1 is ~1 -> the dtr is isotropic (this can only happen in case of the 2. grid)
423 //
424 // compute the transformation parameter
425 if (lambdaval>10.0) {
426 transfpar = 0.5*(-2.77164+lLambda*( 2.94874-lLambda*(0.1535754-lLambda*0.00552888) ));
427 } else {
428 transfpar = 0.5*(1.347+lLambda*(0.209364-lLambda*(0.45525-lLambda*(0.50142-lLambda*0.081234))));
429 }
430 transfpar *= (lambdaval+4.0)*scra;
431 }
432 // return with the selected GS angular distribution that we need to sample cost from (if nullptr => isotropic cost)
433 return dtr;
434}
bool G4bool
Definition: G4Types.hh:86
#define G4UniformRand()
Definition: Randomize.hh:52

Referenced by SampleCosTheta().

◆ GetMoliereBc()

G4double G4GoudsmitSaundersonTable::GetMoliereBc ( G4int  matindx)
inline

◆ GetMoliereXc2()

G4double G4GoudsmitSaundersonTable::GetMoliereXc2 ( G4int  matindx)
inline

◆ GetMottCorrectionFactors()

void G4GoudsmitSaundersonTable::GetMottCorrectionFactors ( G4double  logekin,
G4double  beta2,
G4int  matindx,
G4double mcToScr,
G4double mcToQ1,
G4double mcToG2PerG1 
)

Definition at line 543 of file G4GoudsmitSaundersonTable.cc.

545 {
546 if (fIsMottCorrection) {
547 fMottCorrection->GetMottCorrectionFactors(logekin, beta2, matindx, mcToScr, mcToQ1, mcToG2PerG1);
548 }
549}

Referenced by G4GoudsmitSaundersonMscModel::CrossSectionPerVolume(), and G4GoudsmitSaundersonMscModel::GetTransportMeanFreePath().

◆ Initialise()

void G4GoudsmitSaundersonTable::Initialise ( G4double  lownergylimit,
G4double  highenergylimit 
)

Definition at line 166 of file G4GoudsmitSaundersonTable.cc.

166 {
167 fLowEnergyLimit = lownergylimit;
168 fHighEnergyLimit = highenergylimit;
169 G4double lLambdaMin = G4Log(gLAMBMIN);
170 G4double lLambdaMax = G4Log(gLAMBMAX);
171 fLogLambda0 = lLambdaMin;
172 fLogDeltaLambda = (lLambdaMax-lLambdaMin)/(gLAMBNUM-1.);
173 fInvLogDeltaLambda = 1./fLogDeltaLambda;
174 fInvDeltaQ1 = 1./((gQMAX1-gQMIN1)/(gQNUM1-1.));
175 fDeltaQ2 = (gQMAX2-gQMIN2)/(gQNUM2-1.);
176 fInvDeltaQ2 = 1./fDeltaQ2;
177 // load precomputed angular distributions and set up several values used during the sampling
178 // these are particle independet => they go to static container: load them only onece
179 if (!gIsInitialised) {
180 // load pre-computed GS angular distributions (computed based on Screened-Rutherford DCS)
181 LoadMSCData();
182 gIsInitialised = true;
183 }
184 InitMoliereMSCParams();
185 // Mott-correction: particle(e- or e+) dependet so init them
186 if (fIsMottCorrection) {
187 if (!fMottCorrection) {
188 fMottCorrection = new G4GSMottCorrection(fIsElectron);
189 }
190 fMottCorrection->Initialise();
191 }
192 // init scattering power correction data; used only together with Mott-correction
193 // (Moliere's parameters must be initialised before)
194 if (fMottCorrection) {
196 }
197}

Referenced by G4GoudsmitSaundersonMscModel::Initialise().

◆ InitSCPCorrection()

void G4GoudsmitSaundersonTable::InitSCPCorrection ( )

Definition at line 632 of file G4GoudsmitSaundersonTable.cc.

632 {
633 // get the material-cuts table
635 size_t numMatCuts = thePCTable->GetTableSize();
636 // clear container if any
637 for (size_t imc=0; imc<fSCPCPerMatCuts.size(); ++imc) {
638 if (fSCPCPerMatCuts[imc]) {
639 fSCPCPerMatCuts[imc]->fVSCPC.clear();
640 delete fSCPCPerMatCuts[imc];
641 fSCPCPerMatCuts[imc] = nullptr;
642 }
643 }
644 //
645 // set size of the container and create the corresponding data structures
646 fSCPCPerMatCuts.resize(numMatCuts,nullptr);
647 // loop over the material-cuts and create scattering power correction data structure for each
648 for (size_t imc=0; imc<numMatCuts; ++imc) {
649 const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
650 // get e- production cut in the current material-cuts in energy
651 G4double limit;
652 G4double ecut;
653 if (fIsElectron) {
654 ecut = (*(thePCTable->GetEnergyCutsVector(idxG4ElectronCut)))[matCut->GetIndex()];
655 limit = 2.*ecut;
656 } else {
657 ecut = (*(thePCTable->GetEnergyCutsVector(idxG4PositronCut)))[matCut->GetIndex()];
658 limit = ecut;
659 }
660 G4double min = std::max(limit,fLowEnergyLimit);
661 G4double max = fHighEnergyLimit;
662 if (min>=max) {
663 fSCPCPerMatCuts[imc] = new SCPCorrection();
664 fSCPCPerMatCuts[imc]->fIsUse = false;
665 fSCPCPerMatCuts[imc]->fPrCut = min;
666 continue;
667 }
668 G4int numEbins = fNumSPCEbinPerDec*G4lrint(std::log10(max/min));
669 numEbins = std::max(numEbins,3);
670 G4double lmin = G4Log(min);
671 G4double ldel = G4Log(max/min)/(numEbins-1.0);
672 fSCPCPerMatCuts[imc] = new SCPCorrection();
673 fSCPCPerMatCuts[imc]->fVSCPC.resize(numEbins,1.0);
674 fSCPCPerMatCuts[imc]->fIsUse = true;
675 fSCPCPerMatCuts[imc]->fPrCut = min;
676 fSCPCPerMatCuts[imc]->fLEmin = lmin;
677 fSCPCPerMatCuts[imc]->fILDel = 1./ldel;
678 for (G4int ie=0; ie<numEbins; ++ie) {
679 G4double ekin = G4Exp(lmin+ie*ldel);
680 G4double scpCorr = 1.0;
681 // compute correction factor: I.Kawrakow NIMB 114(1996)307-326 (Eqs(32-37))
682 if (ie>0) {
683 G4double tau = ekin/CLHEP::electron_mass_c2;
684 G4double tauCut = ecut/CLHEP::electron_mass_c2;
685 // Moliere's screening parameter
686 G4int matindx = matCut->GetMaterial()->GetIndex();
687 G4double A = GetMoliereXc2(matindx)/(4.0*tau*(tau+2.)*GetMoliereBc(matindx));
688 G4double gr = (1.+2.*A)*G4Log(1.+1./A)-2.;
689 G4double dum0 = (tau+2.)/(tau+1.);
690 G4double dum1 = tau+1.;
691 G4double gm = G4Log(0.5*tau/tauCut) + (1.+dum0*dum0)*G4Log(2.*(tau-tauCut+2.)/(tau+4.))
692 - 0.25*(tau+2.)*( tau+2.+2.*(2.*tau+1.)/(dum1*dum1))*
693 G4Log((tau+4.)*(tau-tauCut)/tau/(tau-tauCut+2.))
694 + 0.5*(tau-2*tauCut)*(tau+2.)*(1./(tau-tauCut)-1./(dum1*dum1));
695 if (gm<gr) {
696 gm = gm/gr;
697 } else {
698 gm = 1.;
699 }
701 scpCorr = 1.-gm*z0/(z0*(z0+1.));
702 }
703 fSCPCPerMatCuts[imc]->fVSCPC[ie] = scpCorr;
704 }
705 }
706}
double A(double temperature)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
@ idxG4ElectronCut
@ idxG4PositronCut
G4double GetMoliereBc(G4int matindx)
G4double GetMoliereXc2(G4int matindx)
G4double GetZeffective() const
const G4Material * GetMaterial() const
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:224
size_t GetIndex() const
Definition: G4Material.hh:258
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 Initialise().

◆ LoadMSCData()

void G4GoudsmitSaundersonTable::LoadMSCData ( )

Definition at line 437 of file G4GoudsmitSaundersonTable.cc.

437 {
438 char* path = std::getenv("G4LEDATA");
439 if (!path) {
440 G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
442 "Environment variable G4LEDATA not defined");
443 return;
444 }
445 //
446 gGSMSCAngularDistributions1.resize(gLAMBNUM*gQNUM1,nullptr);
447 const G4String str1 = G4String(path) + "/msc_GS/GSGrid_1/gsDistr_";
448 for (G4int il=0; il<gLAMBNUM; ++il) {
449 G4String fname = str1 + std::to_string(il);
450 std::ifstream infile(fname,std::ios::in);
451 if (!infile.is_open()) {
452 G4String msgc = "Cannot open file: " + fname;
453 G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
454 FatalException, msgc.c_str());
455 return;
456 }
457 for (G4int iq=0; iq<gQNUM1; ++iq) {
458 GSMSCAngularDtr *gsd = new GSMSCAngularDtr();
459 infile >> gsd->fNumData;
460 gsd->fUValues = new G4double[gsd->fNumData]();
461 gsd->fParamA = new G4double[gsd->fNumData]();
462 gsd->fParamB = new G4double[gsd->fNumData]();
463 G4double ddummy;
464 infile >> ddummy; infile >> ddummy;
465 for (G4int i=0; i<gsd->fNumData; ++i) {
466 infile >> gsd->fUValues[i];
467 infile >> gsd->fParamA[i];
468 infile >> gsd->fParamB[i];
469 }
470 gGSMSCAngularDistributions1[il*gQNUM1+iq] = gsd;
471 }
472 infile.close();
473 }
474 //
475 // second grid
476 gGSMSCAngularDistributions2.resize(gLAMBNUM*gQNUM2,nullptr);
477 const G4String str2 = G4String(path) + "/msc_GS/GSGrid_2/gsDistr_";
478 for (G4int il=0; il<gLAMBNUM; ++il) {
479 G4String fname = str2 + std::to_string(il);
480 std::ifstream infile(fname,std::ios::in);
481 if (!infile.is_open()) {
482 G4String msgc = "Cannot open file: " + fname;
483 G4Exception("G4GoudsmitSaundersonTable::LoadMSCData()","em0006",
484 FatalException, msgc.c_str());
485 return;
486 }
487 for (G4int iq=0; iq<gQNUM2; ++iq) {
488 G4int numData;
489 infile >> numData;
490 if (numData>1) {
491 GSMSCAngularDtr *gsd = new GSMSCAngularDtr();
492 gsd->fNumData = numData;
493 gsd->fUValues = new G4double[gsd->fNumData]();
494 gsd->fParamA = new G4double[gsd->fNumData]();
495 gsd->fParamB = new G4double[gsd->fNumData]();
496 double ddummy;
497 infile >> ddummy; infile >> ddummy;
498 for (G4int i=0; i<gsd->fNumData; ++i) {
499 infile >> gsd->fUValues[i];
500 infile >> gsd->fParamA[i];
501 infile >> gsd->fParamB[i];
502 }
503 gGSMSCAngularDistributions2[il*gQNUM2+iq] = gsd;
504 } else {
505 gGSMSCAngularDistributions2[il*gQNUM2+iq] = nullptr;
506 }
507 }
508 infile.close();
509 }
510}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35

Referenced by Initialise().

◆ SampleCosTheta()

G4double G4GoudsmitSaundersonTable::SampleCosTheta ( G4double  lambdaval,
G4double  qval,
G4double  scra,
G4double  lekin,
G4double  beta2,
G4int  matindx,
GSMSCAngularDtr **  gsDtr,
G4int mcekini,
G4int mcdelti,
G4double transfPar,
G4bool  isfirst 
)

Definition at line 305 of file G4GoudsmitSaundersonTable.cc.

308 {
309 G4double cost = 1.;
310 // determine the base GS angular distribution if it is the first call (when sub-step sampling is used)
311 if (isfirst) {
312 *gsDtr = GetGSAngularDtr(scra, lambdaval, qval, transfPar);
313 }
314 // sample cost from the GS angular distribution (computed based on Screened-Rutherford DCS)
315 cost = SampleGSSRCosTheta(*gsDtr, transfPar);
316 // Mott-correction if it was requested by the user
317 if (fIsMottCorrection && *gsDtr) { // no Mott-correction in case of izotropic theta
318 static const G4int nlooplim = 1000;
319 G4int nloop = 0 ; // rejection loop counter
320// G4int ekindx = -1; // evaluate only in the first call
321// G4int deltindx = -1 ; // evaluate only in the first call
322 G4double val = fMottCorrection->GetMottRejectionValue(lekin, beta2, qval, cost, matindx, mcekini, mcdelti);
323 while (G4UniformRand()>val && ++nloop<nlooplim) {
324 // sampling cos(theta)
325 cost = SampleGSSRCosTheta(*gsDtr, transfPar);
326 val = fMottCorrection->GetMottRejectionValue(lekin, beta2, qval, cost, matindx, mcekini, mcdelti);
327 };
328 }
329 return cost;
330}
G4double SampleGSSRCosTheta(const GSMSCAngularDtr *gsDrt, G4double transfpar)
GSMSCAngularDtr * GetGSAngularDtr(G4double scra, G4double &lambdaval, G4double &qval, G4double &transfpar)

Referenced by Sampling().

◆ SampleGSSRCosTheta()

G4double G4GoudsmitSaundersonTable::SampleGSSRCosTheta ( const GSMSCAngularDtr gsDrt,
G4double  transfpar 
)

Definition at line 334 of file G4GoudsmitSaundersonTable.cc.

334 {
335 // check if isotropic theta (i.e. cost is uniform on [-1:1])
336 if (!gsDtr) {
337 return 1.-2.0*G4UniformRand();
338 }
339 //
340 // sampling form the selected distribution
341 G4double ndatm1 = gsDtr->fNumData-1.;
342 G4double delta = 1.0/ndatm1;
343 // determine lower cumulative bin inidex
344 G4double rndm = G4UniformRand();
345 G4int indxl = rndm*ndatm1;
346 G4double aval = rndm-indxl*delta;
347 G4double dum0 = delta*aval;
348
349 G4double dum1 = (1.0+gsDtr->fParamA[indxl]+gsDtr->fParamB[indxl])*dum0;
350 G4double dum2 = delta*delta + gsDtr->fParamA[indxl]*dum0 + gsDtr->fParamB[indxl]*aval*aval;
351 G4double sample = gsDtr->fUValues[indxl] + dum1/dum2 *(gsDtr->fUValues[indxl+1]-gsDtr->fUValues[indxl]);
352 // transform back u to cos(theta) :
353 // this is the sampled cos(theta) = (2.0*para*sample)/(1.0-sample+para)
354 return 1.-(2.0*transfpar*sample)/(1.0-sample+transfpar);
355}

Referenced by SampleCosTheta().

◆ Sampling()

G4bool G4GoudsmitSaundersonTable::Sampling ( G4double  lambdaval,
G4double  qval,
G4double  scra,
G4double cost,
G4double sint,
G4double  lekin,
G4double  beta2,
G4int  matindx,
GSMSCAngularDtr **  gsDtr,
G4int mcekini,
G4int mcdelti,
G4double transfPar,
G4bool  isfirst 
)

Definition at line 212 of file G4GoudsmitSaundersonTable.cc.

215 {
216 G4double rand0 = G4UniformRand();
217 G4double expn = G4Exp(-lambdaval);
218 //
219 // no scattering case
220 if (rand0<expn) {
221 cost = 1.0;
222 sint = 0.0;
223 return false;
224 }
225 //
226 // single scattering case : sample from the single scattering PDF
227 // - Mott-correction will be included if it was requested by the user (i.e. if fIsMottCorrection=true)
228 if (rand0<(1.+lambdaval)*expn) {
229 // cost is sampled in SingleScattering()
230 cost = SingleScattering(lambdaval, scra, lekin, beta2, matindx);
231 // add protections
232 if (cost<-1.0) cost = -1.0;
233 if (cost>1.0) cost = 1.0;
234 // compute sin(theta) from the sampled cos(theta)
235 G4double dum0 = 1.-cost;
236 sint = std::sqrt(dum0*(2.0-dum0));
237 return false;
238 }
239 //
240 // handle this case:
241 // -lambdaval < 1 i.e. mean #elastic events along the step is < 1 but
242 // the currently sampled case is not 0 or 1 scattering. [Our minimal
243 // lambdaval (that we have precomputed, transformed angular distributions
244 // stored in a form of equally probabe intervalls together with rational
245 // interp. parameters) is 1.]
246 // -probability of having n elastic events follows Poisson stat. with
247 // lambdaval parameter.
248 // -the max. probability (when lambdaval=1) of having more than one
249 // elastic events is 0.2642411 and the prob of having 2,3,..,n elastic
250 // events decays rapidly with n. So set a max n to 10.
251 // -sampling of this cases is done in a one-by-one single elastic event way
252 // where the current #elastic event is sampled from the Poisson distr.
253 if (lambdaval<1.0) {
254 G4double prob, cumprob;
255 prob = cumprob = expn;
256 G4double curcost,cursint;
257 // init cos(theta) and sin(theta) to the zero scattering values
258 cost = 1.0;
259 sint = 0.0;
260 for (G4int iel=1; iel<10; ++iel) {
261 // prob of having iel scattering from Poisson
262 prob *= lambdaval/(G4double)iel;
263 cumprob += prob;
264 //
265 //sample cos(theta) from the singe scattering pdf:
266 // - Mott-correction will be included if it was requested by the user (i.e. if fIsMottCorrection=true)
267 curcost = SingleScattering(lambdaval, scra, lekin, beta2, matindx);
268 G4double dum0 = 1.-curcost;
269 cursint = dum0*(2.0-dum0); // sin^2(theta)
270 //
271 // if we got current deflection that is not too small
272 // then update cos(theta) sin(theta)
273 if (cursint>1.0e-20) {
274 cursint = std::sqrt(cursint);
275 G4double curphi = CLHEP::twopi*G4UniformRand();
276 cost = cost*curcost-sint*cursint*std::cos(curphi);
277 sint = std::sqrt(std::max(0.0, (1.0-cost)*(1.0+cost)));
278 }
279 //
280 // check if we have done enough scattering i.e. sampling from the Poisson
281 if (rand0<cumprob) {
282 return false;
283 }
284 }
285 // if reached the max iter i.e. 10
286 return false;
287 }
288 //
289 // multiple scattering case with lambdavalue >= 1:
290 // - use the precomputed and transformed Goudsmit-Saunderson angular
291 // distributions to sample cos(theta)
292 // - Mott-correction will be included if it was requested by the user (i.e. if fIsMottCorrection=true)
293 cost = SampleCosTheta(lambdaval, qval, scra, lekin, beta2, matindx, gsDtr, mcekini, mcdelti, transfPar, isfirst);
294 // add protections
295 if (cost<-1.0) cost = -1.0;
296 if (cost> 1.0) cost = 1.0;
297 // compute cos(theta) and sin(theta) from the sampled 1-cos(theta)
298 G4double dum0 = 1.0-cost;
299 sint = std::sqrt(dum0*(2.0-dum0));
300 // return true if it was msc
301 return true;
302}
G4double SampleCosTheta(G4double lambdaval, G4double qval, G4double scra, G4double lekin, G4double beta2, G4int matindx, GSMSCAngularDtr **gsDtr, G4int &mcekini, G4int &mcdelti, G4double &transfPar, G4bool isfirst)
G4double SingleScattering(G4double lambdaval, G4double scra, G4double lekin, G4double beta2, G4int matindx)

Referenced by G4GoudsmitSaundersonMscModel::SampleMSC().

◆ SetOptionMottCorrection()

void G4GoudsmitSaundersonTable::SetOptionMottCorrection ( G4bool  val)
inline

Definition at line 131 of file G4GoudsmitSaundersonTable.hh.

131{ fIsMottCorrection = val; }

Referenced by G4GoudsmitSaundersonMscModel::Initialise().

◆ SetOptionPWACorrection()

void G4GoudsmitSaundersonTable::SetOptionPWACorrection ( G4bool  val)
inline

Definition at line 133 of file G4GoudsmitSaundersonTable.hh.

133{ fIsPWACorrection = val; }

Referenced by G4GoudsmitSaundersonMscModel::Initialise().

◆ SingleScattering()

G4double G4GoudsmitSaundersonTable::SingleScattering ( G4double  lambdaval,
G4double  scra,
G4double  lekin,
G4double  beta2,
G4int  matindx 
)

Definition at line 514 of file G4GoudsmitSaundersonTable.cc.

516 {
517 G4double rand1 = G4UniformRand();
518 // sample cost from the Screened-Rutherford DCS
519 G4double cost = 1.-2.0*scra*rand1/(1.0-rand1+scra);
520 // Mott-correction if it was requested by the user
521 if (fIsMottCorrection) {
522 static const G4int nlooplim = 1000; // rejection loop limit
523 G4int nloop = 0 ; // loop counter
524 G4int ekindx = -1 ; // evaluate only in the first call
525 G4int deltindx = 0 ; // single scattering case
526 G4double q1 = 0.; // not used when deltindx = 0;
527 // computing Mott rejection function value
528 G4double val = fMottCorrection->GetMottRejectionValue(lekin, beta2, q1, cost,
529 matindx, ekindx, deltindx);
530 while (G4UniformRand()>val && ++nloop<nlooplim) {
531 // sampling cos(theta) from the Screened-Rutherford DCS
532 rand1 = G4UniformRand();
533 cost = 1.-2.0*scra*rand1/(1.0-rand1+scra);
534 // computing Mott rejection function value
535 val = fMottCorrection->GetMottRejectionValue(lekin, beta2, q1, cost, matindx,
536 ekindx, deltindx);
537 };
538 }
539 return cost;
540}

Referenced by G4GoudsmitSaundersonMscModel::ComputeTruePathLengthLimit(), and Sampling().


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