61 :
G4VEmModel(nam),fParticleChange(0),isInitialised(false),energyGrid(0),
62 XSTableElectron(0),XSTablePositron(0)
65 fIntrinsicLowEnergyLimit = 100.0*eV;
66 fIntrinsicHighEnergyLimit = 100.0*GeV;
95 if (fPenelopeFSHelper)
96 delete fPenelopeFSHelper;
98 delete fPenelopeAngular;
106 if (verboseLevel > 3)
107 G4cout <<
"Calling G4PenelopeBremsstrahlungModel::Initialise()" <<
G4endl;
113 if (fPenelopeAngular)
119 nBins = std::max(nBins,(
size_t)100);
125 XSTableElectron =
new
127 XSTablePositron =
new
130 if (verboseLevel > 2) {
131 G4cout <<
"Penelope Bremsstrahlung model v2008 is initialized " <<
G4endl
138 if(isInitialised)
return;
140 isInitialised =
true;
152 if (verboseLevel > 3)
153 G4cout <<
"Calling CrossSectionPerVolume() of G4PenelopeBremsstrahlungModel" <<
G4endl;
168 if (verboseLevel > 3)
169 G4cout <<
"Material " << material->
GetName() <<
" has " << atPerMol <<
170 "atoms per molecule" <<
G4endl;
174 moleculeDensity = atomDensity/atPerMol;
176 G4double crossPerVolume = crossPerMolecule*moleculeDensity;
178 if (verboseLevel > 2)
181 G4cout <<
"Mean free path for gamma emission > " << cutEnergy/keV <<
" keV at " <<
182 energy/keV <<
" keV = " << (1./crossPerVolume)/mm <<
" mm" <<
G4endl;
185 return crossPerVolume;
200 G4cout <<
"*** G4PenelopeBremsstrahlungModel -- WARNING ***" <<
G4endl;
201 G4cout <<
"Penelope Bremsstrahlung model v2008 does not calculate cross section _per atom_ " <<
G4endl;
202 G4cout <<
"so the result is always zero. For physics values, please invoke " <<
G4endl;
203 G4cout <<
"GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" <<
G4endl;
214 if (verboseLevel > 3)
215 G4cout <<
"Calling ComputeDEDX() of G4PenelopeBremsstrahlungModel" <<
G4endl;
229 moleculeDensity = atomDensity/atPerMol;
231 G4double sPowerPerVolume = sPowerPerMolecule*moleculeDensity;
233 if (verboseLevel > 2)
236 G4cout <<
"Stopping power < " << cutEnergy/keV <<
" keV at " <<
237 kineticEnergy/keV <<
" keV = " <<
238 sPowerPerVolume/(keV/mm) <<
" keV/mm" <<
G4endl;
240 return sPowerPerVolume;
251 if (verboseLevel > 3)
252 G4cout <<
"Calling SampleSecondaries() of G4PenelopeBremsstrahlungModel" <<
G4endl;
257 if (kineticEnergy <= fIntrinsicLowEnergyLimit)
269 if (kineticEnergy < cutG)
272 if (verboseLevel > 3)
273 G4cout <<
"Going to sample gamma energy for: " <<material->
GetName() <<
" " <<
274 "energy = " << kineticEnergy/keV <<
", cut = " << cutG/keV <<
G4endl;
280 if (verboseLevel > 3)
281 G4cout <<
"Sampled gamma energy: " << gammaEnergy/keV <<
" keV" <<
G4endl;
286 fPenelopeAngular->
SampleDirection(aDynamicParticle,gammaEnergy,0,material);
288 if (verboseLevel > 3)
291 G4double residualPrimaryEnergy = kineticEnergy-gammaEnergy;
292 if (residualPrimaryEnergy < 0)
295 gammaEnergy += residualPrimaryEnergy;
296 residualPrimaryEnergy = 0.0;
300 G4ThreeVector particleDirection1 = initialMomentum - gammaEnergy*gammaDirection1;
301 particleDirection1 = particleDirection1.
unit();
304 if (residualPrimaryEnergy > 0.)
318 fvect->push_back(theGamma);
320 if (verboseLevel > 1)
322 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
323 G4cout <<
"Energy balance from G4PenelopeBremsstrahlung" <<
G4endl;
324 G4cout <<
"Incoming primary energy: " << kineticEnergy/keV <<
" keV" <<
G4endl;
325 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
326 G4cout <<
"Outgoing primary energy: " << residualPrimaryEnergy/keV <<
" keV" <<
G4endl;
327 G4cout <<
"Bremsstrahlung photon " << gammaEnergy/keV <<
" keV" <<
G4endl;
328 G4cout <<
"Total final state: " << (residualPrimaryEnergy+gammaEnergy)/keV
330 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
333 if (verboseLevel > 0)
335 G4double energyDiff = std::fabs(residualPrimaryEnergy+gammaEnergy-kineticEnergy);
336 if (energyDiff > 0.05*keV)
337 G4cout <<
"Warning from G4PenelopeBremsstrahlung: problem with energy conservation: "
339 (residualPrimaryEnergy+gammaEnergy)/keV <<
340 " keV (final) vs. " <<
341 kineticEnergy/keV <<
" keV (initial)" <<
G4endl;
348void G4PenelopeBremsstrahlungModel::ClearTables()
353 for (i=XSTableElectron->begin(); i != XSTableElectron->end(); i++)
358 delete XSTableElectron;
363 for (i=XSTablePositron->begin(); i != XSTablePositron->end(); i++)
368 delete XSTablePositron;
375 if (fPenelopeFSHelper)
378 if (verboseLevel > 2)
379 G4cout <<
"G4PenelopeBremsstrahlungModel: cleared tables" <<
G4endl;
389 return fIntrinsicLowEnergyLimit;
401 if (verboseLevel > 2)
403 G4cout <<
"G4PenelopeBremsstrahlungModel: going to build cross section table " <<
G4endl;
411 ed <<
"Energy Grid looks not initialized" <<
G4endl;
413 G4Exception(
"G4PenelopeBremsstrahlungModel::BuildXSTable()",
424 for (
size_t bin=0;bin<nBins;bin++)
432 ((energy+electron_mass_c2)*(energy+electron_mass_c2)/
433 (energy*(energy+2.0*electron_mass_c2)));
435 G4double restrictedCut = cut/energy;
439 size_t nBinsX = fPenelopeFSHelper->
GetNBinsX();
442 for (
size_t ix=0;ix<nBinsX;ix++)
445 G4double val = (*table)[ix]->Value(logene);
446 tempData[ix] = std::exp(val);
450 if (restrictedCut <= 1)
458 if (restrictedCut <=1)
468 XS1 = XS1A*fact*energy;
469 XH1 = XH1A*fact*energy;
470 XS2 = XS2A*fact*energy*energy;
471 XH2 = XH2A*fact*energy*energy;
476 G4double posCorrection = GetPositronXSCorrection(mat,energy);
486 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
487 XSTableElectron->insert(std::make_pair(theKey,XSEntry));
488 XSTablePositron->insert(std::make_pair(theKey,XSEntry2));
505 G4Exception(
"G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
512 if (!XSTableElectron)
514 G4String excep =
"The Cross Section Table for e- was not initialized correctly!";
515 G4Exception(
"G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
519 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
520 if (XSTableElectron->count(theKey))
521 return XSTableElectron->find(theKey)->second;
524 BuildXSTable(mat,cut);
525 if (XSTableElectron->count(theKey))
526 return XSTableElectron->find(theKey)->second;
530 ed <<
"Unable to build e- table for " << mat->
GetName() <<
G4endl;
531 G4Exception(
"G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
538 if (!XSTablePositron)
540 G4String excep =
"The Cross Section Table for e+ was not initialized correctly!";
541 G4Exception(
"G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
545 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
546 if (XSTablePositron->count(theKey))
547 return XSTablePositron->find(theKey)->second;
550 BuildXSTable(mat,cut);
551 if (XSTablePositron->count(theKey))
552 return XSTablePositron->find(theKey)->second;
556 ed <<
"Unable to build e+ table for " << mat->
GetName() <<
G4endl;
557 G4Exception(
"G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
579 G4double corr = 1.0-std::exp(-t*(1.2359e-1-t*(6.1274e-2-t*
580 (3.1516e-2-t*(7.7446e-3-t*(1.0595e-3-t*
G4DLLIMPORT std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
static G4Electron * Electron()
const G4Material * GetMaterial() const
G4double GetTotNbOfAtomsPerVolume() const
const G4String & GetName() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
const G4String & GetParticleName() const
G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double out_energy, G4int Z, const G4Material *mat=0)
void Initialize()
The Initialize() method forces the cleaning of tables.
G4double GetMomentumIntegral(G4double *y, G4double up, G4int momOrder)
G4double SampleGammaEnergy(G4double energy, const G4Material *, G4double cut)
G4double GetEffectiveZSquared(const G4Material *mat)
G4PhysicsTable * GetScaledXSTable(const G4Material *, G4double cut)
virtual G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *theParticle, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy=DBL_MAX)
virtual G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *theParticle, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
G4PenelopeBremsstrahlungModel(const G4ParticleDefinition *p=0, const G4String &processName="PenBrem")
G4ParticleChangeForLoss * fParticleChange
virtual ~G4PenelopeBremsstrahlungModel()
G4double GetSoftStoppingPower(G4double energy)
Returns the total stopping power due to soft collisions.
G4double GetHardCrossSection(G4double energy)
Returns hard cross section at the given energy.
void AddCrossSectionPoint(size_t binNumber, G4double energy, G4double XH0, G4double XH1, G4double XH2, G4double XS0, G4double XS1, G4double XS2)
G4double GetAtomsPerMolecule(const G4Material *)
Returns the total number of atoms per molecule.
static G4PenelopeOscillatorManager * GetOscillatorManager()
size_t GetVectorLength() const
virtual G4double GetLowEdgeEnergy(size_t binNumber) const
static G4Positron * Positron()
void SetHighEnergyLimit(G4double)
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
virtual void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
void SetDeexcitationFlag(G4bool val)
G4ParticleChangeForLoss * GetParticleChangeForLoss()
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::ostringstream G4ExceptionDescription