Geant4 11.4.0
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 G4Material *, const G4ParticleDefinition *, const G4double kinEnergy, const G4double cutEnergy, 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)
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)
void SetMasterThread (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

Referenced by G4PenelopeIonisationModel(), InitialiseLocal(), and operator=().

◆ ~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 342 of file G4PenelopeIonisationModel.cc.

348{
349 G4cout << "*** G4PenelopeIonisationModel -- WARNING ***" << G4endl;
350 G4cout << "Penelope Ionisation model v2008 does not calculate cross section _per atom_ " << G4endl;
351 G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
352 G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
353 return 0;
354}
#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 358 of file G4PenelopeIonisationModel.cc.

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

◆ 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 = " <<
327 (crossPerVolume ? (1./crossPerVolume)/mm : DBL_MAX) << " mm" << G4endl;
328 if (theXS)
329 totalCross = (theXS->GetTotalCrossSection(energy))*moleculeDensity;
330 G4cout << "Total free path for ionisation (no threshold) at " <<
331 energy/keV << " keV = " <<
332 (totalCross ? (1./totalCross)/mm : DBL_MAX) << " mm" << G4endl;
333 }
334 return crossPerVolume;
335}
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)
#define DBL_MAX
Definition templates.hh:62

◆ 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
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}
G4PenelopeIonisationModel(const G4ParticleDefinition *p=nullptr, const G4String &processName="PenIoni")

◆ MinEnergyCut()

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

Reimplemented from G4VEmModel.

Definition at line 444 of file G4PenelopeIonisationModel.cc.

446{
447 return fIntrinsicLowEnergyLimit;
448}

◆ 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 452 of file G4PenelopeIonisationModel.cc.

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

◆ fParticleChange

G4ParticleChangeForLoss* G4PenelopeIonisationModel::fParticleChange
protected

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