Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PenelopeIonisationModel Class Reference

#include <G4PenelopeIonisationModel.hh>

+ Inheritance diagram for G4PenelopeIonisationModel:

Public Member Functions

 G4PenelopeIonisationModel (const G4ParticleDefinition *p=nullptr, const G4String &processName="PenIoni")
 
virtual ~G4PenelopeIonisationModel ()
 
void Initialise (const G4ParticleDefinition *, const G4DataVector &) override
 
void InitialiseLocal (const G4ParticleDefinition *, G4VEmModel *) override
 
G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double, G4double, G4double, G4double, G4double) override
 
G4double CrossSectionPerVolume (const G4Material *material, const G4ParticleDefinition *theParticle, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy=DBL_MAX) override
 
void SampleSecondaries (std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
 
G4double ComputeDEDXPerVolume (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy) override
 
G4double MinEnergyCut (const G4ParticleDefinition *, const G4MaterialCutsCouple *) override
 
void SetVerbosityLevel (G4int lev)
 
G4int GetVerbosityLevel ()
 
G4PenelopeIonisationModeloperator= (const G4PenelopeIonisationModel &right)=delete
 
 G4PenelopeIonisationModel (const G4PenelopeIonisationModel &)=delete
 
- Public Member Functions inherited from G4VEmModel
 G4VEmModel (const G4String &nam)
 
virtual ~G4VEmModel ()
 
virtual void InitialiseForMaterial (const G4ParticleDefinition *, const G4Material *)
 
virtual void InitialiseForElement (const G4ParticleDefinition *, G4int Z)
 
virtual G4double GetPartialCrossSection (const G4Material *, G4int level, const G4ParticleDefinition *, G4double kineticEnergy)
 
virtual G4double ComputeCrossSectionPerShell (const G4ParticleDefinition *, G4int Z, G4int shellIdx, G4double kinEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
virtual G4double ChargeSquareRatio (const G4Track &)
 
virtual G4double GetChargeSquareRatio (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual G4double GetParticleCharge (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual void StartTracking (G4Track *)
 
virtual void CorrectionsAlongStep (const G4MaterialCutsCouple *, const G4DynamicParticle *, const G4double &length, G4double &eloss)
 
virtual G4double Value (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
 
virtual G4double MinPrimaryEnergy (const G4Material *, const G4ParticleDefinition *, G4double cut=0.0)
 
virtual void SetupForMaterial (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual void DefineForRegion (const G4Region *)
 
virtual void FillNumberOfSecondaries (G4int &numberOfTriplets, G4int &numberOfRecoil)
 
virtual void ModelDescription (std::ostream &outFile) const
 
void InitialiseElementSelectors (const G4ParticleDefinition *, const G4DataVector &)
 
std::vector< G4EmElementSelector * > * GetElementSelectors ()
 
void SetElementSelectors (std::vector< G4EmElementSelector * > *)
 
G4double ComputeDEDX (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=DBL_MAX)
 
G4double CrossSection (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4double ComputeMeanFreePath (const G4ParticleDefinition *, G4double kineticEnergy, const G4Material *, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, const G4Element *, G4double kinEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementSelectRandomAtom (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementSelectTargetAtom (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double logKineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementSelectRandomAtom (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementGetCurrentElement (const G4Material *mat=nullptr) const
 
G4int SelectRandomAtomNumber (const G4Material *) const
 
const G4IsotopeGetCurrentIsotope (const G4Element *elm=nullptr) const
 
G4int SelectIsotopeNumber (const G4Element *) const
 
void SetParticleChange (G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
 
void SetCrossSectionTable (G4PhysicsTable *, G4bool isLocal)
 
G4ElementDataGetElementData ()
 
G4PhysicsTableGetCrossSectionTable ()
 
G4VEmFluctuationModelGetModelOfFluctuations ()
 
G4VEmAngularDistributionGetAngularDistribution ()
 
G4VEmModelGetTripletModel ()
 
void SetTripletModel (G4VEmModel *)
 
void SetAngularDistribution (G4VEmAngularDistribution *)
 
G4double HighEnergyLimit () const
 
G4double LowEnergyLimit () const
 
G4double HighEnergyActivationLimit () const
 
G4double LowEnergyActivationLimit () const
 
G4double PolarAngleLimit () const
 
G4double SecondaryThreshold () const
 
G4bool DeexcitationFlag () const
 
G4bool ForceBuildTableFlag () const
 
G4bool UseAngularGeneratorFlag () const
 
void SetAngularGeneratorFlag (G4bool)
 
void SetHighEnergyLimit (G4double)
 
void SetLowEnergyLimit (G4double)
 
void SetActivationHighEnergyLimit (G4double)
 
void SetActivationLowEnergyLimit (G4double)
 
G4bool IsActive (G4double kinEnergy) const
 
void SetPolarAngleLimit (G4double)
 
void SetSecondaryThreshold (G4double)
 
void SetDeexcitationFlag (G4bool val)
 
void SetForceBuildTable (G4bool val)
 
void SetFluctuationFlag (G4bool val)
 
void SetMasterThread (G4bool val)
 
G4bool IsMaster () const
 
void SetUseBaseMaterials (G4bool val)
 
G4bool UseBaseMaterials () const
 
G4double MaxSecondaryKinEnergy (const G4DynamicParticle *dynParticle)
 
const G4StringGetName () const
 
void SetCurrentCouple (const G4MaterialCutsCouple *)
 
G4bool IsLocked () const
 
void SetLocked (G4bool)
 
void SetLPMFlag (G4bool)
 
G4VEmModeloperator= (const G4VEmModel &right)=delete
 
 G4VEmModel (const G4VEmModel &)=delete
 

Protected Attributes

G4ParticleChangeForLossfParticleChange
 
const G4ParticleDefinitionfParticle
 
- Protected Attributes inherited from G4VEmModel
G4ElementDatafElementData = nullptr
 
G4VParticleChangepParticleChange = nullptr
 
G4PhysicsTablexSectionTable = nullptr
 
const G4MaterialpBaseMaterial = nullptr
 
const std::vector< G4double > * theDensityFactor = nullptr
 
const std::vector< G4int > * theDensityIdx = nullptr
 
G4double inveplus
 
G4double pFactor = 1.0
 
std::size_t currentCoupleIndex = 0
 
std::size_t basedCoupleIndex = 0
 
G4bool lossFlucFlag = true
 

Additional Inherited Members

- Protected Member Functions inherited from G4VEmModel
G4ParticleChangeForLossGetParticleChangeForLoss ()
 
G4ParticleChangeForGammaGetParticleChangeForGamma ()
 
virtual G4double MaxSecondaryEnergy (const G4ParticleDefinition *, G4double kineticEnergy)
 
const G4MaterialCutsCoupleCurrentCouple () const
 
void SetCurrentElement (const G4Element *)
 

Detailed Description

Definition at line 65 of file G4PenelopeIonisationModel.hh.

Constructor & Destructor Documentation

◆ G4PenelopeIonisationModel() [1/2]

G4PenelopeIonisationModel::G4PenelopeIonisationModel ( const G4ParticleDefinition * p = nullptr,
const G4String & processName = "PenIoni" )
explicit

Definition at line 73 of file G4PenelopeIonisationModel.cc.

75 :G4VEmModel(nam),fParticleChange(nullptr),fParticle(nullptr),
76 fCrossSectionHandler(nullptr),
77 fAtomDeexcitation(nullptr), fKineticEnergy1(0.*eV),
78 fCosThetaPrimary(1.0),fEnergySecondary(0.*eV),
79 fCosThetaSecondary(0.0),fTargetOscillator(-1),
80 fIsInitialised(false),fPIXEflag(false),fLocalTable(false)
81{
82 fIntrinsicLowEnergyLimit = 100.0*eV;
83 fIntrinsicHighEnergyLimit = 100.0*GeV;
84 // SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
85 SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
86 fNBins = 200;
87
88 if (part)
89 SetParticle(part);
90
91 //
93 //
94 fVerboseLevel= 0;
95 // Verbosity scale:
96 // 0 = nothing
97 // 1 = warning for energy non-conservation
98 // 2 = details of energy budget
99 // 3 = calculation of cross sections, file openings, sampling of atoms
100 // 4 = entering in methods
101
102 // Atomic deexcitation model activated by default
104}
G4ParticleChangeForLoss * fParticleChange
const G4ParticleDefinition * fParticle
static G4PenelopeOscillatorManager * GetOscillatorManager()
void SetHighEnergyLimit(G4double)
void SetDeexcitationFlag(G4bool val)
G4VEmModel(const G4String &nam)
Definition G4VEmModel.cc:67

◆ ~G4PenelopeIonisationModel()

G4PenelopeIonisationModel::~G4PenelopeIonisationModel ( )
virtual

Definition at line 108 of file G4PenelopeIonisationModel.cc.

109{
110 if (IsMaster() || fLocalTable)
111 {
112 if (fCrossSectionHandler)
113 delete fCrossSectionHandler;
114 }
115}
G4bool IsMaster() const

◆ G4PenelopeIonisationModel() [2/2]

G4PenelopeIonisationModel::G4PenelopeIonisationModel ( const G4PenelopeIonisationModel & )
delete

Member Function Documentation

◆ ComputeCrossSectionPerAtom()

G4double G4PenelopeIonisationModel::ComputeCrossSectionPerAtom ( const G4ParticleDefinition * ,
G4double ,
G4double ,
G4double ,
G4double ,
G4double  )
overridevirtual

Reimplemented from G4VEmModel.

Definition at line 340 of file G4PenelopeIonisationModel.cc.

346{
347 G4cout << "*** G4PenelopeIonisationModel -- WARNING ***" << G4endl;
348 G4cout << "Penelope Ionisation model v2008 does not calculate cross section _per atom_ " << G4endl;
349 G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
350 G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
351 return 0;
352}
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout

◆ ComputeDEDXPerVolume()

G4double G4PenelopeIonisationModel::ComputeDEDXPerVolume ( const G4Material * material,
const G4ParticleDefinition * theParticle,
G4double kineticEnergy,
G4double cutEnergy )
overridevirtual

Reimplemented from G4VEmModel.

Definition at line 356 of file G4PenelopeIonisationModel.cc.

360{
361 // Penelope model v2008 to calculate the stopping power for soft inelastic collisions
362 // below the threshold. It makes use of the Generalised Oscillator Strength (GOS)
363 // model from
364 // D. Liljequist, J. Phys. D: Appl. Phys. 16 (1983) 1567
365 //
366 // The stopping power is calculated analytically using the dsigma/dW cross
367 // section from the GOS models, which includes separate contributions from
368 // distant longitudinal collisions, distant transverse collisions and
369 // close collisions. Only the atomic oscillators that come in the play
370 // (according to the threshold) are considered for the calculation.
371 // Differential cross sections have a different form for e+ and e-.
372 //
373 // Fermi density correction is calculated analytically according to
374 // U. Fano, Ann. Rev. Nucl. Sci. 13 (1963),1
375
376 if (fVerboseLevel > 3)
377 G4cout << "Calling ComputeDEDX() of G4PenelopeIonisationModel" << G4endl;
378
379 //Either Initialize() was not called, or we are in a slave and InitializeLocal() was
380 //not invoked
381 if (!fCrossSectionHandler)
382 {
383 //create a **thread-local** version of the table. Used only for G4EmCalculator and
384 //Unit Tests
385 fLocalTable = true;
386 fCrossSectionHandler = new G4PenelopeIonisationXSHandler(fNBins);
387 }
388
389 const G4PenelopeCrossSection* theXS =
390 fCrossSectionHandler->GetCrossSectionTableForCouple(theParticle,material,
391 cutEnergy);
392 if (!theXS)
393 {
394 //If we are here, it means that Initialize() was inkoved, but the MaterialTable was
395 //not filled up. This can happen in a UnitTest or via G4EmCalculator
396 if (fVerboseLevel > 0)
397 {
398 //Issue a G4Exception (warning) only in verbose mode
400 ed << "Unable to retrieve the cross section table for " <<
401 theParticle->GetParticleName() <<
402 " in " << material->GetName() << ", cut = " << cutEnergy/keV << " keV " << G4endl;
403 ed << "This can happen only in Unit Tests or via G4EmCalculator" << G4endl;
404 G4Exception("G4PenelopeIonisationModel::ComputeDEDXPerVolume()",
405 "em2038",JustWarning,ed);
406 }
407 //protect file reading via autolock
408 G4AutoLock lock(&PenelopeIonisationModelMutex);
409 fCrossSectionHandler->BuildXSTable(material,cutEnergy,theParticle);
410 lock.unlock();
411 //now it should be ok
412 theXS =
413 fCrossSectionHandler->GetCrossSectionTableForCouple(theParticle,
414 material,
415 cutEnergy);
416 }
417
418 G4double sPowerPerMolecule = 0.0;
419 if (theXS)
420 sPowerPerMolecule = theXS->GetSoftStoppingPower(kineticEnergy);
421
422 G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
423 G4double atPerMol = fOscManager->GetAtomsPerMolecule(material);
424
425 G4double moleculeDensity = 0.;
426 if (atPerMol)
427 moleculeDensity = atomDensity/atPerMol;
428 G4double sPowerPerVolume = sPowerPerMolecule*moleculeDensity;
429
430 if (fVerboseLevel > 2)
431 {
432 G4cout << "G4PenelopeIonisationModel " << G4endl;
433 G4cout << "Stopping power < " << cutEnergy/keV << " keV at " <<
434 kineticEnergy/keV << " keV = " <<
435 sPowerPerVolume/(keV/mm) << " keV/mm" << G4endl;
436 }
437 return sPowerPerVolume;
438}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
double G4double
Definition G4Types.hh:83
G4double GetTotNbOfAtomsPerVolume() const
const G4String & GetName() const
const G4String & GetParticleName() const
G4double GetSoftStoppingPower(G4double energy) const
Returns the total stopping power due to soft collisions.
void BuildXSTable(const G4Material *, G4double cut, const G4ParticleDefinition *, G4bool isMaster=true)
This can be inkoved only by the master.
const G4PenelopeCrossSection * GetCrossSectionTableForCouple(const G4ParticleDefinition *, const G4Material *, const G4double cut) const
G4double GetAtomsPerMolecule(const G4Material *)
Returns the total number of atoms per molecule.

◆ CrossSectionPerVolume()

G4double G4PenelopeIonisationModel::CrossSectionPerVolume ( const G4Material * material,
const G4ParticleDefinition * theParticle,
G4double kineticEnergy,
G4double cutEnergy,
G4double maxEnergy = DBL_MAX )
overridevirtual

Reimplemented from G4VEmModel.

Definition at line 236 of file G4PenelopeIonisationModel.cc.

242{
243 // Penelope model v2008 to calculate the cross section for inelastic collisions above the
244 // threshold. It makes use of the Generalised Oscillator Strength (GOS) model from
245 // D. Liljequist, J. Phys. D: Appl. Phys. 16 (1983) 1567
246 //
247 // The total cross section is calculated analytically by taking
248 // into account the atomic oscillators coming into the play for a given threshold.
249 //
250 // For incident e- the maximum energy allowed for the delta-rays is energy/2.
251 // because particles are undistinghishable.
252 //
253 // The contribution is splitted in three parts: distant longitudinal collisions,
254 // distant transverse collisions and close collisions. Each term is described by
255 // its own analytical function.
256 // Fermi density correction is calculated analytically according to
257 // U. Fano, Ann. Rev. Nucl. Sci. 13 (1963),1
258 //
259 if (fVerboseLevel > 3)
260 G4cout << "Calling CrossSectionPerVolume() of G4PenelopeIonisationModel" << G4endl;
261
262 SetupForMaterial(theParticle, material, energy);
263
264 G4double totalCross = 0.0;
265 G4double crossPerMolecule = 0.;
266
267 //Either Initialize() was not called, or we are in a slave and InitializeLocal() was
268 //not invoked
269 if (!fCrossSectionHandler)
270 {
271 //create a **thread-local** version of the table. Used only for G4EmCalculator and
272 //Unit Tests
273 fLocalTable = true;
274 fCrossSectionHandler = new G4PenelopeIonisationXSHandler(fNBins);
275 }
276
277 const G4PenelopeCrossSection* theXS =
278 fCrossSectionHandler->GetCrossSectionTableForCouple(theParticle,
279 material,
280 cutEnergy);
281 if (!theXS)
282 {
283 //If we are here, it means that Initialize() was inkoved, but the MaterialTable was
284 //not filled up. This can happen in a UnitTest or via G4EmCalculator
285 if (fVerboseLevel > 0)
286 {
287 //Issue a G4Exception (warning) only in verbose mode
289 ed << "Unable to retrieve the cross section table for " <<
290 theParticle->GetParticleName() <<
291 " in " << material->GetName() << ", cut = " << cutEnergy/keV << " keV " << G4endl;
292 ed << "This can happen only in Unit Tests or via G4EmCalculator" << G4endl;
293 G4Exception("G4PenelopeIonisationModel::CrossSectionPerVolume()",
294 "em2038",JustWarning,ed);
295 }
296 //protect file reading via autolock
297 G4AutoLock lock(&PenelopeIonisationModelMutex);
298 fCrossSectionHandler->BuildXSTable(material,cutEnergy,theParticle);
299 lock.unlock();
300 //now it should be ok
301 theXS =
302 fCrossSectionHandler->GetCrossSectionTableForCouple(theParticle,
303 material,
304 cutEnergy);
305 }
306
307 if (theXS)
308 crossPerMolecule = theXS->GetHardCrossSection(energy);
309
310 G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
311 G4double atPerMol = fOscManager->GetAtomsPerMolecule(material);
312
313 if (fVerboseLevel > 3)
314 G4cout << "Material " << material->GetName() << " has " << atPerMol <<
315 "atoms per molecule" << G4endl;
316
317 G4double moleculeDensity = 0.;
318 if (atPerMol)
319 moleculeDensity = atomDensity/atPerMol;
320 G4double crossPerVolume = crossPerMolecule*moleculeDensity;
321
322 if (fVerboseLevel > 2)
323 {
324 G4cout << "G4PenelopeIonisationModel " << G4endl;
325 G4cout << "Mean free path for delta emission > " << cutEnergy/keV << " keV at " <<
326 energy/keV << " keV = " << (1./crossPerVolume)/mm << " mm" << G4endl;
327 if (theXS)
328 totalCross = (theXS->GetTotalCrossSection(energy))*moleculeDensity;
329 G4cout << "Total free path for ionisation (no threshold) at " <<
330 energy/keV << " keV = " << (1./totalCross)/mm << " mm" << G4endl;
331 }
332 return crossPerVolume;
333}
G4double GetTotalCrossSection(G4double energy) const
Returns total cross section at the given energy.
G4double GetHardCrossSection(G4double energy) const
Returns hard cross section at the given energy.
virtual void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
G4double energy(const ThreeVector &p, const G4double m)

◆ GetVerbosityLevel()

G4int G4PenelopeIonisationModel::GetVerbosityLevel ( )
inline

Definition at line 109 of file G4PenelopeIonisationModel.hh.

109{return fVerboseLevel;};

◆ Initialise()

void G4PenelopeIonisationModel::Initialise ( const G4ParticleDefinition * particle,
const G4DataVector & theCuts )
overridevirtual

Implements G4VEmModel.

Definition at line 119 of file G4PenelopeIonisationModel.cc.

121{
122 if (fVerboseLevel > 3)
123 G4cout << "Calling G4PenelopeIonisationModel::Initialise()" << G4endl;
124
125 fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
126 //Issue warning if the AtomicDeexcitation has not been declared
127 if (!fAtomDeexcitation)
128 {
129 G4cout << G4endl;
130 G4cout << "WARNING from G4PenelopeIonisationModel " << G4endl;
131 G4cout << "Atomic de-excitation module is not instantiated, so there will not be ";
132 G4cout << "any fluorescence/Auger emission." << G4endl;
133 G4cout << "Please make sure this is intended" << G4endl;
134 }
135
136 if (fAtomDeexcitation)
137 fPIXEflag = fAtomDeexcitation->IsPIXEActive();
138
139 //If the PIXE flag is active, the PIXE interface will take care of the
140 //atomic de-excitation. The model does not need to do that.
141 //Issue warnings here
142 if (fPIXEflag && IsMaster() && particle==G4Electron::Electron())
143 {
145 G4cout << "======================================================================" << G4endl;
146 G4cout << "The G4PenelopeIonisationModel is being used with the PIXE flag ON." << G4endl;
147 G4cout << "Atomic de-excitation will be produced statistically by the PIXE " << G4endl;
148 G4cout << "interface by using the shell cross section --> " << theModel << G4endl;
149 G4cout << "The built-in model procedure for atomic de-excitation is disabled. " << G4endl;
150 G4cout << "*Please be sure this is intended*, or disable PIXE by" << G4endl;
151 G4cout << "/process/em/pixe false" << G4endl;
152 G4cout << "======================================================================" << G4endl;
153 }
154
155 SetParticle(particle);
156
157 //Only the master model creates/manages the tables. All workers get the
158 //pointer to the table, and use it as readonly
159 if (IsMaster() && particle == fParticle)
160 {
161 //Set the number of bins for the tables. 20 points per decade
162 fNBins = (std::size_t) (20*std::log10(HighEnergyLimit()/LowEnergyLimit()));
163 fNBins = std::max(fNBins,(std::size_t)100);
164
165 //Clear and re-build the tables
166 if (fCrossSectionHandler)
167 {
168 delete fCrossSectionHandler;
169 fCrossSectionHandler = 0;
170 }
171 fCrossSectionHandler = new G4PenelopeIonisationXSHandler(fNBins);
172 fCrossSectionHandler->SetVerboseLevel(fVerboseLevel);
173
174 //Build tables for all materials
175 G4ProductionCutsTable* theCoupleTable =
177 for (G4int i=0;i<(G4int)theCoupleTable->GetTableSize();++i)
178 {
179 const G4Material* theMat =
180 theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
181 //Forces the building of the cross section tables
182 fCrossSectionHandler->BuildXSTable(theMat,theCuts.at(i),particle,
183 IsMaster());
184 }
185
186 if (fVerboseLevel > 2) {
187 G4cout << "Penelope Ionisation model v2008 is initialized " << G4endl
188 << "Energy range: "
189 << LowEnergyLimit() / keV << " keV - "
190 << HighEnergyLimit() / GeV << " GeV. Using "
191 << fNBins << " bins."
192 << G4endl;
193 }
194 }
195
196 if(fIsInitialised)
197 return;
199 fIsInitialised = true;
200
201 return;
202}
int G4int
Definition G4Types.hh:85
static G4Electron * Electron()
Definition G4Electron.cc:91
static G4EmParameters * Instance()
const G4String & PIXEElectronCrossSectionModel()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
void SetVerboseLevel(G4int vl)
Setter for the verbosity level.
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
G4ParticleChangeForLoss * GetParticleChangeForLoss()

◆ InitialiseLocal()

void G4PenelopeIonisationModel::InitialiseLocal ( const G4ParticleDefinition * part,
G4VEmModel * masterModel )
overridevirtual

Reimplemented from G4VEmModel.

Definition at line 206 of file G4PenelopeIonisationModel.cc.

208{
209 if (fVerboseLevel > 3)
210 G4cout << "Calling G4PenelopeIonisationModel::InitialiseLocal()" << G4endl;
211 //
212 //Check that particle matches: one might have multiple master models (e.g.
213 //for e+ and e-).
214 //
215 if (part == fParticle)
216 {
217 //Get the const table pointers from the master to the workers
218 const G4PenelopeIonisationModel* theModel =
219 static_cast<G4PenelopeIonisationModel*> (masterModel);
220
221 //Copy pointers to the data tables
222 fCrossSectionHandler = theModel->fCrossSectionHandler;
223
224 //copy data
225 fNBins = theModel->fNBins;
226
227 //Same verbosity for all workers, as the master
228 fVerboseLevel = theModel->fVerboseLevel;
229 }
230 return;
231}

◆ MinEnergyCut()

G4double G4PenelopeIonisationModel::MinEnergyCut ( const G4ParticleDefinition * ,
const G4MaterialCutsCouple *  )
overridevirtual

Reimplemented from G4VEmModel.

Definition at line 442 of file G4PenelopeIonisationModel.cc.

444{
445 return fIntrinsicLowEnergyLimit;
446}

◆ operator=()

G4PenelopeIonisationModel & G4PenelopeIonisationModel::operator= ( const G4PenelopeIonisationModel & right)
delete

◆ SampleSecondaries()

void G4PenelopeIonisationModel::SampleSecondaries ( std::vector< G4DynamicParticle * > * fvect,
const G4MaterialCutsCouple * couple,
const G4DynamicParticle * aDynamicParticle,
G4double tmin,
G4double maxEnergy )
overridevirtual

Implements G4VEmModel.

Definition at line 450 of file G4PenelopeIonisationModel.cc.

454{
455 // Penelope model v2008 to sample the final state following an hard inelastic interaction.
456 // It makes use of the Generalised Oscillator Strength (GOS) model from
457 // D. Liljequist, J. Phys. D: Appl. Phys. 16 (1983) 1567
458 //
459 // The GOS model is used to calculate the individual cross sections for all
460 // the atomic oscillators coming in the play, taking into account the three
461 // contributions (distant longitudinal collisions, distant transverse collisions and
462 // close collisions). Then the target shell and the interaction channel are
463 // sampled. Final state of the delta-ray (energy, angle) are generated according
464 // to the analytical distributions (dSigma/dW) for the selected interaction
465 // channels.
466 // For e-, the maximum energy for the delta-ray is initialEnergy/2. (because
467 // particles are indistinghusbable), while it is the full initialEnergy for
468 // e+.
469 // The efficiency of the random sampling algorithm (e.g. for close collisions)
470 // decreases when initial and cutoff energy increase (e.g. 87% for 10-keV primary
471 // and 1 keV threshold, 99% for 10-MeV primary and 10-keV threshold).
472 // Differential cross sections have a different form for e+ and e-.
473 //
474 // WARNING: The model provides an _average_ description of inelastic collisions.
475 // Anyway, the energy spectrum associated to distant excitations of a given
476 // atomic shell is approximated as a single resonance. The simulated energy spectra
477 // show _unphysical_ narrow peaks at energies that are multiple of the shell
478 // resonance energies. The spurious speaks are automatically smoothed out after
479 // multiple inelastic collisions.
480 //
481 // The model determines also the original shell from which the delta-ray is expelled,
482 // in order to produce fluorescence de-excitation (from G4DeexcitationManager)
483 //
484 // Fermi density correction is calculated analytically according to
485 // U. Fano, Ann. Rev. Nucl. Sci. 13 (1963),1
486
487 if (fVerboseLevel > 3)
488 G4cout << "Calling SamplingSecondaries() of G4PenelopeIonisationModel" << G4endl;
489
490 G4double kineticEnergy0 = aDynamicParticle->GetKineticEnergy();
491 const G4ParticleDefinition* theParticle = aDynamicParticle->GetDefinition();
492
493 if (kineticEnergy0 <= fIntrinsicLowEnergyLimit)
494 {
497 return ;
498 }
499
500 const G4Material* material = couple->GetMaterial();
501 const G4PenelopeOscillatorTable* theTable = fOscManager->GetOscillatorTableIonisation(material);
502
503 G4ParticleMomentum particleDirection0 = aDynamicParticle->GetMomentumDirection();
504
505 //Initialise final-state variables. The proper values will be set by the methods
506 // SampleFinalStateElectron() and SampleFinalStatePositron()
507 fKineticEnergy1=kineticEnergy0;
508 fCosThetaPrimary=1.0;
509 fEnergySecondary=0.0;
510 fCosThetaSecondary=1.0;
511 fTargetOscillator = -1;
512
513 if (theParticle == G4Electron::Electron())
514 SampleFinalStateElectron(material,cutE,kineticEnergy0);
515 else if (theParticle == G4Positron::Positron())
516 SampleFinalStatePositron(material,cutE,kineticEnergy0);
517 else
518 {
520 ed << "Invalid particle " << theParticle->GetParticleName() << G4endl;
521 G4Exception("G4PenelopeIonisationModel::SamplingSecondaries()",
522 "em0001",FatalException,ed);
523
524 }
525 if (fEnergySecondary == 0) return;
526
527 if (fVerboseLevel > 3)
528 {
529 G4cout << "G4PenelopeIonisationModel::SamplingSecondaries() for " <<
530 theParticle->GetParticleName() << G4endl;
531 G4cout << "Final eKin = " << fKineticEnergy1 << " keV" << G4endl;
532 G4cout << "Final cosTheta = " << fCosThetaPrimary << G4endl;
533 G4cout << "Delta-ray eKin = " << fEnergySecondary << " keV" << G4endl;
534 G4cout << "Delta-ray cosTheta = " << fCosThetaSecondary << G4endl;
535 G4cout << "Oscillator: " << fTargetOscillator << G4endl;
536 }
537
538 //Update the primary particle
539 G4double sint = std::sqrt(1. - fCosThetaPrimary*fCosThetaPrimary);
540 G4double phiPrimary = twopi * G4UniformRand();
541 G4double dirx = sint * std::cos(phiPrimary);
542 G4double diry = sint * std::sin(phiPrimary);
543 G4double dirz = fCosThetaPrimary;
544
545 G4ThreeVector electronDirection1(dirx,diry,dirz);
546 electronDirection1.rotateUz(particleDirection0);
547
548 if (fKineticEnergy1 > 0)
549 {
550 fParticleChange->ProposeMomentumDirection(electronDirection1);
552 }
553 else
555
556 //Generate the delta ray
557 G4double ionEnergyInPenelopeDatabase =
558 (*theTable)[fTargetOscillator]->GetIonisationEnergy();
559
560 //Now, try to handle fluorescence
561 //Notice: merged levels are indicated with Z=0 and flag=30
562 G4int shFlag = (*theTable)[fTargetOscillator]->GetShellFlag();
563 G4int Z = (G4int) (*theTable)[fTargetOscillator]->GetParentZ();
564
565 //initialize here, then check photons created by Atomic-Deexcitation, and the final state e-
567 G4double bindingEnergy = 0.*eV;
568
569 const G4AtomicShell* shell = nullptr;
570 //Real level
571 if (Z > 0 && shFlag<30)
572 {
573 shell = transitionManager->Shell(Z,shFlag-1);
574 bindingEnergy = shell->BindingEnergy();
575 //shellId = shell->ShellId();
576 }
577
578 //correct the fEnergySecondary to account for the fact that the Penelope
579 //database of ionisation energies is in general (slightly) different
580 //from the fluorescence database used in Geant4.
581 fEnergySecondary += ionEnergyInPenelopeDatabase-bindingEnergy;
582
583 G4double localEnergyDeposit = bindingEnergy;
584 //testing purposes only
585 G4double energyInFluorescence = 0;
586 G4double energyInAuger = 0;
587
588 if (fEnergySecondary < 0)
589 {
590 //It means that there was some problem/mismatch between the two databases.
591 //In this case, the available energy is ok to excite the level according
592 //to the Penelope database, but not according to the Geant4 database
593 //Full residual energy is deposited locally
594 localEnergyDeposit += fEnergySecondary;
595 fEnergySecondary = 0.0;
596 }
597
598 //Notice: shell might be nullptr (invalid!) if shFlag=30. Must be protected
599 //Disable the built-in de-excitation of the PIXE flag is active. In this
600 //case, the PIXE interface takes care (statistically) of producing the
601 //de-excitation.
602 //Now, take care of fluorescence, if required
603 if (fAtomDeexcitation && !fPIXEflag && shell)
604 {
605 G4int index = couple->GetIndex();
606 if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
607 {
608 std::size_t nBefore = fvect->size();
609 fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
610 std::size_t nAfter = fvect->size();
611
612 if (nAfter>nBefore) //actual production of fluorescence
613 {
614 for (std::size_t j=nBefore;j<nAfter;++j) //loop on products
615 {
616 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
617 if (itsEnergy < localEnergyDeposit) // valid secondary, generate it
618 {
619 localEnergyDeposit -= itsEnergy;
620 if (((*fvect)[j])->GetParticleDefinition() == G4Gamma::Definition())
621 energyInFluorescence += itsEnergy;
622 else if (((*fvect)[j])->GetParticleDefinition() == G4Electron::Definition())
623 energyInAuger += itsEnergy;
624 }
625 else //invalid secondary: takes more than the available energy: delete it
626 {
627 delete (*fvect)[j];
628 (*fvect)[j] = nullptr;
629 }
630 }
631 }
632 }
633 }
634
635 // Generate the delta ray --> to be done only if above cut
636 if (fEnergySecondary > cutE)
637 {
638 G4DynamicParticle* electron = nullptr;
639 G4double sinThetaE = std::sqrt(1.-fCosThetaSecondary*fCosThetaSecondary);
640 G4double phiEl = phiPrimary+pi; //pi with respect to the primary electron/positron
641 G4double xEl = sinThetaE * std::cos(phiEl);
642 G4double yEl = sinThetaE * std::sin(phiEl);
643 G4double zEl = fCosThetaSecondary;
644 G4ThreeVector eDirection(xEl,yEl,zEl); //electron direction
645 eDirection.rotateUz(particleDirection0);
647 eDirection,fEnergySecondary) ;
648 fvect->push_back(electron);
649 }
650 else
651 {
652 localEnergyDeposit += fEnergySecondary;
653 fEnergySecondary = 0;
654 }
655
656 if (localEnergyDeposit < 0) //Should not be: issue a G4Exception (warning)
657 {
658 G4Exception("G4PenelopeIonisationModel::SampleSecondaries()",
659 "em2099",JustWarning,"WARNING: Negative local energy deposit");
660 localEnergyDeposit=0.;
661 }
662 fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
663
664 if (fVerboseLevel > 1)
665 {
666 G4cout << "-----------------------------------------------------------" << G4endl;
667 G4cout << "Energy balance from G4PenelopeIonisation" << G4endl;
668 G4cout << "Incoming primary energy: " << kineticEnergy0/keV << " keV" << G4endl;
669 G4cout << "-----------------------------------------------------------" << G4endl;
670 G4cout << "Outgoing primary energy: " << fKineticEnergy1/keV << " keV" << G4endl;
671 G4cout << "Delta ray " << fEnergySecondary/keV << " keV" << G4endl;
672 if (energyInFluorescence)
673 G4cout << "Fluorescence x-rays: " << energyInFluorescence/keV << " keV" << G4endl;
674 if (energyInAuger)
675 G4cout << "Auger electrons: " << energyInAuger/keV << " keV" << G4endl;
676 G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
677 G4cout << "Total final state: " << (fEnergySecondary+energyInFluorescence+fKineticEnergy1+
678 localEnergyDeposit+energyInAuger)/keV <<
679 " keV" << G4endl;
680 G4cout << "-----------------------------------------------------------" << G4endl;
681 }
682
683 if (fVerboseLevel > 0)
684 {
685 G4double energyDiff = std::fabs(fEnergySecondary+energyInFluorescence+fKineticEnergy1+
686 localEnergyDeposit+energyInAuger-kineticEnergy0);
687 if (energyDiff > 0.05*keV)
688 G4cout << "Warning from G4PenelopeIonisation: problem with energy conservation: " <<
689 (fEnergySecondary+energyInFluorescence+fKineticEnergy1+localEnergyDeposit+energyInAuger)/keV <<
690 " keV (final) vs. " <<
691 kineticEnergy0/keV << " keV (initial)" << G4endl;
692 }
693
694}
@ FatalException
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
#define G4UniformRand()
Definition Randomize.hh:52
G4double BindingEnergy() const
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
static G4AtomicTransitionManager * Instance()
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
Definition G4Electron.cc:45
static G4Gamma * Definition()
Definition G4Gamma.cc:43
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
static G4Positron * Positron()
Definition G4Positron.cc:90
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)

◆ SetVerbosityLevel()

void G4PenelopeIonisationModel::SetVerbosityLevel ( G4int lev)
inline

Definition at line 108 of file G4PenelopeIonisationModel.hh.

108{fVerboseLevel = lev;};

Member Data Documentation

◆ fParticle

const G4ParticleDefinition* G4PenelopeIonisationModel::fParticle
protected

Definition at line 116 of file G4PenelopeIonisationModel.hh.

Referenced by Initialise(), and InitialiseLocal().

◆ fParticleChange

G4ParticleChangeForLoss* G4PenelopeIonisationModel::fParticleChange
protected

Definition at line 115 of file G4PenelopeIonisationModel.hh.

Referenced by Initialise(), and SampleSecondaries().


The documentation for this class was generated from the following files: