89 :
G4VEmModel(nam),fParticleChange(0),isInitialised(false),
90 scatterFunctionData(0),crossSectionHandler(0),fAtomDeexcitation(0)
92 lowEnergyLimit = 250 *
eV;
93 highEnergyLimit = 100 *
GeV;
103 if( verboseLevel>0 ) {
104 G4cout <<
"Low energy photon Compton model is constructed " <<
G4endl
106 << lowEnergyLimit /
eV <<
" eV - "
107 << highEnergyLimit /
GeV <<
" GeV"
120 delete crossSectionHandler;
121 delete scatterFunctionData;
129 if (verboseLevel > 2) {
130 G4cout <<
"Calling G4LowEPComptonModel::Initialise()" <<
G4endl;
133 if (crossSectionHandler)
135 crossSectionHandler->
Clear();
136 delete crossSectionHandler;
138 delete scatterFunctionData;
142 G4String crossSectionFile =
"comp/ce-cs-";
143 crossSectionHandler->
LoadData(crossSectionFile);
146 G4String scatterFile =
"comp/ce-sf-";
148 scatterFunctionData->
LoadData(scatterFile);
157 if (verboseLevel > 2) {
158 G4cout <<
"Loaded cross section files for low energy photon Compton model" <<
G4endl;
161 if(isInitialised) {
return; }
162 isInitialised =
true;
168 if( verboseLevel>0 ) {
169 G4cout <<
"Low energy photon Compton model is initialized " <<
G4endl
185 if (verboseLevel > 3) {
186 G4cout <<
"Calling ComputeCrossSectionPerAtom() of G4LowEPComptonModel" <<
G4endl;
188 if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) {
return 0.0; }
223 if (verboseLevel > 3) {
224 G4cout <<
"G4LowEPComptonModel::SampleSecondaries() E(MeV)= "
230 if (photonEnergy0 <= lowEnergyLimit)
246 G4double LowEPCepsilon0 = 1. / (1. + 2. * e0m);
247 G4double LowEPCepsilon0Sq = LowEPCepsilon0 * LowEPCepsilon0;
248 G4double alpha1 = -std::log(LowEPCepsilon0);
249 G4double alpha2 = 0.5 * (1. - LowEPCepsilon0Sq);
265 LowEPCepsilonSq = LowEPCepsilon * LowEPCepsilon;
269 LowEPCepsilonSq = LowEPCepsilon0Sq + (1. - LowEPCepsilon0Sq) *
G4UniformRand();
270 LowEPCepsilon = std::sqrt(LowEPCepsilonSq);
273 oneCosT = (1. - LowEPCepsilon) / ( LowEPCepsilon * e0m);
274 sinT2 = oneCosT * (2. - oneCosT);
275 G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/
cm);
277 gReject = (1. - LowEPCepsilon * sinT2 / (1. + LowEPCepsilonSq)) * scatteringFunction;
282 G4double sinTheta = std::sqrt(sinT2);
284 G4double dirx = sinTheta * std::cos(phi);
285 G4double diry = sinTheta * std::sin(phi);
300 const G4int maxDopplerIterations = 1000;
302 G4double pEIncident = photonEnergy0 ;
342 G4double ePSI = ePAU * momentum_au_to_nat;
345 u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)) )/vel_c;
355 G4double systemE = eEIncident + pEIncident;
358 G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
360 G4double subdenom1 = u_temp*cosTheta*std::cos(e_alpha);
361 G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
363 pERecoil = (numerator/denominator);
364 eERecoil = systemE - pERecoil;
365 CE_emission_flag = pEIncident - pERecoil;
366 }
while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
381 G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
385 G4double sinAlpha = std::sin(e_alpha);
386 G4double cosAlpha = std::cos(e_alpha);
387 G4double sinBeta = std::sin(e_beta);
388 G4double cosBeta = std::cos(e_beta);
390 G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
391 G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
393 G4double var_A = pERecoil*u_p_temp*sinTheta;
394 G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
398 G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
400 G4double var_D = var_D1*var_D2 + var_D3;
403 G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
406 G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
407 G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
410 G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
415 G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
416 G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
419 G4double var_Y = 2.0*(((var_A*var_D-var_F*var_C)*(var_F*var_B-var_E*var_A)) - ((var_G*var_G)*var_B*var_C));
421 G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
422 G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
433 G4double g4d_limit = std::pow(10.,-g4d_order);
437 if ((diff < 0.0) && (abs(diff / diff1) < g4d_limit) && (abs(diff / diff2) < g4d_limit) )
444 G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
445 G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
452 if (sol_select < 0.5)
454 ThetaE = std::acos(X_p);
456 if (sol_select > 0.5)
458 ThetaE = std::acos(X_m);
461 cosThetaE = std::cos(ThetaE);
462 sinThetaE = std::sin(ThetaE);
463 G4double Theta = std::acos(cosTheta);
466 G4double iSinThetaE = std::sqrt(1+std::tan((
pi/2.0)-ThetaE)*std::tan((
pi/2.0)-ThetaE));
467 G4double iSinTheta = std::sqrt(1+std::tan((
pi/2.0)-Theta)*std::tan((
pi/2.0)-Theta));
468 G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
470 cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
476 }
while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
481 if (iteration >= maxDopplerIterations)
483 pERecoil = photonEnergy0 ;
493 photonDirection1.
rotateUz(photonDirection0);
502 G4double eDirX = sinThetaE * std::cos(phi+PhiE);
503 G4double eDirY = sinThetaE * std::sin(phi+PhiE);
506 G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
509 eDirection.
rotateUz(photonDirection0);
511 eDirection,eKineticEnergy) ;
512 fvect->push_back(dp);
526 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
529 size_t nbefore = fvect->size();
533 size_t nafter = fvect->size();
534 if(nafter > nbefore) {
535 for (
size_t i=nbefore; i<nafter; ++i) {
536 bindingE -= ((*fvect)[i])->GetKineticEnergy();
541 if(bindingE < 0.0) { bindingE = 0.0; }
G4double LowEnergyLimit() const
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
static G4LossTableManager * Instance()
G4double GetKineticEnergy() const
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
G4double HighEnergyLimit() const
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
G4LowEPComptonModel(const G4ParticleDefinition *p=0, const G4String &nam="LowEPComptonModel")
const G4String & GetName() const
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
G4ParticleDefinition * GetDefinition() const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4int SelectRandomShell(G4int Z) const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void LoadData(const G4String &fileName)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
G4double FindValue(G4int Z, G4double e) const
virtual ~G4LowEPComptonModel()
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double BindingEnergy(G4int Z, G4int shellIndex) const
Hep3Vector & rotateUz(const Hep3Vector &)
void LoadData(const G4String &dataFile)
virtual G4bool LoadData(const G4String &fileName)=0
static G4Electron * Electron()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
G4ParticleChangeForGamma * fParticleChange
G4VAtomDeexcitation * AtomDeexcitation()
void ProposeTrackStatus(G4TrackStatus status)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void SetDeexcitationFlag(G4bool val)
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
const G4Material * GetMaterial() const