Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4EmUtility.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// Geant4 class G4EmUtility
28//
29// Author V.Ivanchenko 14.03.2022
30//
31
32#include "G4EmUtility.hh"
33#include "G4RegionStore.hh"
35#include "G4VEmProcess.hh"
36#include "G4EmParameters.hh"
37#include "G4PhysicsVector.hh"
38#include "Randomize.hh"
39#include "G4Log.hh"
40#include "G4Exp.hh"
41
42//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
43
44static const G4double g4log10 = G4Log(10.);
45
46const G4Region*
47G4EmUtility::FindRegion(const G4String& regionName, const G4int verbose)
48{
49 const G4Region* reg = nullptr;
51 G4String r = regionName;
52 if(r == "") { r = "DefaultRegionForTheWorld"; }
53 reg = regStore->GetRegion(r, true);
54 if(nullptr == reg && verbose > 0) {
55 G4cout << "### G4EmUtility WARNING: fails to find a region <"
56 << r << G4endl;
57 } else if(verbose > 1) {
58 G4cout << "### G4EmUtility finds out G4Region <" << r << ">"
59 << G4endl;
60 }
61 return reg;
62}
63
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
65
67{
68 const G4Element* elm = mat->GetElement(0);
69 std::size_t nElements = mat->GetNumberOfElements();
70 if(1 < nElements) {
72 const G4double* y = mat->GetVecNbOfAtomsPerVolume();
73 for(std::size_t i=0; i<nElements; ++i) {
74 elm = mat->GetElement((G4int)i);
75 x -= y[i]*elm->GetZ();
76 if(x <= 0.0) { break; }
77 }
78 }
79 return elm;
80}
81
82//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
83
85{
86 const std::size_t ni = elm->GetNumberOfIsotopes();
87 const G4Isotope* iso = elm->GetIsotope(0);
88 if(ni > 1) {
89 const G4double* ab = elm->GetRelativeAbundanceVector();
91 for(std::size_t idx=0; idx<ni; ++idx) {
92 x -= ab[idx];
93 if (x <= 0.0) {
94 iso = elm->GetIsotope((G4int)idx);
95 break;
96 }
97 }
98 }
99 return iso;
100}
101
102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
103
105{
106 std::vector<G4double>* ptr = nullptr;
107 if(nullptr == p) { return ptr; }
108
109 const std::size_t n = p->length();
110 ptr = new std::vector<G4double>;
111 ptr->resize(n, DBL_MAX);
112
113 G4bool isPeak = false;
114 G4double e, ss, ee, xs;
115
116 // first loop on existing vectors
117 for (std::size_t i=0; i<n; ++i) {
118 const G4PhysicsVector* pv = (*p)[i];
119 xs = ee = 0.0;
120 if(nullptr != pv) {
121 G4int nb = (G4int)pv->GetVectorLength();
122 for (G4int j=0; j<nb; ++j) {
123 e = pv->Energy(j);
124 ss = (*pv)(j);
125 if(ss >= xs) {
126 xs = ss;
127 ee = e;
128 continue;
129 } else {
130 isPeak = true;
131 (*ptr)[i] = ee;
132 break;
133 }
134 }
135 }
136 }
137
138 // there is no peak for any material
139 if(!isPeak) {
140 delete ptr;
141 ptr = nullptr;
142 }
143 return ptr;
144}
145
146//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
147
148std::vector<G4double>*
150 const G4ParticleDefinition* part)
151{
152 std::vector<G4double>* ptr = nullptr;
153 if(nullptr == p || nullptr == part) { return ptr; }
154 /*
155 G4cout << "G4EmUtility::FindCrossSectionMax for "
156 << p->GetProcessName() << " and " << part->GetParticleName() << G4endl;
157 */
158 G4EmParameters* theParameters = G4EmParameters::Instance();
159 G4double tmin = theParameters->MinKinEnergy();
160 G4double tmax = theParameters->MaxKinEnergy();
161
162 const G4ProductionCutsTable* theCoupleTable=
164 std::size_t n = theCoupleTable->GetTableSize();
165 ptr = new std::vector<G4double>;
166 ptr->resize(n, DBL_MAX);
167
168 G4bool isPeak = false;
169 G4double scale = theParameters->NumberOfBinsPerDecade()/g4log10;
170
171 G4double e, sig, ee, x, sm, em, emin, emax;
172
173 // first loop on existing vectors
174 for (std::size_t i=0; i<n; ++i) {
175 auto couple = theCoupleTable->GetMaterialCutsCouple((G4int)i);
176 emin = std::max(p->MinPrimaryEnergy(part, couple->GetMaterial()), tmin);
177 emax = std::max(tmax, 2*emin);
178 ee = G4Log(emax/emin);
179
180 G4int nbin = G4lrint(ee*scale);
181 if(nbin < 4) { nbin = 4; }
182 x = G4Exp(ee/nbin);
183 sm = 0.0;
184 em = 0.0;
185 e = emin;
186 for(G4int j=0; j<=nbin; ++j) {
187 sig = p->GetCrossSection(e, couple);
188 if(sig >= sm) {
189 em = e;
190 sm = sig;
191 e = (j+1 < nbin) ? e*x : emax;
192 } else {
193 isPeak = true;
194 (*ptr)[i] = em;
195 break;
196 }
197 }
198 //G4cout << i << ". em=" << em << " sm=" << sm << G4endl;
199 }
200 // there is no peak for any couple
201 if(!isPeak) {
202 delete ptr;
203 ptr = nullptr;
204 }
205 return ptr;
206}
207
208//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
209
210std::vector<G4TwoPeaksXS*>*
212{
213 std::vector<G4TwoPeaksXS*>* ptr = nullptr;
214 if(nullptr == p) { return ptr; }
215
216 const G4int n = (G4int)p->length();
217 ptr = new std::vector<G4TwoPeaksXS*>;
218 ptr->resize(n, nullptr);
219
220 G4double e, ss, xs, ee;
221 G4double e1peak, e1deep, e2peak, e2deep, e3peak;
222 G4bool isDeep = false;
223
224 // first loop on existing vectors
225 for (G4int i=0; i<n; ++i) {
226 const G4PhysicsVector* pv = (*p)[i];
227 ee = xs = 0.0;
228 e1peak = e1deep = e2peak = e2deep = e3peak = DBL_MAX;
229 if(nullptr != pv) {
230 G4int nb = (G4int)pv->GetVectorLength();
231 for (G4int j=0; j<nb; ++j) {
232 e = pv->Energy(j);
233 ss = (*pv)(j);
234 // find out 1st peak
235 if(e1peak == DBL_MAX) {
236 if(ss >= xs) {
237 xs = ss;
238 ee = e;
239 continue;
240 } else {
241 e1peak = ee;
242 }
243 }
244 // find out the deep
245 if(e1deep == DBL_MAX) {
246 if(ss <= xs) {
247 xs = ss;
248 ee = e;
249 continue;
250 } else {
251 e1deep = ee;
252 isDeep = true;
253 }
254 }
255 // find out 2nd peak
256 if(e2peak == DBL_MAX) {
257 if(ss >= xs) {
258 xs = ss;
259 ee = e;
260 continue;
261 } else {
262 e2peak = ee;
263 }
264 }
265 if(e2deep == DBL_MAX) {
266 if(ss <= xs) {
267 xs = ss;
268 ee = e;
269 continue;
270 } else {
271 e2deep = ee;
272 break;
273 }
274 }
275 // find out 3d peak
276 if(e3peak == DBL_MAX) {
277 if(ss >= xs) {
278 xs = ss;
279 ee = e;
280 continue;
281 } else {
282 e3peak = ee;
283 }
284 }
285 }
286 }
287 G4TwoPeaksXS* x = (*ptr)[i];
288 if(nullptr == x) {
289 x = new G4TwoPeaksXS();
290 (*ptr)[i] = x;
291 }
292 x->e1peak = e1peak;
293 x->e1deep = e1deep;
294 x->e2peak = e2peak;
295 x->e2deep = e2deep;
296 x->e3peak = e3peak;
297 }
298 // case of no 1st peak in all vectors
299 if(!isDeep) {
300 delete ptr;
301 ptr = nullptr;
302 return ptr;
303 }
304 // check base particles
305 if(!bld->GetBaseMaterialFlag()) { return ptr; }
306
307 auto theDensityIdx = bld->GetCoupleIndexes();
308 // second loop using base materials
309 for (G4int i=0; i<n; ++i) {
310 const G4PhysicsVector* pv = (*p)[i];
311 if (nullptr == pv) {
312 G4int j = (*theDensityIdx)[i];
313 if(j == i) { continue; }
314 G4TwoPeaksXS* x = (*ptr)[i];
315 G4TwoPeaksXS* y = (*ptr)[j];
316 if(nullptr == x) {
317 x = new G4TwoPeaksXS();
318 (*ptr)[i] = x;
319 }
320 x->e1peak = y->e1peak;
321 x->e1deep = y->e1deep;
322 x->e2peak = y->e2peak;
323 x->e2deep = y->e2deep;
324 x->e3peak = y->e3peak;
325 }
326 }
327 return ptr;
328}
329
330//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
331
333 const G4ParticleDefinition* part,
334 const G4DataVector& cuts,
335 const G4double elow,
336 const G4double ehigh)
337{
338 // using spline for element selectors should be investigated in details
339 // because small number of points may provide biased results
340 // large number of points requires significant increase of memory
341 G4bool spline = false;
342
344
345 G4ProductionCutsTable* theCoupleTable=
347 std::size_t numOfCouples = theCoupleTable->GetTableSize();
348
349 // prepare vector
350 auto elmSelectors = mod->GetElementSelectors();
351 if(nullptr == elmSelectors) {
352 elmSelectors = new std::vector<G4EmElementSelector*>;
353 }
354 std::size_t nSelectors = elmSelectors->size();
355 if(numOfCouples > nSelectors) {
356 for(std::size_t i=nSelectors; i<numOfCouples; ++i) {
357 elmSelectors->push_back(nullptr);
358 }
359 nSelectors = numOfCouples;
360 }
361
362 // initialise vector
363 for(std::size_t i=0; i<numOfCouples; ++i) {
364
365 // no need in element selectors for infinite cuts
366 if(cuts[i] == DBL_MAX) { continue; }
367
368 auto couple = theCoupleTable->GetMaterialCutsCouple((G4int)i);
369 auto mat = couple->GetMaterial();
370 mod->SetCurrentCouple(couple);
371
372 // selector already exist then delete
373 delete (*elmSelectors)[i];
374
375 G4double emin = std::max(elow, mod->MinPrimaryEnergy(mat, part, cuts[i]));
376 G4double emax = std::max(ehigh, 10*emin);
377 static const G4double invlog106 = 1.0/(6*G4Log(10.));
378 G4int nbins = G4lrint(nbinsPerDec*G4Log(emax/emin)*invlog106);
379 nbins = std::max(nbins, 3);
380
381 (*elmSelectors)[i] = new G4EmElementSelector(mod,mat,nbins,
382 emin,emax,spline);
383 ((*elmSelectors)[i])->Initialise(part, cuts[i]);
384 /*
385 G4cout << "G4VEmModel::InitialiseElmSelectors i= " << i
386 << " " << part->GetParticleName()
387 << " for " << mod->GetName() << " cut= " << cuts[i]
388 << " " << (*elmSelectors)[i] << G4endl;
389 ((*elmSelectors)[i])->Dump(part);
390 */
391 }
392 mod->SetElementSelectors(elmSelectors);
393}
394
395//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
G4double G4Log(G4double x)
Definition: G4Log.hh:227
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
G4double * GetRelativeAbundanceVector() const
Definition: G4Element.hh:167
G4double GetZ() const
Definition: G4Element.hh:131
const G4Isotope * GetIsotope(G4int iso) const
Definition: G4Element.hh:170
size_t GetNumberOfIsotopes() const
Definition: G4Element.hh:159
static G4EmParameters * Instance()
G4double MinKinEnergy() const
G4int NumberOfBinsPerDecade() const
G4double MaxKinEnergy() const
static const G4Element * SampleRandomElement(const G4Material *)
Definition: G4EmUtility.cc:66
static std::vector< G4TwoPeaksXS * > * FillPeaksStructure(G4PhysicsTable *, G4LossTableBuilder *)
Definition: G4EmUtility.cc:211
static const G4Isotope * SampleRandomIsotope(const G4Element *)
Definition: G4EmUtility.cc:84
static void InitialiseElementSelectors(G4VEmModel *, const G4ParticleDefinition *, const G4DataVector &cuts, const G4double emin, const G4double emax)
Definition: G4EmUtility.cc:332
static const G4Region * FindRegion(const G4String &regionName, const G4int verbose=0)
Definition: G4EmUtility.cc:47
static std::vector< G4double > * FindCrossSectionMax(G4PhysicsTable *)
Definition: G4EmUtility.cc:104
const std::vector< G4int > * GetCoupleIndexes() const
const G4Material * GetMaterial() const
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:197
G4double GetTotNbOfElectPerVolume() const
Definition: G4Material.hh:207
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:201
std::size_t length() const
G4double Energy(const std::size_t index) const
std::size_t GetVectorLength() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
virtual G4double GetCrossSection(const G4double, const G4MaterialCutsCouple *)
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition *, const G4Material *)
virtual G4double MinPrimaryEnergy(const G4Material *, const G4ParticleDefinition *, G4double cut=0.0)
Definition: G4VEmModel.cc:358
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
Definition: G4VEmModel.hh:831
std::vector< G4EmElementSelector * > * GetElementSelectors()
Definition: G4VEmModel.hh:823
void SetCurrentCouple(const G4MaterialCutsCouple *)
Definition: G4VEmModel.hh:468
G4double e1peak
G4double e3peak
G4double e2deep
G4double e1deep
G4double e2peak
int G4lrint(double ad)
Definition: templates.hh:134
#define DBL_MAX
Definition: templates.hh:62