87 :
G4VEmModel(nam),fParticleChange(0),isInitialised(false),
88 scatterFunctionData(0),crossSectionHandler(0),fAtomDeexcitation(0)
90 lowEnergyLimit = 250 * eV;
91 highEnergyLimit = 100 * GeV;
101 if( verboseLevel>0 ) {
102 G4cout <<
"Low energy photon Compton model is constructed " <<
G4endl
104 << lowEnergyLimit / eV <<
" eV - "
105 << highEnergyLimit / GeV <<
" GeV"
118 delete crossSectionHandler;
119 delete scatterFunctionData;
127 if (verboseLevel > 2) {
128 G4cout <<
"Calling G4LowEPComptonModel::Initialise()" <<
G4endl;
131 if (crossSectionHandler)
133 crossSectionHandler->
Clear();
134 delete crossSectionHandler;
136 delete scatterFunctionData;
140 G4String crossSectionFile =
"comp/ce-cs-";
141 crossSectionHandler->
LoadData(crossSectionFile);
144 G4String scatterFile =
"comp/ce-sf-";
146 scatterFunctionData->
LoadData(scatterFile);
150 G4String file =
"/doppler/shell-doppler";
155 if (verboseLevel > 2) {
156 G4cout <<
"Loaded cross section files for low energy photon Compton model" <<
G4endl;
159 if(isInitialised) {
return; }
160 isInitialised =
true;
166 if( verboseLevel>0 ) {
167 G4cout <<
"Low energy photon Compton model is initialized " <<
G4endl
183 if (verboseLevel > 3) {
184 G4cout <<
"Calling ComputeCrossSectionPerAtom() of G4LowEPComptonModel" <<
G4endl;
186 if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) {
return 0.0; }
221 if (verboseLevel > 3) {
222 G4cout <<
"G4LowEPComptonModel::SampleSecondaries() E(MeV)= "
228 if (photonEnergy0 <= lowEnergyLimit)
236 G4double e0m = photonEnergy0 / electron_mass_c2 ;
244 G4double LowEPCepsilon0 = 1. / (1. + 2. * e0m);
245 G4double LowEPCepsilon0Sq = LowEPCepsilon0 * LowEPCepsilon0;
246 G4double alpha1 = -std::log(LowEPCepsilon0);
247 G4double alpha2 = 0.5 * (1. - LowEPCepsilon0Sq);
249 G4double wlPhoton = h_Planck*c_light/photonEnergy0;
263 LowEPCepsilonSq = LowEPCepsilon * LowEPCepsilon;
267 LowEPCepsilonSq = LowEPCepsilon0Sq + (1. - LowEPCepsilon0Sq) *
G4UniformRand();
268 LowEPCepsilon = std::sqrt(LowEPCepsilonSq);
271 oneCosT = (1. - LowEPCepsilon) / ( LowEPCepsilon * e0m);
272 sinT2 = oneCosT * (2. - oneCosT);
273 G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/cm);
275 gReject = (1. - LowEPCepsilon * sinT2 / (1. + LowEPCepsilonSq)) * scatteringFunction;
280 G4double sinTheta = std::sqrt(sinT2);
282 G4double dirx = sinTheta * std::cos(phi);
283 G4double diry = sinTheta * std::sin(phi);
295 G4double momentum_au_to_nat = (pi/2.0)*1.992851740*std::pow(10.,-24.);
296 G4double e_mass_kg = 9.10938188 * std::pow(10.,-31.);
298 G4int maxDopplerIterations = 1000;
300 G4double pEIncident = photonEnergy0 ;
343 G4double ePSI = ePAU * momentum_au_to_nat;
347 u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)))/vel_c;
356 G4double eEIncident = electron_mass_c2 / sqrt( 1 - (u_temp*u_temp));
357 G4double systemE = eEIncident + pEIncident;
360 G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
361 G4double numerator = gamma_temp*electron_mass_c2*(1 - u_temp * std::cos(e_alpha));
362 G4double subdenom1 = u_temp*cosTheta*std::cos(e_alpha);
363 G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
364 G4double denominator = (1.0 - cosTheta) + (gamma_temp*electron_mass_c2*(1 - subdenom1 - subdenom2) / pEIncident);
365 pERecoil = (numerator/denominator);
366 eERecoil = systemE - pERecoil;
367 CE_emission_flag = pEIncident - pERecoil;
368 }
while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
382 G4double a_temp = eERecoil / electron_mass_c2;
383 G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
387 G4double sinAlpha = std::sin(e_alpha);
388 G4double cosAlpha = std::cos(e_alpha);
389 G4double sinBeta = std::sin(e_beta);
390 G4double cosBeta = std::cos(e_beta);
392 G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
393 G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
395 G4double var_A = pERecoil*u_p_temp*sinTheta;
396 G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
397 G4double var_C = (pERecoil-pEIncident) - ( (pERecoil*pEIncident) / (gamma_p*electron_mass_c2))*(1 - cosTheta);
399 G4double var_D1 = gamma*electron_mass_c2*pERecoil;
400 G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
401 G4double var_D3 = ((electron_mass_c2*electron_mass_c2)*(gamma*gamma_p - 1)) - (gamma_p*electron_mass_c2*pERecoil);
402 G4double var_D = var_D1*var_D2 + var_D3;
404 G4double var_E1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosAlpha);
405 G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
408 G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
409 G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
412 G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
417 G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
418 G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
421 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));
423 G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
424 G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
427 G4double diff = ((var_Y*var_Y)-4*var_W*var_Z);
438 funorder = abs(
G4lrint(std::log10(
static_cast<double>(abs(diff1)))+std::numeric_limits<double>::epsilon()))+sf;
439 diff1 =
G4lrint(diff1*std::pow(10.0,funorder))/(1.0*std::pow(10.0,funorder));
442 funorder = abs(
G4lrint(std::log10(
static_cast<double>(abs(diff2)))+std::numeric_limits<double>::epsilon()))+sf;
443 diff2 =
G4lrint(diff2*std::pow(10.0,funorder))/(1.0*std::pow(10.0,funorder));
452 G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
453 G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
460 if (sol_select < 0.5)
462 ThetaE = std::acos(X_p);
464 if (sol_select > 0.5)
466 ThetaE = std::acos(X_m);
469 cosThetaE = std::cos(ThetaE);
470 sinThetaE = std::sin(ThetaE);
471 G4double Theta = std::acos(cosTheta);
474 G4double iSinThetaE = std::sqrt(1+std::tan((pi/2.0)-ThetaE)*std::tan((pi/2.0)-ThetaE));
475 G4double iSinTheta = std::sqrt(1+std::tan((pi/2.0)-Theta)*std::tan((pi/2.0)-Theta));
476 G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
478 cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
482 if (abs(cosPhiE) > 1.0)
486 funorder = abs(
G4lrint(std::log10(
static_cast<double>(abs(cosPhiE)))+std::numeric_limits<double>::epsilon()))+sf;
487 cosPhiE =
G4lrint(cosPhiE*std::pow(10.0,funorder))/(1.0*std::pow(10.0,funorder));
494 }
while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
499 if (iteration >= maxDopplerIterations)
501 pERecoil = photonEnergy0 ;
511 photonDirection1.
rotateUz(photonDirection0);
520 G4double eDirX = sinThetaE * std::cos(phi+PhiE);
521 G4double eDirY = sinThetaE * std::sin(phi+PhiE);
524 G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
527 eDirection.
rotateUz(photonDirection0);
529 eDirection,eKineticEnergy) ;
530 fvect->push_back(dp);
544 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
547 size_t nbefore = fvect->size();
551 size_t nafter = fvect->size();
552 if(nafter > nbefore) {
553 for (
size_t i=nbefore; i<nafter; ++i) {
554 bindingE -= ((*fvect)[i])->GetKineticEnergy();
559 if(bindingE < 0.0) { bindingE = 0.0; }
G4DLLIMPORT std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
virtual ~G4LowEPComptonModel()
G4LowEPComptonModel(const G4ParticleDefinition *p=0, const G4String &nam="LowEPComptonModel")
G4ParticleChangeForGamma * fParticleChange
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
const G4Material * GetMaterial() const
const G4String & GetName() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double BindingEnergy(G4int Z, G4int shellIndex) const
void LoadData(const G4String &fileName)
G4int SelectRandomShell(G4int Z) 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)
G4double FindValue(G4int Z, G4double e) const
void LoadData(const G4String &dataFile)
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
virtual G4bool LoadData(const G4String &fileName)=0
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
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)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)