53 :
G4VEmModel(nam), smallEnergy(2.*MeV), isInitialised(false)
55 fParticleChange =
nullptr;
56 lowEnergyLimit = 2*electron_mass_c2;
67 if(verboseLevel > 0) {
68 G4cout <<
"Livermore Polarized GammaConversion is constructed "
79 for(
G4int i=0; i<maxZ; ++i) {
95 G4cout <<
"Calling1 G4LivermorePolarizedGammaConversionModel::Initialise()"
116 for(
G4int i=0; i<numOfCouples; ++i)
123 for (std::size_t j=0; j<nelm; ++j)
127 else if(
Z > maxZ) {
Z = maxZ; }
128 if(!data[
Z]) { ReadData(
Z, path); }
132 if(isInitialised) {
return; }
134 isInitialised =
true;
150 return lowEnergyLimit;
155void G4LivermorePolarizedGammaConversionModel::ReadData(std::size_t
Z,
const char* path)
157 if (verboseLevel > 1)
159 G4cout <<
"Calling ReadData() of G4LivermorePolarizedGammaConversionModel"
163 if(data[
Z]) {
return; }
165 const char* datadir = path;
172 G4Exception(
"G4LivermorePolarizedGammaConversionModel::ReadData()",
174 "Environment variable G4LEDATA not defined");
181 std::ostringstream ost;
182 ost << datadir <<
"/livermore/pair/pp-cs-" <<
Z <<
".dat";
183 std::ifstream fin(ost.str().c_str());
188 ed <<
"G4LivermorePolarizedGammaConversionModel data file <" << ost.str().c_str()
189 <<
"> is not opened!" <<
G4endl;
190 G4Exception(
"G4LivermorePolarizedGammaConversionModel::ReadData()",
192 ed,
"G4LEDATA version should be G4EMLOW6.27 or later.");
198 if(verboseLevel > 3) {
G4cout <<
"File " << ost.str()
199 <<
" is opened by G4LivermorePolarizedGammaConversionModel" <<
G4endl;}
217 if (verboseLevel > 1) {
218 G4cout <<
"G4LivermorePolarizedGammaConversionModel::ComputeCrossSectionPerAtom()"
221 if (GammaEnergy < lowEnergyLimit) {
return 0.0; }
227 if(intZ < 1 || intZ > maxZ) {
return xs; }
237 if(!pv) {
return xs; }
240 xs = pv->
Value(GammaEnergy);
245 G4cout <<
"****** DEBUG: tcs value for Z=" <<
Z <<
" at energy (MeV)="
246 << GammaEnergy/MeV <<
G4endl;
247 G4cout <<
" cs (Geant4 internal unit)=" << xs <<
G4endl;
248 G4cout <<
" -> first cs value in EADL data file (iu) =" << (*pv)[0] <<
G4endl;
249 G4cout <<
" -> last cs value in EADL data file (iu) =" << (*pv)[n] <<
G4endl;
250 G4cout <<
"*********************************************************" <<
G4endl;
270 if (verboseLevel > 3)
271 G4cout <<
"Calling SampleSecondaries() of G4LivermorePolarizedGammaConversionModel" <<
G4endl;
275 if(photonEnergy <= lowEnergyLimit)
287 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
289 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
295 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
302 G4double epsilon0Local = electron_mass_c2 / photonEnergy ;
306 if (photonEnergy < smallEnergy )
316 if (element ==
nullptr)
318 G4cout <<
"G4LivermorePolarizedGammaConversionModel::SampleSecondaries - element = 0" <<
G4endl;
324 if (ionisation ==
nullptr)
326 G4cout <<
"G4LivermorePolarizedGammaConversionModel::SampleSecondaries - ionisation = 0" <<
G4endl;
332 if (photonEnergy > 50. * MeV) fZ += 8. * (element->
GetfCoulomb());
337 G4double screenMin = std::min(4.*screenFactor,screenMax) ;
340 G4double epsilon1 = 0.5 - 0.5 * sqrt(1. - screenMin / screenMax) ;
341 G4double epsilonMin = std::max(epsilon0Local,epsilon1);
342 G4double epsilonRange = 0.5 - epsilonMin ;
348 G4double f10 = ScreenFunction1(screenMin) - fZ;
349 G4double f20 = ScreenFunction2(screenMin) - fZ;
350 G4double normF1 = std::max(f10 * epsilonRange * epsilonRange,0.);
351 G4double normF2 = std::max(1.5 * f20,0.);
358 gReject = (ScreenFunction1(screen) - fZ) / f10 ;
364 gReject = (ScreenFunction2(screen) - fZ) / f20 ;
375 electronTotEnergy = (1. -
epsilon) * photonEnergy;
376 positronTotEnergy =
epsilon * photonEnergy;
380 positronTotEnergy = (1. -
epsilon) * photonEnergy;
381 electronTotEnergy =
epsilon * photonEnergy;
387 G4double Ene = electronTotEnergy/electron_mass_c2;
392 SetTheta(&cosTheta,&sinTheta,Ene);
396 phi = SetPhi(photonEnergy);
397 psi = SetPsi(photonEnergy,phi);
439 G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
441 SystemOfRefChange(gammaDirection0,electronDirection,
449 Ene = positronTotEnergy/electron_mass_c2;
454 SetTheta(&cosTheta,&sinTheta,Ene);
457 dirX = sinTheta*cos(phip);
458 dirY = sinTheta*sin(phip);
462 G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
463 SystemOfRefChange(gammaDirection0,positronDirection,
468 positronDirection, positronKineEnergy);
469 fvect->push_back(particle1);
470 fvect->push_back(particle2);
479G4double G4LivermorePolarizedGammaConversionModel::ScreenFunction1(
G4double screenVariable)
483 if (screenVariable > 1.)
484 value = 42.24 - 8.368 * log(screenVariable + 0.952);
486 value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
493G4double G4LivermorePolarizedGammaConversionModel::ScreenFunction2(
G4double screenVariable)
498 if (screenVariable > 1.)
499 value = 42.24 - 8.368 * log(screenVariable + 0.952);
501 value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
515 *p_cosTheta = (Energy*((2*Rand)- 1) +
Momentum)/((Momentum*(2*Rand-1))+Energy);
516 *p_sinTheta = (2*sqrt(Rand*(1-Rand)))/(Momentum*(2*Rand-1)+Energy);
535 const G4double ay0=5.6, by0=18.6, aa0=2.9, ba0 = 8.16E-3;
536 const G4double aw = 0.0151, bw = 10.7, cw = -410.;
538 const G4double axc = 3.1455, bxc = -1.11, cxc = 310.;
540 pl[0] = Fln(ay0,by0,Ene);
541 pl[1] = aa0 + ba0*(Ene);
542 pl[2] = Poli(aw,bw,cw,Ene);
543 pl[3] = Poli(axc,bxc,cxc,Ene);
545 const G4double abf = 3.1216, bbf = 2.68;
547 pt[1] = abf + bbf/Ene;
551 n1 = Fintlor(pl,pi) - Fintlor(pl,xe);
552 n2 = Finttan(pt,xe) - Finttan(pt,0.);
558 const G4double aw = 0.21, bw = 10.8, cw = -58.;
559 const G4double axc = 3.17, bxc = -0.87, cxc = -6.;
561 pl[0] = Fln(ay0, by0, Ene);
562 pl[1] = Fln(aa0, ba0, Ene);
563 pl[2] = Poli(aw,bw,cw,Ene);
564 pl[3] = Poli(axc,bxc,cxc,Ene);
566 n1 = Fintlor(pl,pi) - Fintlor(pl,xe);
587 value = Finvlor(pl,xe,r2);
588 xco = Glor(pl,value)/c1;
594 value = Finvtan(pt,n,r1);
602 value = Finvlor(pl,xe,r2);
603 xco = Glor(pl,value)/c1;
628 const G4double ay00 = 3.4, by00 = 9.8, aa00 = 1.34, ba00 = 5.3;
629 const G4double aw0 = 0.014, bw0 = 9.7, cw0 = -2.E4;
630 const G4double axc0 = 3.1423, bxc0 = -2.35, cxc0 = 0.;
631 const G4double ay0p = 1.53, by0p = 3.2, aap = 0.67, bap = 8.5E-3;
632 const G4double awp = 6.9E-3, bwp = 12.6, cwp = -3.8E4;
633 const G4double axcp = 2.8E-3,bxcp = -3.133;
634 const G4double abf0 = 3.1213, bbf0 = 2.61;
635 const G4double abfpm = 3.1231, bbfpm = 2.84;
637 p0l[0] = Fln(ay00, by00, Ene);
638 p0l[1] = Fln(aa00, ba00, Ene);
639 p0l[2] = Poli(aw0, bw0, cw0, Ene);
640 p0l[3] = Poli(axc0, bxc0, cxc0, Ene);
642 ppml[0] = Fln(ay0p, by0p, Ene);
643 ppml[1] = aap + bap*(Ene);
644 ppml[2] = Poli(awp, bwp, cwp, Ene);
645 ppml[3] = Fln(axcp,bxcp,Ene);
648 p0t[1] = abf0 + bbf0/Ene;
650 ppmt[1] = abfpm + bbfpm/Ene;
653 xe0 = Encu(p0l, p0t, xi);
654 xepm = Encu(ppml, ppmt, xi);
658 const G4double ay00 = 2.82, by00 = 6.35;
659 const G4double aa00 = -1.75, ba00 = 0.25;
661 const G4double aw0 = 0.028, bw0 = 5., cw0 = -50.;
662 const G4double axc0 = 3.14213, bxc0 = -2.3, cxc0 = 5.7;
663 const G4double ay0p = 1.56, by0p = 3.6;
664 const G4double aap = 0.86, bap = 8.3E-3;
665 const G4double awp = 0.022, bwp = 7.4, cwp = -51.;
668 p0l[0] = Fln(ay00, by00, Ene);
669 p0l[1] = aa00+pow(Ene, ba00);
670 p0l[2] = Poli(aw0, bw0, cw0, Ene);
671 p0l[3] = Poli(axc0, bxc0, cxc0, Ene);
672 ppml[0] = Fln(ay0p, by0p, Ene);
673 ppml[1] = aap + bap*(Ene);
674 ppml[2] = Poli(awp, bwp, cwp, Ene);
684 b = (ppml[0]+2*ppml[1]*ppml[2]*Flor(ppml,PhiLocal));
688 b = Ftan(ppmt,PhiLocal);
692 a = (p0l[0]+2*p0l[1]*p0l[2]*Flor(p0l,PhiLocal));
696 a = Ftan(p0t,PhiLocal);
701 b = (ppml[0]+2*ppml[1]*ppml[2]*Flor(ppml,PhiLocal));
702 a = (p0l[0]+2*p0l[1]*p0l[2]*Flor(p0l,PhiLocal));
723 r3 = nr*(a*cos(value)*cos(value) + b*sin(value)*sin(value));
731G4double G4LivermorePolarizedGammaConversionModel::Poli
737 value =(a + b/x + c/(x*x*x));
748G4double G4LivermorePolarizedGammaConversionModel::Fln
765G4double G4LivermorePolarizedGammaConversionModel::Encu
775 fx = (Flor(p_p1,x)*Glor(p_p1,x) - Ftan(p_p2, x))/
776 (Fdlor(p_p1,x) - Fdtan(p_p2,x));
778 if(x > xmax) {
return xmax; }
779 if(std::fabs(fx) <= x*1.0e-6) {
break; }
782 if(x < 0.0) { x = 0.0; }
794 value = 1./(
pi*(w*w + 4.*(x-xc)*(x-xc)));
808 value = (y0 *
pi*(w*w + 4.*(x-xc)*(x-xc)) + 2.*
A*w);
821 value = (-16.*
A*w*(x-xc))/
822 (
pi*(w*w+4.*(x-xc)*(x-xc))*(w*w+4.*(x-xc)*(x-xc)));
836 value = y0*x +
A*atan( 2*(x-xc)/w) /
pi;
848 nor = atan(2.*(pi-xc)/w)/(2.*
pi*w) - atan(2.*(x-xc)/w)/(2.*pi*w);
849 value = xc - (w/2.)*tan(-2.*r*nor*pi*w+atan(2*(xc-x)/w));
874 value = -1.*a / ((x-b)*(x-b));
898 value = b*(1-
G4Exp(r*cnor/a));
935 c.
setX(std::cos(angle)*(
a0.x())+std::sin(angle)*b0.
x());
936 c.
setY(std::cos(angle)*(
a0.y())+std::sin(angle)*b0.
y());
937 c.
setZ(std::cos(angle)*(
a0.z())+std::sin(angle)*b0.
z());
946G4ThreeVector G4LivermorePolarizedGammaConversionModel::GetPerpendicularPolarization
959 return gammaPolarization - gammaPolarization.
dot(gammaDirection)/gammaDirection.
dot(gammaDirection) * gammaDirection;
964void G4LivermorePolarizedGammaConversionModel::SystemOfRefChange
979 direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
988 G4AutoLock l(&LivermorePolarizedGammaConversionModelMutex);
989 if(!data[
Z]) { ReadData(
Z); }
G4double epsilon(G4double density, G4double temperature)
std::vector< const G4Element * > G4ElementVector
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
double howOrthogonal(const Hep3Vector &v) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
G4double GetfCoulomb() const
G4IonisParamElm * GetIonisation() const
G4double GetlogZ3() const
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4LivermorePolarizedGammaConversionModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="LivermorePolarizedGammaConversion")
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
virtual ~G4LivermorePolarizedGammaConversionModel()
G4double MinPrimaryEnergy(const G4Material *, const G4ParticleDefinition *, G4double) override
void InitialiseForElement(const G4ParticleDefinition *, G4int Z) override
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
size_t GetNumberOfElements() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
G4bool Retrieve(std::ifstream &fIn, G4bool ascii=false)
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
void FillSecondDerivatives(const G4SplineType=G4SplineType::Base, const G4double dir1=0.0, const G4double dir2=0.0)
static G4Positron * Positron()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4double HighEnergyLimit() const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
void ProposeTrackStatus(G4TrackStatus status)