Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4GoudsmitSaundersonTable Class Reference

#include <G4GoudsmitSaundersonTable.hh>

Public Member Functions

 G4GoudsmitSaundersonTable ()
 
 ~G4GoudsmitSaundersonTable ()
 
void Initialise ()
 
G4double SampleCosTheta (G4double, G4double, G4double, G4double, G4double, G4double)
 
G4double SampleCosThetaII (G4double, G4double, G4double, G4double, G4double, G4double)
 
G4double GetScreeningParam (G4double)
 
void Sampling (G4double, G4double, G4double, G4double &, G4double &)
 
G4double GetMoliereBc (G4int matindx)
 
G4double GetMoliereXc2 (G4int matindx)
 

Detailed Description

Definition at line 72 of file G4GoudsmitSaundersonTable.hh.

Constructor & Destructor Documentation

G4GoudsmitSaundersonTable::G4GoudsmitSaundersonTable ( )
inline

Definition at line 76 of file G4GoudsmitSaundersonTable.hh.

76 {};
G4GoudsmitSaundersonTable::~G4GoudsmitSaundersonTable ( )

Definition at line 299 of file G4GoudsmitSaundersonTable.cc.

299  {
300  if(fgMoliereBc){
301  delete fgMoliereBc;
302  fgMoliereBc = 0;
303  }
304  if(fgMoliereXc2){
305  delete fgMoliereXc2;
306  fgMoliereXc2 = 0;
307  }
308  fgIsInitialised = FALSE;
309 }
#define FALSE
Definition: globals.hh:52

Member Function Documentation

G4double G4GoudsmitSaundersonTable::GetMoliereBc ( G4int  matindx)
inline

Definition at line 104 of file G4GoudsmitSaundersonTable.hh.

104 {return (*fgMoliereBc)[matindx];}

Here is the caller graph for this function:

G4double G4GoudsmitSaundersonTable::GetMoliereXc2 ( G4int  matindx)
inline

Definition at line 105 of file G4GoudsmitSaundersonTable.hh.

105 {return (*fgMoliereXc2)[matindx];}

Here is the caller graph for this function:

G4double G4GoudsmitSaundersonTable::GetScreeningParam ( G4double  G1)

Definition at line 563 of file G4GoudsmitSaundersonTable.cc.

563  {
564  if(G1<fgG1Values[0]) return fgScreeningParam[0];
565  if(G1>fgG1Values[fgNumScreeningParams-1]) return fgScreeningParam[fgNumScreeningParams-1];
566  // normal case
567  const G4double lng10 = -2.30258509299405e+01; //log(fgG1Values[0]);
568  const G4double invlng1 = 6.948711710452e+00; //1./log(fgG1Values[i+1]/fgG1Values[i])
569  G4double logG1 = G4Log(G1);
570  G4int k = (G4int)((logG1-lng10)*invlng1);
571  return G4Exp(logG1*fgSrcAValues[k])*fgSrcBValues[k]; // log-log linear
572 }
int G4int
Definition: G4Types.hh:78
G4double G4Log(G4double x)
Definition: G4Log.hh:230
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

void G4GoudsmitSaundersonTable::Initialise ( )

Definition at line 288 of file G4GoudsmitSaundersonTable.cc.

288  {
289  if(!fgIsInitialised){
290  LoadMSCData();
291  LoadMSCDataII();
292  fgIsInitialised = TRUE;
293  }
294 
295  InitMoliereMSCParams();
296 }
#define TRUE
Definition: globals.hh:55

Here is the caller graph for this function:

G4double G4GoudsmitSaundersonTable::SampleCosTheta ( G4double  lambdavalue,
G4double  lamG1value,
G4double  screeningparam,
G4double  rndm1,
G4double  rndm2,
G4double  rndm3 
)

Definition at line 314 of file G4GoudsmitSaundersonTable.cc.

316  {
317  const G4double lnl0 = 0.0; //log(fgLambdaValues[0]);
318  const G4double invlnl = 6.5144172285e+00; //1./log(fgLambdaValues[i+1]/fgLambdaValues[i])
319  G4double logLambdaVal = G4Log(lambdavalue);
320  G4int lambdaindx = (G4int)((logLambdaVal-lnl0)*invlnl);
321 
322  const G4double dd = 1.0/0.0499; // delta
323  G4int lamg1indx = (G4int)((lamG1value-fgLamG1Values[0])*dd);
324 
325  G4double probOfLamJ = G4Log(fgLambdaValues[lambdaindx+1]/lambdavalue)*invlnl;
326  if(rndm1 > probOfLamJ)
327  ++lambdaindx;
328 
329  // store 1.0/(fgLamG1Values[lamg1indx+1]-fgLamG1Values[lamg1indx]) const value
330  const G4double onePerLamG1Diff = dd;
331  G4double probOfLamG1J = (fgLamG1Values[lamg1indx+1]-lamG1value)*onePerLamG1Diff;
332  if(rndm2 > probOfLamG1J)
333  ++lamg1indx;
334 
335  G4int begin = lambdaindx*(fgNumLamG1*fgNumUvalues)+lamg1indx*fgNumUvalues;
336 
337  // sample bin
338  G4int indx = (G4int)(rndm3*100); // value/delatU ahol deltaU = 0.01; find u-indx
339  G4double cp1 = fgUValues[indx];
340 // G4double cp2 = fgUValues[indx+1];
341  indx +=begin;
342 
343  G4double u1 = fgInverseQ2CDFs[indx];
344  G4double u2 = fgInverseQ2CDFs[indx+1];
345 
346  G4double dum1 = rndm3 - cp1;
347  const G4double dum2 = 0.01;//cp2-cp1; // this is constans 0.01
348  const G4double dum22 = 0.0001;
349  // rational interpolation of the inverse CDF
350  G4double sample= u1+(1.0+fgInterParamsA2[indx]+fgInterParamsB2[indx])*dum1*dum2/(dum22+
351  dum1*dum2*fgInterParamsA2[indx]+fgInterParamsB2[indx]*dum1*dum1)*(u2-u1);
352 
353  // transform back u to cos(theta) :
354  // -compute parameter value a = w2*screening_parameter
355  G4double t = logLambdaVal;
356  G4double dum;
357  if(lambdavalue >= 10.0)
358  dum = 0.5*(-2.77164+t*( 2.94874-t*(0.1535754-t*0.00552888) ));
359  else
360  dum = 0.5*(1.347+t*(0.209364-t*(0.45525-t*(0.50142-t*0.081234))));
361 
362  G4double a = dum*(lambdavalue+4.0)*screeningparam;
363 
364  // this is the sampled cos(theta)
365  return (2.0*a*sample)/(1.0-sample+a);
366 }
int G4int
Definition: G4Types.hh:78
G4double G4Log(G4double x)
Definition: G4Log.hh:230
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

G4double G4GoudsmitSaundersonTable::SampleCosThetaII ( G4double  lambdavalue,
G4double  lamG1value,
G4double  screeningparam,
G4double  rndm1,
G4double  rndm2,
G4double  rndm3 
)

Definition at line 371 of file G4GoudsmitSaundersonTable.cc.

373  {
374  const G4double lnl0 = 0.0; //log(fgLambdaValues[0]);
375  const G4double invlnl = 6.5144172285e+00; //1./log(fgLambdaValues[i+1]/fgLambdaValues[i])
376  G4double logLambdaVal = G4Log(lambdavalue);
377  G4int lambdaindx = (G4int)((logLambdaVal-lnl0)*invlnl);
378 
379  const G4double dd = 1.0/0.333; // delta
380  G4int lamg1indx = (G4int)((lamG1value-fgLamG1ValuesII[0])*dd);
381 
382  G4double probOfLamJ = G4Log(fgLambdaValues[lambdaindx+1]/lambdavalue)*invlnl;
383  if(rndm1 > probOfLamJ)
384  ++lambdaindx;
385 
386  // store 1.0/(fgLamG1Values[lamg1indx+1]-fgLamG1Values[lamg1indx]) const value
387  const G4double onePerLamG1Diff = dd;
388  G4double probOfLamG1J = (fgLamG1ValuesII[lamg1indx+1]-lamG1value)*onePerLamG1Diff;
389  if(rndm2 > probOfLamG1J)
390  ++lamg1indx;
391 
392  // protection against cases when the sampled lamG1 values are not possible due
393  // to the fact that G1<=1 (G1 = lam_el/lam_tr1)
394  // -- in theory it should never happen when lamg1indx=0 but check it just to be sure
395  if(fgLamG1ValuesII[lamg1indx]>lambdavalue && lamg1indx>0)
396  --lamg1indx;
397 
398 
399  G4int begin = lambdaindx*(fgNumLamG1II*fgNumUvalues)+lamg1indx*fgNumUvalues;
400 
401  // sample bin
402  G4int indx = (G4int)(rndm3*100); // value/delatU ahol deltaU = 0.01; find u-indx
403  G4double cp1 = fgUValues[indx];
404 // G4double cp2 = fgUValues[indx+1];
405  indx +=begin;
406 
407  G4double u1 = fgInverseQ2CDFsII[indx];
408  G4double u2 = fgInverseQ2CDFsII[indx+1];
409 
410  G4double dum1 = rndm3 - cp1;
411  const G4double dum2 = 0.01;//cp2-cp1; // this is constans 0.01
412  const G4double dum22 = 0.0001;
413  // rational interpolation of the inverse CDF
414  G4double sample= u1+(1.0+fgInterParamsA2II[indx]+fgInterParamsB2II[indx])*dum1*dum2/(dum22+
415  dum1*dum2*fgInterParamsA2II[indx]+fgInterParamsB2II[indx]*dum1*dum1)*(u2-u1);
416 
417  // transform back u to cos(theta) :
418  // -compute parameter value a = w2*screening_parameter
419  G4double t = logLambdaVal;
420  G4double dum = 0.;
421  if(lambdavalue >= 10.0)
422  dum = 0.5*(-2.77164+t*( 2.94874-t*(0.1535754-t*0.00552888) ));
423  else
424  dum = 0.5*(1.347+t*(0.209364-t*(0.45525-t*(0.50142-t*0.081234))));
425 
426  G4double a = dum*(lambdavalue+4.0)*screeningparam;
427 
428  // this is the sampled cos(theta)
429  return (2.0*a*sample)/(1.0-sample+a);
430 }
int G4int
Definition: G4Types.hh:78
G4double G4Log(G4double x)
Definition: G4Log.hh:230
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

void G4GoudsmitSaundersonTable::Sampling ( G4double  lambdavalue,
G4double  lamG1value,
G4double  scrPar,
G4double cost,
G4double sint 
)

**** let it izotropic if we are above the grid i.e. true path length is long

Definition at line 435 of file G4GoudsmitSaundersonTable.cc.

436  {
437  G4double rand0 = G4UniformRand();
438  G4double expn = G4Exp(-lambdavalue);
439 
440  //
441  // no scattering case
442  //
443  if(rand0 < expn) {
444  cost = 1.0;
445  sint = 0.0;
446  return;
447  }
448 
449  //
450  // single scattering case : sample (analitically) from the single scattering PDF
451  // that corresponds to the modified-Wentzel DCS i.e.
452  // Wentzel DCS that gives back the PWA first-transport mfp
453  //
454  if( rand0 < (1.+lambdavalue)*expn) {
455  G4double rand1 = G4UniformRand();
456  // sampling 1-cos(theta)
457  G4double dum0 = 2.0*scrPar*rand1/(1.0 - rand1 + scrPar);
458  // add protections
459  if(dum0 < 0.0) dum0 = 0.0;
460  else if(dum0 > 2.0 ) dum0 = 2.0;
461  // compute cos(theta) and sin(theta)
462  cost = 1.0 - dum0;
463  sint = std::sqrt(dum0*(2.0 - dum0));
464  return;
465  }
466 
467  //
468  // handle this case:
469  // -lambdavalue < 1 i.e. mean #elastic events along the step is < 1 but
470  // the currently sampled case is not 0 or 1 scattering. [Our minimal
471  // lambdavalue (that we have precomputed, transformed angular distributions
472  // stored in a form of equally probabe intervalls together with rational
473  // interp. parameters) is 1.]
474  // -probability of having n elastic events follows Poisson stat. with
475  // lambdavalue parameter.
476  // -the max. probability (when lambdavalue=1) of having more than one
477  // elastic events is 0.2642411 and the prob of having 2,3,..,n elastic
478  // events decays rapidly with n. So set a max n to 10.
479  // -sampling of this cases is done in a one-by-one single elastic event way
480  // where the current #elastic event is sampled from the Poisson distr.
481  // -(other possibility would be to use lambdavalue=1 distribution because
482  // they are very close)
483  if(lambdavalue < 1.0) {
484  G4double prob, cumprob;
485  prob = cumprob = expn;
486  G4double curcost,cursint;
487  // init cos(theta) and sin(theta) to the zero scattering values
488  cost = 1.0;
489  sint = 0.0;
490 
491  for(G4int iel = 1; iel < 10; ++iel){
492  // prob of having iel scattering from Poisson
493  prob *= lambdavalue/(G4double)iel;
494  cumprob += prob;
495  //
496  //sample cos(theta) from the singe scattering pdf
497  //
498  G4double rand1 = G4UniformRand();
499  // sampling 1-cos(theta)
500  G4double dum0 = 2.0*scrPar*rand1/(1.0 - rand1 + scrPar);
501  // compute cos(theta) and sin(theta)
502  curcost = 1.0 - dum0;
503  cursint = dum0*(2.0 - dum0);
504  //
505  // if we got current deflection that is not too small
506  // then update cos(theta) sin(theta)
507  if(cursint > 1.0e-20){
508  cursint = std::sqrt(cursint);
510  cost = cost*curcost - sint*cursint*std::cos(curphi);
511  sint = std::sqrt(std::max(0.0, (1.0-cost)*(1.0+cost)));
512  }
513  //
514  // check if we have done enough scattering i.e. sampling from the Poisson
515  if( rand0 < cumprob)
516  return;
517  }
518  // if reached the max iter i.e. 10
519  return;
520  }
521 
522 
524  // IT IS DONE NOW IN THE MODEL
525  //if(lamG1value>fgLamG1Values[fgNumLamG1-1]) {
526  // cost = 1.-2.*G4UniformRand();
527  // sint = std::sqrt((1.-cost)*(1.+cost));
528  // return;
529  //}
530 
531 
532  //
533  // multiple scattering case with lambdavalue >= 1:
534  // - use the precomputed and transformed Goudsmit-Saunderson angular
535  // distributions that are stored in a form of equally probabe intervalls
536  // together with the corresponding rational interp. parameters
537  //
538  // add protections
539  if(lamG1value<fgLamG1Values[0]) lamG1value = fgLamG1Values[0];
540  if(lamG1value>fgLamG1ValuesII[fgNumLamG1II-1]) lamG1value = fgLamG1ValuesII[fgNumLamG1II-1];
541 
542  // sample 1-cos(theta) :: depending on the grids
543  G4double dum0 = 0.0;
544  if(lamG1value<fgLamG1Values[fgNumLamG1-1]) {
545  dum0 = SampleCosTheta(lambdavalue, lamG1value, scrPar, G4UniformRand(),
547 
548  } else {
549  dum0 = SampleCosThetaII(lambdavalue, lamG1value, scrPar, G4UniformRand(),
551  }
552 
553  // add protections
554  if(dum0 < 0.0) dum0 = 0.0;
555  if(dum0 > 2.0 ) dum0 = 2.0;
556 
557  // compute cos(theta) and sin(theta)
558  cost = 1.0-dum0;
559  sint = std::sqrt(dum0*(2.0 - dum0));
560 }
int G4int
Definition: G4Types.hh:78
G4double SampleCosThetaII(G4double, G4double, G4double, G4double, G4double, G4double)
#define G4UniformRand()
Definition: Randomize.hh:97
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double G4double
Definition: G4Types.hh:76
G4double SampleCosTheta(G4double, G4double, G4double, G4double, G4double, G4double)
static constexpr double twopi
Definition: SystemOfUnits.h:55

Here is the call graph for this function:

Here is the caller graph for this function:


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