#include <G4PenelopeRayleighModel.hh>
Inheritance diagram for G4PenelopeRayleighModel:
Public Member Functions | |
G4PenelopeRayleighModel (const G4ParticleDefinition *p=0, const G4String &processName="PenRayleigh") | |
virtual | ~G4PenelopeRayleighModel () |
virtual void | Initialise (const G4ParticleDefinition *, const G4DataVector &) |
virtual G4double | ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX) |
virtual void | SampleSecondaries (std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) |
void | SetVerbosityLevel (G4int lev) |
G4int | GetVerbosityLevel () |
void | DumpFormFactorTable (const G4Material *) |
Protected Attributes | |
G4ParticleChangeForGamma * | fParticleChange |
Definition at line 57 of file G4PenelopeRayleighModel.hh.
G4PenelopeRayleighModel::G4PenelopeRayleighModel | ( | const G4ParticleDefinition * | p = 0 , |
|
const G4String & | processName = "PenRayleigh" | |||
) |
Definition at line 53 of file G4PenelopeRayleighModel.cc.
References G4VEmModel::SetHighEnergyLimit().
00055 :G4VEmModel(nam),fParticleChange(0),isInitialised(false),logAtomicCrossSection(0), 00056 atomicFormFactor(0),logFormFactorTable(0),pMaxTable(0),samplingTable(0) 00057 { 00058 fIntrinsicLowEnergyLimit = 100.0*eV; 00059 fIntrinsicHighEnergyLimit = 100.0*GeV; 00060 // SetLowEnergyLimit(fIntrinsicLowEnergyLimit); 00061 SetHighEnergyLimit(fIntrinsicHighEnergyLimit); 00062 // 00063 verboseLevel= 0; 00064 // Verbosity scale: 00065 // 0 = nothing 00066 // 1 = warning for energy non-conservation 00067 // 2 = details of energy budget 00068 // 3 = calculation of cross sections, file openings, sampling of atoms 00069 // 4 = entering in methods 00070 00071 //build the energy grid. It is the same for all materials 00072 G4double logenergy = std::log(fIntrinsicLowEnergyLimit/2.); 00073 G4double logmaxenergy = std::log(1.5*fIntrinsicHighEnergyLimit); 00074 //finer grid below 160 keV 00075 G4double logtransitionenergy = std::log(160*keV); 00076 G4double logfactor1 = std::log(10.)/250.; 00077 G4double logfactor2 = logfactor1*10; 00078 logEnergyGridPMax.push_back(logenergy); 00079 do{ 00080 if (logenergy < logtransitionenergy) 00081 logenergy += logfactor1; 00082 else 00083 logenergy += logfactor2; 00084 logEnergyGridPMax.push_back(logenergy); 00085 }while (logenergy < logmaxenergy); 00086 }
G4PenelopeRayleighModel::~G4PenelopeRayleighModel | ( | ) | [virtual] |
Definition at line 90 of file G4PenelopeRayleighModel.cc.
00091 { 00092 std::map <G4int,G4PhysicsFreeVector*>::iterator i; 00093 if (logAtomicCrossSection) 00094 { 00095 for (i=logAtomicCrossSection->begin();i != logAtomicCrossSection->end();i++) 00096 if (i->second) delete i->second; 00097 delete logAtomicCrossSection; 00098 } 00099 00100 if (atomicFormFactor) 00101 { 00102 for (i=atomicFormFactor->begin();i != atomicFormFactor->end();i++) 00103 if (i->second) delete i->second; 00104 delete atomicFormFactor; 00105 } 00106 00107 ClearTables(); 00108 }
G4double G4PenelopeRayleighModel::ComputeCrossSectionPerAtom | ( | const G4ParticleDefinition * | , | |
G4double | kinEnergy, | |||
G4double | Z, | |||
G4double | A = 0 , |
|||
G4double | cut = 0 , |
|||
G4double | emax = DBL_MAX | |||
) | [virtual] |
Reimplemented from G4VEmModel.
Definition at line 186 of file G4PenelopeRayleighModel.cc.
References FatalException, G4cout, G4endl, G4Exception(), and G4PhysicsVector::Value().
00192 { 00193 // Cross section of Rayleigh scattering in Penelope v2008 is calculated by the EPDL97 00194 // tabulation, Cuellen et al. (1997), with non-relativistic form factors from Hubbel 00195 // et al. J. Phys. Chem. Ref. Data 4 (1975) 471; Erratum ibid. 6 (1977) 615. 00196 00197 if (verboseLevel > 3) 00198 G4cout << "Calling CrossSectionPerAtom() of G4PenelopeRayleighModel" << G4endl; 00199 00200 G4int iZ = (G4int) Z; 00201 00202 //read data files 00203 if (!logAtomicCrossSection->count(iZ)) 00204 ReadDataFile(iZ); 00205 //now it should be ok 00206 if (!logAtomicCrossSection->count(iZ)) 00207 { 00208 G4Exception("G4PenelopeRayleighModel::ComputeCrossSectionPerAtom()", 00209 "em2040",FatalException,"Unable to load the cross section table"); 00210 } 00211 00212 G4double cross = 0; 00213 00214 G4PhysicsFreeVector* atom = logAtomicCrossSection->find(iZ)->second; 00215 if (!atom) 00216 { 00217 G4ExceptionDescription ed; 00218 ed << "Unable to find Z=" << iZ << " in the atomic cross section table" << G4endl; 00219 G4Exception("G4PenelopeRayleighModel::ComputeCrossSectionPerAtom()", 00220 "em2041",FatalException,ed); 00221 return 0; 00222 } 00223 G4double logene = std::log(energy); 00224 G4double logXS = atom->Value(logene); 00225 cross = std::exp(logXS); 00226 00227 if (verboseLevel > 2) 00228 G4cout << "Rayleigh cross section at " << energy/keV << " keV for Z=" << Z << 00229 " = " << cross/barn << " barn" << G4endl; 00230 return cross; 00231 }
void G4PenelopeRayleighModel::DumpFormFactorTable | ( | const G4Material * | ) |
Definition at line 1160 of file G4PenelopeRayleighModel.cc.
References G4cout, G4PhysicsVector::GetLowEdgeEnergy(), G4Material::GetName(), and G4PhysicsVector::GetVectorLength().
01161 { 01162 G4cout << "*****************************************************************" << G4endl; 01163 G4cout << "G4PenelopeRayleighModel: Form Factor Table for " << mat->GetName() << G4endl; 01164 //try to use the same format as Penelope-Fortran, namely Q (/m_e*c) and F 01165 G4cout << "Q/(m_e*c) F(Q) " << G4endl; 01166 G4cout << "*****************************************************************" << G4endl; 01167 if (!logFormFactorTable->count(mat)) 01168 BuildFormFactorTable(mat); 01169 01170 G4PhysicsFreeVector* theVec = logFormFactorTable->find(mat)->second; 01171 for (size_t i=0;i<theVec->GetVectorLength();i++) 01172 { 01173 G4double logQ2 = theVec->GetLowEdgeEnergy(i); 01174 G4double Q = std::exp(0.5*logQ2); 01175 G4double logF2 = (*theVec)[i]; 01176 G4double F = std::exp(0.5*logF2); 01177 G4cout << Q << " " << F << G4endl; 01178 } 01179 //DONE 01180 return; 01181 }
G4int G4PenelopeRayleighModel::GetVerbosityLevel | ( | ) | [inline] |
void G4PenelopeRayleighModel::Initialise | ( | const G4ParticleDefinition * | , | |
const G4DataVector & | ||||
) | [virtual] |
Implements G4VEmModel.
Definition at line 145 of file G4PenelopeRayleighModel.cc.
References fParticleChange, G4cout, G4endl, G4VEmModel::GetParticleChangeForGamma(), G4VEmModel::HighEnergyLimit(), and G4VEmModel::LowEnergyLimit().
00147 { 00148 if (verboseLevel > 3) 00149 G4cout << "Calling G4PenelopeRayleighModel::Initialise()" << G4endl; 00150 00151 //clear tables depending on materials, not the atomic ones 00152 ClearTables(); 00153 00154 //create new tables 00155 // 00156 // logAtomicCrossSection and atomicFormFactor are created only once, 00157 // since they are never cleared 00158 if (!logAtomicCrossSection) 00159 logAtomicCrossSection = new std::map<G4int,G4PhysicsFreeVector*>; 00160 if (!atomicFormFactor) 00161 atomicFormFactor = new std::map<G4int,G4PhysicsFreeVector*>; 00162 00163 if (!logFormFactorTable) 00164 logFormFactorTable = new std::map<const G4Material*,G4PhysicsFreeVector*>; 00165 if (!pMaxTable) 00166 pMaxTable = new std::map<const G4Material*,G4PhysicsFreeVector*>; 00167 if (!samplingTable) 00168 samplingTable = new std::map<const G4Material*,G4PenelopeSamplingData*>; 00169 00170 00171 if (verboseLevel > 0) { 00172 G4cout << "Penelope Rayleigh model v2008 is initialized " << G4endl 00173 << "Energy range: " 00174 << LowEnergyLimit() / keV << " keV - " 00175 << HighEnergyLimit() / GeV << " GeV" 00176 << G4endl; 00177 } 00178 00179 if(isInitialised) return; 00180 fParticleChange = GetParticleChangeForGamma(); 00181 isInitialised = true; 00182 }
void G4PenelopeRayleighModel::SampleSecondaries | ( | std::vector< G4DynamicParticle * > * | , | |
const G4MaterialCutsCouple * | , | |||
const G4DynamicParticle * | , | |||
G4double | tmin, | |||
G4double | maxEnergy | |||
) | [virtual] |
Implements G4VEmModel.
Definition at line 306 of file G4PenelopeRayleighModel.cc.
References FatalException, fParticleChange, fStopAndKill, G4cout, G4endl, G4Exception(), G4UniformRand, G4DynamicParticle::GetKineticEnergy(), G4MaterialCutsCouple::GetMaterial(), G4DynamicParticle::GetMomentumDirection(), G4PenelopeSamplingData::GetNumberOfStoredPoints(), G4PenelopeSamplingData::GetX(), G4VParticleChange::ProposeLocalEnergyDeposit(), G4ParticleChangeForGamma::ProposeMomentumDirection(), G4VParticleChange::ProposeTrackStatus(), G4PenelopeSamplingData::SampleValue(), G4ParticleChangeForGamma::SetProposedKineticEnergy(), and G4PhysicsVector::Value().
00311 { 00312 // Sampling of the Rayleigh final state (namely, scattering angle of the photon) 00313 // from the Penelope2008 model. The scattering angle is sampled from the atomic 00314 // cross section dOmega/d(cosTheta) from Born ("Atomic Phyisics", 1969), disregarding 00315 // anomalous scattering effects. The Form Factor F(Q) function which appears in the 00316 // analytical cross section is retrieved via the method GetFSquared(); atomic data 00317 // are tabulated for F(Q). Form factor for compounds is calculated according to 00318 // the additivity rule. The sampling from the F(Q) is made via a Rational Inverse 00319 // Transform with Aliasing (RITA) algorithm; RITA parameters are calculated once 00320 // for each material and managed by G4PenelopeSamplingData objects. 00321 // The sampling algorithm (rejection method) has efficiency 67% at low energy, and 00322 // increases with energy. For E=100 keV the efficiency is 100% and 86% for 00323 // hydrogen and uranium, respectively. 00324 00325 if (verboseLevel > 3) 00326 G4cout << "Calling SamplingSecondaries() of G4PenelopeRayleighModel" << G4endl; 00327 00328 G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy(); 00329 00330 if (photonEnergy0 <= fIntrinsicLowEnergyLimit) 00331 { 00332 fParticleChange->ProposeTrackStatus(fStopAndKill); 00333 fParticleChange->SetProposedKineticEnergy(0.); 00334 fParticleChange->ProposeLocalEnergyDeposit(photonEnergy0); 00335 return ; 00336 } 00337 00338 G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection(); 00339 00340 const G4Material* theMat = couple->GetMaterial(); 00341 00342 //1) Verify if tables are ready 00343 if (!pMaxTable || !samplingTable) 00344 { 00345 G4Exception("G4PenelopeRayleighModel::SampleSecondaries()", 00346 "em2043",FatalException,"Invalid model initialization"); 00347 return; 00348 } 00349 00350 //2) retrieve or build the sampling table 00351 if (!(samplingTable->count(theMat))) 00352 InitializeSamplingAlgorithm(theMat); 00353 G4PenelopeSamplingData* theDataTable = samplingTable->find(theMat)->second; 00354 00355 //3) retrieve or build the pMax data 00356 if (!pMaxTable->count(theMat)) 00357 GetPMaxTable(theMat); 00358 G4PhysicsFreeVector* thePMax = pMaxTable->find(theMat)->second; 00359 00360 G4double cosTheta = 1.0; 00361 00362 //OK, ready to go! 00363 G4double qmax = 2.0*photonEnergy0/electron_mass_c2; //this is non-dimensional now 00364 00365 if (qmax < 1e-10) //very low momentum transfer 00366 { 00367 G4bool loopAgain=false; 00368 do 00369 { 00370 loopAgain = false; 00371 cosTheta = 1.0-2.0*G4UniformRand(); 00372 G4double G = 0.5*(1+cosTheta*cosTheta); 00373 if (G4UniformRand()>G) 00374 loopAgain = true; 00375 }while(loopAgain); 00376 } 00377 else //larger momentum transfer 00378 { 00379 size_t nData = theDataTable->GetNumberOfStoredPoints(); 00380 G4double LastQ2inTheTable = theDataTable->GetX(nData-1); 00381 G4double q2max = std::min(qmax*qmax,LastQ2inTheTable); 00382 00383 G4bool loopAgain = false; 00384 G4double MaxPValue = thePMax->Value(photonEnergy0); 00385 G4double xx=0; 00386 00387 //Sampling by rejection method. The rejection function is 00388 //G = 0.5*(1+cos^2(theta)) 00389 // 00390 do{ 00391 loopAgain = false; 00392 G4double RandomMax = G4UniformRand()*MaxPValue; 00393 xx = theDataTable->SampleValue(RandomMax); 00394 //xx is a random value of q^2 in (0,q2max),sampled according to 00395 //F(Q^2) via the RITA algorithm 00396 if (xx > q2max) 00397 loopAgain = true; 00398 cosTheta = 1.0-2.0*xx/q2max; 00399 G4double G = 0.5*(1+cosTheta*cosTheta); 00400 if (G4UniformRand()>G) 00401 loopAgain = true; 00402 }while(loopAgain); 00403 } 00404 00405 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta); 00406 00407 // Scattered photon angles. ( Z - axis along the parent photon) 00408 G4double phi = twopi * G4UniformRand() ; 00409 G4double dirX = sinTheta*std::cos(phi); 00410 G4double dirY = sinTheta*std::sin(phi); 00411 G4double dirZ = cosTheta; 00412 00413 // Update G4VParticleChange for the scattered photon 00414 G4ThreeVector photonDirection1(dirX, dirY, dirZ); 00415 00416 photonDirection1.rotateUz(photonDirection0); 00417 fParticleChange->ProposeMomentumDirection(photonDirection1) ; 00418 fParticleChange->SetProposedKineticEnergy(photonEnergy0) ; 00419 00420 return; 00421 }
void G4PenelopeRayleighModel::SetVerbosityLevel | ( | G4int | lev | ) | [inline] |
Definition at line 88 of file G4PenelopeRayleighModel.hh.
Referenced by Initialise(), and SampleSecondaries().