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

#include <G4DensityEffectCalculator.hh>

Public Member Functions

 G4DensityEffectCalculator (const G4Material *, G4int)
 
 ~G4DensityEffectCalculator ()
 
G4double ComputeDensityCorrection (G4double x)
 

Detailed Description

Definition at line 53 of file G4DensityEffectCalculator.hh.

Constructor & Destructor Documentation

◆ G4DensityEffectCalculator()

G4DensityEffectCalculator::G4DensityEffectCalculator ( const G4Material * mat,
G4int n )

Definition at line 57 of file G4DensityEffectCalculator.cc.

58 : fMaterial(mat), nlev(n)
59{
60 fVerbose = std::max(fVerbose, G4NistManager::Instance()->GetVerbose());
61
62 sternf = new G4double[nlev];
63 levE = new G4double[nlev];
64 sternl = new G4double[nlev];
65 sternEbar = new G4double[nlev];
66 for (G4int i = 0; i < nlev; ++i) {
67 sternf[i] = 0.0;
68 levE[i] = 0.0;
69 sternl[i] = 0.0;
70 sternEbar[i] = 0.0;
71 }
72
73 fConductivity = sternx = 0.0;
74 G4bool conductor = (fMaterial->GetFreeElectronDensity() > 0.0);
75
76 G4int sh = 0;
77 G4double sum = 0.;
78 const G4double tot = fMaterial->GetTotNbOfAtomsPerVolume();
79 for (size_t j = 0; j < fMaterial->GetNumberOfElements(); ++j) {
80 // The last subshell is considered to contain the conduction
81 // electrons. Sternheimer 1984 says "the lowest chemical valance of
82 // the element" is used to set the number of conduction electrons.
83 // I'm not sure if that means the highest subshell or the whole
84 // shell, but in any case, he also says that the choice is arbitrary
85 // and offers a possible alternative. This is one of the sources of
86 // uncertainty in the model.
87 const G4double frac = fMaterial->GetVecNbOfAtomsPerVolume()[j] / tot;
88 const G4int Z = fMaterial->GetElement((G4int)j)->GetZasInt();
90 for (G4int i = 0; i < nshell; ++i) {
91 // For conductors, put *all* top shell electrons into the conduction
92 // band, regardless of element.
93 const G4double xx = frac * G4AtomicShells::GetNumberOfElectrons(Z, i);
94 if (i < nshell - 1 || ! conductor) {
95 sternf[sh] += xx;
96 }
97 else {
98 fConductivity += xx;
99 }
100 levE[sh] = G4AtomicShells::GetBindingEnergy(Z, i) / CLHEP::eV;
101 ++sh;
102 }
103 }
104 for (G4int i = 0; i < nlev; ++i) {
105 sum += sternf[i];
106 }
107 sum += fConductivity;
108
109 const G4double invsum = (sum > 0.0) ? 1. / sum : 0.0;
110 for (G4int i = 0; i < nlev; ++i) {
111 sternf[i] *= invsum;
112 }
113 fConductivity *= invsum;
114 plasmaE = fMaterial->GetIonisation()->GetPlasmaEnergy() / CLHEP::eV;
115 meanexcite = fMaterial->GetIonisation()->GetMeanExcitationEnergy() / CLHEP::eV;
116}
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
static G4int GetNumberOfElectrons(G4int Z, G4int SubshellNb)
static G4double GetBindingEnergy(G4int Z, G4int SubshellNb)
static G4int GetNumberOfShells(G4int Z)
G4int GetZasInt() const
Definition G4Element.hh:120
G4double GetMeanExcitationEnergy() const
G4double GetPlasmaEnergy() const
G4double GetTotNbOfAtomsPerVolume() const
const G4Element * GetElement(G4int iel) const
G4IonisParamMat * GetIonisation() const
G4double GetFreeElectronDensity() const
const G4double * GetVecNbOfAtomsPerVolume() const
std::size_t GetNumberOfElements() const
static G4NistManager * Instance()

◆ ~G4DensityEffectCalculator()

G4DensityEffectCalculator::~G4DensityEffectCalculator ( )

Definition at line 118 of file G4DensityEffectCalculator.cc.

119{
120 delete[] sternf;
121 delete[] levE;
122 delete[] sternl;
123 delete[] sternEbar;
124}

Member Function Documentation

◆ ComputeDensityCorrection()

G4double G4DensityEffectCalculator::ComputeDensityCorrection ( G4double x)

Definition at line 126 of file G4DensityEffectCalculator.cc.

127{
128 if (fVerbose > 1) {
129 G4cout << "G4DensityEffectCalculator::ComputeDensityCorrection for " << fMaterial->GetName()
130 << ", x= " << x << G4endl;
131 }
132 const G4double approx = fMaterial->GetIonisation()->GetDensityCorrection(x);
133 const G4double exact = FermiDeltaCalculation(x);
134
135 if (fVerbose > 1) {
136 G4cout << " Delta: computed= " << exact << ", parametrized= " << approx << G4endl;
137 }
138 if (approx >= 0. && exact < 0.) {
139 if (fVerbose > 0) {
140 ++fWarnings;
141 if (fWarnings < maxWarnings) {
143 ed << "Sternheimer fit failed for " << fMaterial->GetName() << ", x = " << x
144 << ": Delta exact= " << exact << ", approx= " << approx;
145 G4Exception("G4DensityEffectCalculator::DensityCorrection", "mat008", JustWarning, ed);
146 }
147 }
148 return approx;
149 }
150 // Fall back to approx if exact and approx are very different, under the
151 // assumption that this means the exact calculation has gone haywire
152 // somehow, with the exception of the case where approx is negative. I
153 // have seen this clearly-wrong result occur for substances with extremely
154 // low density (1e-25 g/cc).
155 if (approx >= 0. && std::abs(exact - approx) > 1.) {
156 if (fVerbose > 0) {
157 ++fWarnings;
158 if (fWarnings < maxWarnings) {
160 ed << "Sternheimer exact= " << exact << " and approx= " << approx
161 << " are too different for " << fMaterial->GetName() << ", x = " << x;
162 G4Exception("G4DensityEffectCalculator::DensityCorrection", "mat008", JustWarning, ed);
163 }
164 }
165 return approx;
166 }
167 return exact;
168}
const G4int maxWarnings
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4double GetDensityCorrection(G4double x) const
const G4String & GetName() const

Referenced by G4IonisParamMat::DensityCorrection().


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