78G4ShellData* G4LivermorePolarizedComptonModel::shellData =
nullptr;
96 G4cout <<
"Livermore Polarized Compton is constructed " <<
G4endl;
101 fParticleChange =
nullptr;
102 fAtomDeexcitation =
nullptr;
114 profileData =
nullptr;
115 delete scatterFunctionData;
116 scatterFunctionData =
nullptr;
117 for(
G4int i=0; i<maxZ; ++i) {
131 if (verboseLevel > 1)
132 G4cout <<
"Calling G4LivermorePolarizedComptonModel::Initialise()" <<
G4endl;
144 for(
G4int i=0; i<numOfCouples; ++i) {
150 for (std::size_t j=0; j<nelm; ++j) {
153 else if(Z > maxZ){ Z = maxZ; }
155 if( (!data[Z]) ) { ReadData(Z, path); }
163 G4String file =
"/doppler/shell-doppler";
169 if(!scatterFunctionData)
173 G4String scatterFile =
"comp/ce-sf-";
175 scatterFunctionData->
LoadData(scatterFile);
181 if (verboseLevel > 2) {
185 if( verboseLevel>1 ) {
186 G4cout <<
"G4LivermoreComptonModel is initialized " <<
G4endl
193 if(isInitialised) {
return; }
197 isInitialised =
true;
209void G4LivermorePolarizedComptonModel::ReadData(std::size_t Z,
const char* path)
211 if (verboseLevel > 1)
213 G4cout <<
"G4LivermorePolarizedComptonModel::ReadData()"
216 if(data[Z]) {
return; }
217 const char* datadir = path;
223 G4Exception(
"G4LivermorePolarizedComptonModel::ReadData()",
225 "Environment variable G4LEDATA not defined");
232 std::ostringstream ost;
233 ost << datadir <<
"/livermore/comp/ce-cs-" << Z <<
".dat";
234 std::ifstream fin(ost.str().c_str());
239 ed <<
"G4LivermorePolarizedComptonModel data file <" << ost.str().c_str()
240 <<
"> is not opened!" <<
G4endl;
243 ed,
"G4LEDATA version should be G4EMLOW8.0 or later");
246 if(verboseLevel > 3) {
247 G4cout <<
"File " << ost.str()
248 <<
" is opened by G4LivermorePolarizedComptonModel" <<
G4endl;
264 if (verboseLevel > 3)
265 G4cout <<
"Calling ComputeCrossSectionPerAtom() of G4LivermorePolarizedComptonModel" <<
G4endl;
273 if(intZ < 1 || intZ > maxZ) {
return cs; }
283 if(!pv) {
return cs; }
290 if(GammaEnergy <= e1) { cs = GammaEnergy/(e1*e1)*pv->
Value(e1); }
291 else if(GammaEnergy <= e2) { cs = pv->
Value(GammaEnergy)/GammaEnergy; }
292 else if(GammaEnergy > e2) { cs = pv->
Value(e2)/GammaEnergy; }
312 if (verboseLevel > 3)
313 G4cout <<
"Calling SampleSecondaries() of G4LivermorePolarizedComptonModel" <<
G4endl;
331 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
333 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
339 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
344 G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
355 G4double epsilon0Local = 1./(1. + 2*E0_m);
356 G4double epsilon0Sq = epsilon0Local*epsilon0Local;
360 G4double wlGamma = h_Planck*c_light/gammaEnergy0;
373 epsilon = std::sqrt(epsilonSq);
377 sinThetaSqr = onecost*(2.-onecost);
380 if (sinThetaSqr > 1.)
383 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
384 <<
"sin(theta)**2 = "
390 if (sinThetaSqr < 0.)
393 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
394 <<
"sin(theta)**2 = "
402 G4double x = std::sqrt(onecost/2.) / (wlGamma/cm);;
404 greject = (1. -
epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
423 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
433 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
442 G4double sinTheta = std::sqrt (sinThetaSqr);
448 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
458 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
473 if (entanglementAuxInfo) {
475 (entanglementAuxInfo->GetEntanglementClipBoard());
483 if (clipBoard->IsTrack1Measurement()) {
502 clipBoard->ResetTrack1Measurement();
504 clipBoard->SetComptonCosTheta1(cosTheta);
505 clipBoard->SetComptonPhi1(phi);
507 }
else if (clipBoard->IsTrack2Measurement()) {
521 clipBoard->ResetTrack2Measurement();
524 const G4double& cosTheta1 = clipBoard->GetComptonCosTheta1();
525 const G4double& phi1 = clipBoard->GetComptonPhi1();
527 const G4double& cosTheta2 = cosTheta;
536 const G4double sin2Theta1 = 1.-cosTheta1*cosTheta1;
537 const G4double sin2Theta2 = 1.-cosTheta2*cosTheta2;
542 ((g4Pow->powN(1.-cosTheta1,3))+2.)*(g4Pow->powN(1.-cosTheta2,3)+2.)/
543 ((g4Pow->powN(2.-cosTheta1,3)*g4Pow->powN(2.-cosTheta2,3)));
544 const G4double B = -(sin2Theta1*sin2Theta2)/
545 ((g4Pow->powN(2.-cosTheta1,2)*g4Pow->powN(2.-cosTheta2,2)));
567 const G4int maxCount = 999999;
569 for (; iCount < maxCount; ++iCount) {
573 if (iCount >= maxCount ) {
574 G4cout <<
"G4LivermorePolarizedComptonModel::SampleSecondaries: "
575 <<
"Re-sampled delta phi not found in " << maxCount
576 <<
" tries - carrying on anyway." <<
G4endl;
580 phi2 = deltaPhi - phi1 + halfpi;
605 G4double dirx = sinTheta*std::cos(phi);
606 G4double diry = sinTheta*std::sin(phi);
617 static G4int maxDopplerIterations = 1000;
626 if (verboseLevel > 3) {
637 if (verboseLevel > 3) {
638 G4cout <<
"Shell ID= " << shellIdx
639 <<
" Ebind(keV)= " << bindingE/keV <<
G4endl;
641 eMax = gammaEnergy0 - bindingE;
646 if (verboseLevel > 3) {
650 G4double pDoppler = pSample * fine_structure_const;
651 G4double pDoppler2 = pDoppler * pDoppler;
652 G4double var2 = 1. + onecost * E0_m;
653 G4double var3 = var2*var2 - pDoppler2;
654 G4double var4 = var2 - pDoppler2 * cosTheta;
655 G4double var = var4*var4 - var3 + pDoppler2 * var3;
659 G4double scale = gammaEnergy0 / var3;
661 if (
G4UniformRand() < 0.5) photonE = (var4 - varSqrt) * scale;
662 else photonE = (var4 + varSqrt) * scale;
668 }
while ( iteration <= maxDopplerIterations &&
669 (photonE < 0. || photonE > eMax || photonE < eMax*
G4UniformRand()) );
673 if (iteration >= maxDopplerIterations)
675 photonE = photonEoriginal;
679 gammaEnergy1 = photonE;
692 gammaDirection1 = tmpDirection1;
695 SystemOfRefChange(gammaDirection0,gammaDirection1,
696 gammaPolarization0,gammaPolarization1);
698 if (gammaEnergy1 > 0.)
714 G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 -bindingE;
718 if(ElecKineEnergy < 0.0) {
723 G4double ElecMomentum = std::sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
725 G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
726 gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
730 fvect->push_back(dp);
734 if (verboseLevel > 3) {
735 G4cout <<
"Started atomic de-excitation " << fAtomDeexcitation <<
G4endl;
738 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
741 std::size_t nbefore = fvect->size();
745 std::size_t nafter = fvect->size();
746 if(nafter > nbefore) {
747 for (std::size_t i=nbefore; i<nafter; ++i) {
749 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
752 bindingE -= ((*fvect)[i])->GetKineticEnergy();
767 G4Exception(
"G4LivermoreComptonModel::SampleSecondaries()",
793 b = energyRate + 1/energyRate;
795 phiProbability = 1 - (a/b)*(std::cos(phi)*std::cos(phi));
797 while ( rand2 > phiProbability );
834 c.
setX(std::cos(angle)*(
a0.x())+std::sin(angle)*b0.
x());
835 c.
setY(std::cos(angle)*(
a0.y())+std::sin(angle)*b0.
y());
836 c.
setZ(std::cos(angle)*(
a0.z())+std::sin(angle)*b0.
z());
845G4ThreeVector G4LivermorePolarizedComptonModel::GetPerpendicularPolarization
858 return gammaPolarization - gammaPolarization.
dot(gammaDirection)/gammaDirection.
dot(gammaDirection) * gammaDirection;
872 G4double sinTheta = std::sqrt(sinSqrTh);
876 G4double normalisation = std::sqrt(1. - cosSqrPhi*sinSqrTh);
900 G4double sinBeta = std::sqrt(1-cosBeta*cosBeta);
904 G4double xParallel = normalisation*cosBeta;
905 G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
906 G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
908 G4double yPerpendicular = (costheta)*sinBeta/normalisation;
909 G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
911 G4double xTotal = (xParallel + xPerpendicular);
912 G4double yTotal = (yParallel + yPerpendicular);
913 G4double zTotal = (zParallel + zPerpendicular);
915 gammaPolarization1.
setX(xTotal);
916 gammaPolarization1.
setY(yTotal);
917 gammaPolarization1.
setZ(zTotal);
919 return gammaPolarization1;
924void G4LivermorePolarizedComptonModel::SystemOfRefChange(
G4ThreeVector& direction0,
940 direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
945 polarization1 = (polarization_x*Axis_X0 + polarization_y*Axis_Y0 + polarization_z*Axis_Z0).unit();
957 G4AutoLock l(&LivermorePolarizedComptonModelMutex);
958 if(!data[Z]) { ReadData(Z); }
G4double epsilon(G4double density, G4double temperature)
G4double C(G4double temp)
G4double B(G4double temperature)
G4double D(G4double temp)
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.
G4double G4Log(G4double x)
#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
virtual G4double FindValue(G4double x, G4int componentId=0) const
virtual G4bool LoadData(const G4String &fileName)
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
virtual ~G4LivermorePolarizedComptonModel()
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
void InitialiseForElement(const G4ParticleDefinition *, G4int Z) override
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX) override
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
G4LivermorePolarizedComptonModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="LivermorePolarizedCompton")
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
std::size_t GetNumberOfElements() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
static G4int GetModelID(const G4int modelIndex)
void ScaleVector(const G4double factorE, const G4double factorV)
G4double Energy(const std::size_t index) const
G4bool Retrieve(std::ifstream &fIn, G4bool ascii=false)
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
static G4Pow * GetInstance()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4double BindingEnergy(G4int Z, G4int shellIndex) const
void LoadData(const G4String &fileName)
G4int SelectRandomShell(G4int Z) const
G4VAuxiliaryTrackInformation * GetAuxiliaryTrackInformation(G4int id) const
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
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 SetDeexcitationFlag(G4bool val)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
void ProposeTrackStatus(G4TrackStatus status)
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)