Geant4-11
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
G4PenelopeBremsstrahlungFS Class Reference

#include <G4PenelopeBremsstrahlungFS.hh>

Public Member Functions

void BuildScaledXSTable (const G4Material *material, G4double cut, G4bool isMaster)
 
void ClearTables (G4bool isMaster=true)
 Reserved for the master model: they build and handle tables. More...
 
 G4PenelopeBremsstrahlungFS (const G4PenelopeBremsstrahlungFS &)=delete
 
 G4PenelopeBremsstrahlungFS (G4int verbosity=0)
 Only master models are supposed to create instances. More...
 
G4double GetEffectiveZSquared (const G4Material *mat) const
 
G4double GetMomentumIntegral (G4double *y, G4double up, G4int momOrder) const
 
size_t GetNBinsX () const
 
const G4PhysicsTableGetScaledXSTable (const G4Material *, const G4double cut) const
 
G4int GetVerbosity ()
 
G4PenelopeBremsstrahlungFSoperator= (const G4PenelopeBremsstrahlungFS &right)=delete
 
G4double SampleGammaEnergy (G4double energy, const G4Material *, const G4double cut) const
 
void SetVerbosity (G4int ver)
 
 ~G4PenelopeBremsstrahlungFS ()
 

Private Member Functions

void InitializeEnergySampling (const G4Material *, G4double cut)
 
void ReadDataFile (G4int Z)
 

Private Attributes

G4Cache< G4PhysicsFreeVector * > fCache
 
std::map< const G4Material *, G4double > * fEffectiveZSq
 
std::map< G4int, G4DataVector * > * fElementData
 
std::map< std::pair< const G4Material *, G4double >, G4PhysicsFreeVector * > * fPBcut
 
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fReducedXSTable
 
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fSamplingTable
 
G4int fVerbosity
 
G4double theEGrid [fNBinsE]
 
G4double theXGrid [fNBinsX]
 

Static Private Attributes

static const size_t fNBinsE = 57
 
static const size_t fNBinsX = 32
 

Detailed Description

Definition at line 60 of file G4PenelopeBremsstrahlungFS.hh.

Constructor & Destructor Documentation

◆ G4PenelopeBremsstrahlungFS() [1/2]

G4PenelopeBremsstrahlungFS::G4PenelopeBremsstrahlungFS ( G4int  verbosity = 0)
explicit

Only master models are supposed to create instances.

Definition at line 52 of file G4PenelopeBremsstrahlungFS.cc.

52 :
53 fReducedXSTable(nullptr),fEffectiveZSq(nullptr),fSamplingTable(nullptr),
54 fPBcut(nullptr),fVerbosity(verbosity)
55{
56 fCache.Put(0);
57 G4double tempvector[fNBinsX] =
58 {1.0e-12,0.025e0,0.05e0,0.075e0,0.1e0,0.15e0,0.2e0,0.25e0,
59 0.3e0,0.35e0,0.4e0,0.45e0,0.5e0,0.55e0,0.6e0,0.65e0,0.7e0,
60 0.75e0,0.8e0,0.85e0,0.9e0,0.925e0,0.95e0,0.97e0,0.99e0,
61 0.995e0,0.999e0,0.9995e0,0.9999e0,0.99995e0,0.99999e0,1.0e0};
62
63 for (size_t ix=0;ix<fNBinsX;ix++)
64 theXGrid[ix] = tempvector[ix];
65
66 for (size_t i=0;i<fNBinsE;i++)
67 theEGrid[i] = 0.;
68
69 fElementData = new std::map<G4int,G4DataVector*>;
70}
double G4double
Definition: G4Types.hh:83
void Put(const value_type &val) const
Definition: G4Cache.hh:321
std::map< const G4Material *, G4double > * fEffectiveZSq
std::map< G4int, G4DataVector * > * fElementData
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fSamplingTable
std::map< std::pair< const G4Material *, G4double >, G4PhysicsFreeVector * > * fPBcut
std::map< std::pair< const G4Material *, G4double >, G4PhysicsTable * > * fReducedXSTable
G4Cache< G4PhysicsFreeVector * > fCache

References fCache, fElementData, fNBinsE, fNBinsX, G4Cache< VALTYPE >::Put(), theEGrid, and theXGrid.

◆ ~G4PenelopeBremsstrahlungFS()

G4PenelopeBremsstrahlungFS::~G4PenelopeBremsstrahlungFS ( )

Definition at line 74 of file G4PenelopeBremsstrahlungFS.cc.

75{
77
78 //The G4Physics*Vector pointers contained in the fCache are automatically deleted by
79 //the G4AutoDelete so there is no need to take care of them manually
80
81 //Clear manually fElementData
82 if (fElementData)
83 {
84 for (auto& item : (*fElementData))
85 delete item.second;
86 delete fElementData;
87 fElementData = nullptr;
88 }
89}
void ClearTables(G4bool isMaster=true)
Reserved for the master model: they build and handle tables.

References ClearTables(), and fElementData.

◆ G4PenelopeBremsstrahlungFS() [2/2]

G4PenelopeBremsstrahlungFS::G4PenelopeBremsstrahlungFS ( const G4PenelopeBremsstrahlungFS )
delete

Member Function Documentation

◆ BuildScaledXSTable()

void G4PenelopeBremsstrahlungFS::BuildScaledXSTable ( const G4Material material,
G4double  cut,
G4bool  isMaster 
)

Definition at line 175 of file G4PenelopeBremsstrahlungFS.cc.

177{
178 //Corresponds to subroutines EBRaW and EBRaR of PENELOPE
179 /*
180 This method generates the table of the scaled energy-loss cross section from
181 bremsstrahlung emission for the given material. Original data are read from
182 file. The table is normalized according to the Berger-Seltzer cross section.
183 */
184
185 //Just to check
186 if (!isMaster)
187 G4Exception("G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
188 "em0100",FatalException,"Worker thread in this method");
189
190 if (fVerbosity > 2)
191 {
192 G4cout << "Entering in G4PenelopeBremsstrahlungFS::BuildScaledXSTable for " <<
193 material->GetName() << G4endl;
194 G4cout << "Threshold = " << cut/keV << " keV, isMaster= " << isMaster <<
195 G4endl;
196 }
197
198 //This method should be accessed by the master only
199 if (!fSamplingTable)
201 new std::map< std::pair<const G4Material*,G4double> , G4PhysicsTable*>;
202 if (!fPBcut)
203 fPBcut =
204 new std::map< std::pair<const G4Material*,G4double> , G4PhysicsFreeVector* >;
205
206 //check if the container exists (if not, create it)
207 if (!fReducedXSTable)
208 fReducedXSTable = new std::map< std::pair<const G4Material*,G4double> ,
210 if (!fEffectiveZSq)
211 fEffectiveZSq = new std::map<const G4Material*,G4double>;
212
213 //*********************************************************************
214 //Determine the equivalent atomic number <Z^2>
215 //*********************************************************************
216 std::vector<G4double> *StechiometricFactors = new std::vector<G4double>;
217 G4int nElements = material->GetNumberOfElements();
218 const G4ElementVector* elementVector = material->GetElementVector();
219 const G4double* fractionVector = material->GetFractionVector();
220 for (G4int i=0;i<nElements;i++)
221 {
222 G4double fraction = fractionVector[i];
223 G4double atomicWeigth = (*elementVector)[i]->GetA()/(g/mole);
224 StechiometricFactors->push_back(fraction/atomicWeigth);
225 }
226 //Find max
227 G4double MaxStechiometricFactor = 0.;
228 for (G4int i=0;i<nElements;i++)
229 {
230 if ((*StechiometricFactors)[i] > MaxStechiometricFactor)
231 MaxStechiometricFactor = (*StechiometricFactors)[i];
232 }
233 //Normalize
234 for (G4int i=0;i<nElements;i++)
235 (*StechiometricFactors)[i] /= MaxStechiometricFactor;
236
237 G4double sumz2 = 0;
238 G4double sums = 0;
239 for (G4int i=0;i<nElements;i++)
240 {
241 G4double Z = (*elementVector)[i]->GetZ();
242 sumz2 += (*StechiometricFactors)[i]*Z*Z;
243 sums += (*StechiometricFactors)[i];
244 }
245 G4double ZBR2 = sumz2/sums;
246
247 fEffectiveZSq->insert(std::make_pair(material,ZBR2));
248
249 //*********************************************************************
250 // loop on elements and read data files
251 //*********************************************************************
252 G4DataVector* tempData = new G4DataVector(fNBinsE);
253 G4DataVector* tempMatrix = new G4DataVector(fNBinsE*fNBinsX,0.);
254
255 for (G4int iel=0;iel<nElements;iel++)
256 {
257 G4double Z = (*elementVector)[iel]->GetZ();
258 G4int iZ = (G4int) Z;
259 G4double wgt = (*StechiometricFactors)[iel]*Z*Z/ZBR2;
260
261 //the element is not already loaded
262 if (!fElementData->count(iZ))
263 {
264 ReadDataFile(iZ);
265 if (!fElementData->count(iZ))
266 {
268 ed << "Error in G4PenelopeBremsstrahlungFS::BuildScaledXSTable" << G4endl;
269 ed << "Unable to retrieve data for element " << iZ << G4endl;
270 G4Exception("G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
271 "em2009",FatalException,ed);
272 }
273 }
274
275 G4DataVector* atomData = fElementData->find(iZ)->second;
276
277 for (size_t ie=0;ie<fNBinsE;ie++)
278 {
279 (*tempData)[ie] += wgt*(*atomData)[ie*(fNBinsX+1)+fNBinsX]; //last column contains total XS
280 for (size_t ix=0;ix<fNBinsX;ix++)
281 (*tempMatrix)[ie*fNBinsX+ix] += wgt*(*atomData)[ie*(fNBinsX+1)+ix];
282 }
283 }
284
285 //*********************************************************************
286 // the total energy loss spectrum is re-normalized to reproduce the total
287 // scaled cross section of Berger and Seltzer
288 //*********************************************************************
289 for (size_t ie=0;ie<fNBinsE;ie++)
290 {
291 //for each energy, calculate integral of dSigma/dx over dx
292 G4double* tempData2 = new G4double[fNBinsX];
293 for (size_t ix=0;ix<fNBinsX;ix++)
294 tempData2[ix] = (*tempMatrix)[ie*fNBinsX+ix];
295 G4double rsum = GetMomentumIntegral(tempData2,1.0,0);
296 delete[] tempData2;
299 G4double fnorm = (*tempData)[ie]/(rsum*fact);
300 G4double TST = 100.*std::fabs(fnorm-1.0);
301 if (TST > 1.0)
302 {
304 ed << "G4PenelopeBremsstrahlungFS. Corrupted data files?" << G4endl;
305 G4cout << "TST= " << TST << "; fnorm = " << fnorm << G4endl;
306 G4cout << "rsum = " << rsum << G4endl;
307 G4cout << "fact = " << fact << G4endl;
308 G4cout << ie << " " << theEGrid[ie]/keV << " " << (*tempData)[ie]/barn << G4endl;
309 G4Exception("G4PenelopeBremsstrahlungFS::BuildScaledXSTable()",
310 "em2010",FatalException,ed);
311 }
312 for (size_t ix=0;ix<fNBinsX;ix++)
313 (*tempMatrix)[ie*fNBinsX+ix] *= fnorm;
314 }
315
316 //*********************************************************************
317 // create and fill the tables
318 //*********************************************************************
319 G4PhysicsTable* thePhysicsTable = new G4PhysicsTable();
320 // the table will contain 32 G4PhysicsFreeVectors with different
321 // values of x. Each of the G4PhysicsFreeVectors has a profile of
322 // log(XS) vs. log(E)
323
324 //reserve space of the vectors. Everything is log-log
325 //I add one extra "fake" point at low energy, since the Penelope
326 //table starts at 1 keV
327 for (size_t i=0;i<fNBinsX;i++)
328 thePhysicsTable->push_back(new G4PhysicsFreeVector(fNBinsE+1));
329
330 for (size_t ix=0;ix<fNBinsX;ix++)
331 {
332 G4PhysicsFreeVector* theVec =
333 (G4PhysicsFreeVector*) ((*thePhysicsTable)[ix]);
334 for (size_t ie=0;ie<fNBinsE;ie++)
335 {
336 G4double logene = G4Log(theEGrid[ie]);
337 G4double aValue = (*tempMatrix)[ie*fNBinsX+ix];
338 if (aValue < 1e-20*millibarn) //protection against log(0)
339 aValue = 1e-20*millibarn;
340 theVec->PutValues(ie+1,logene,G4Log(aValue));
341 }
342 //Add fake point at 1 eV using an extrapolation with the derivative
343 //at the first valid point (Penelope approach)
344 G4double derivative = ((*theVec)[2]-(*theVec)[1])/(theVec->Energy(2) - theVec->Energy(1));
345 G4double log1eV = G4Log(1*eV);
346 G4double val1eV = (*theVec)[1]+derivative*(log1eV-theVec->Energy(1));
347 //fake point at very low energy
348 theVec->PutValues(0,log1eV,val1eV);
349 }
350 std::pair<const G4Material*,G4double> theKey = std::make_pair(material,cut);
351 fReducedXSTable->insert(std::make_pair(theKey,thePhysicsTable));
352
353 delete StechiometricFactors;
354 delete tempData;
355 delete tempMatrix;
356
357 //Do here also the initialization of the energy sampling
358 if (!(fSamplingTable->count(theKey)))
360
361 return;
362}
std::vector< const G4Element * > G4ElementVector
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4double G4Log(G4double x)
Definition: G4Log.hh:226
static constexpr double mole
Definition: G4SIunits.hh:279
static constexpr double barn
Definition: G4SIunits.hh:85
static constexpr double millibarn
Definition: G4SIunits.hh:86
static constexpr double keV
Definition: G4SIunits.hh:202
static constexpr double eV
Definition: G4SIunits.hh:201
static constexpr double g
Definition: G4SIunits.hh:168
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void InitializeEnergySampling(const G4Material *, G4double cut)
G4double GetMomentumIntegral(G4double *y, G4double up, G4int momOrder) const
void PutValues(const std::size_t index, const G4double energy, const G4double value)
void push_back(G4PhysicsVector *)
G4double Energy(const std::size_t index) const
string material
Definition: eplot.py:19
float electron_mass_c2
Definition: hepunit.py:273
int classic_electr_radius
Definition: hepunit.py:287
int fine_structure_const
Definition: hepunit.py:286

References barn, source.hepunit::classic_electr_radius, source.hepunit::electron_mass_c2, G4PhysicsVector::Energy(), eV, FatalException, fEffectiveZSq, fElementData, source.hepunit::fine_structure_const, fNBinsE, fNBinsX, fPBcut, fReducedXSTable, fSamplingTable, fVerbosity, g, G4cout, G4endl, G4Exception(), G4Log(), GetMomentumIntegral(), InitializeEnergySampling(), keV, eplot::material, millibarn, mole, G4PhysicsTable::push_back(), G4PhysicsFreeVector::PutValues(), ReadDataFile(), theEGrid, and Z.

Referenced by G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple(), and G4PenelopeBremsstrahlungModel::Initialise().

◆ ClearTables()

void G4PenelopeBremsstrahlungFS::ClearTables ( G4bool  isMaster = true)

Reserved for the master model: they build and handle tables.

Definition at line 94 of file G4PenelopeBremsstrahlungFS.cc.

95{
96 //Just to check
97 if (!isMaster)
98 G4Exception("G4PenelopeBremsstrahlungFS::ClearTables()",
99 "em0100",FatalException,"Worker thread in this method");
100
101 if (fReducedXSTable)
102 {
103 for (auto& item : (*fReducedXSTable))
104 {
105 G4PhysicsTable* tab = item.second;
106 tab->clearAndDestroy();
107 delete tab;
108 }
109 fReducedXSTable->clear();
110 delete fReducedXSTable;
111 fReducedXSTable = nullptr;
112 }
113
114 if (fSamplingTable)
115 {
116 for (auto& item : (*fSamplingTable))
117 {
118 G4PhysicsTable* tab = item.second;
119 tab->clearAndDestroy();
120 delete tab;
121 }
122 fSamplingTable->clear();
123 delete fSamplingTable;
124 fSamplingTable = nullptr;
125 }
126 if (fPBcut)
127 {
128 /*
129 std::map< std::pair<const G4Material*,G4double> ,G4PhysicsFreeVector*>::iterator kk;
130 for (kk=fPBcut->begin(); kk != fPBcut->end(); kk++)
131 delete kk->second;
132 */
133 delete fPBcut;
134 fPBcut = nullptr;
135 }
136
137 if (fEffectiveZSq)
138 {
139 delete fEffectiveZSq;
140 fEffectiveZSq = nullptr;
141 }
142
143 return;
144}
void clearAndDestroy()

References G4PhysicsTable::clearAndDestroy(), FatalException, fEffectiveZSq, fPBcut, fReducedXSTable, fSamplingTable, and G4Exception().

Referenced by G4PenelopeBremsstrahlungModel::ClearTables(), and ~G4PenelopeBremsstrahlungFS().

◆ GetEffectiveZSquared()

G4double G4PenelopeBremsstrahlungFS::GetEffectiveZSquared ( const G4Material mat) const

Master and workers (do not touch tables) All of them are const

Definition at line 148 of file G4PenelopeBremsstrahlungFS.cc.

149{
150 if (!fEffectiveZSq)
151 {
153 ed << "The container for the <Z^2> values is not initialized" << G4endl;
154 G4Exception("G4PenelopeBremsstrahlungFS::GetEffectiveZSquared()",
155 "em2007",FatalException,ed);
156 return 0;
157 }
158 //found in the table: return it
159 if (fEffectiveZSq->count(material))
160 return fEffectiveZSq->find(material)->second;
161 else
162 {
164 ed << "The value of <Z^2> is not properly set for material " <<
165 material->GetName() << G4endl;
166 //requires running of BuildScaledXSTable()
167 G4Exception("G4PenelopeBremsstrahlungFS::GetEffectiveZSquared()",
168 "em2008",FatalException,ed);
169 }
170 return 0;
171}

References FatalException, fEffectiveZSq, G4endl, G4Exception(), and eplot::material.

Referenced by G4PenelopeBremsstrahlungModel::BuildXSTable(), and G4PenelopeBremsstrahlungModel::GetPositronXSCorrection().

◆ GetMomentumIntegral()

G4double G4PenelopeBremsstrahlungFS::GetMomentumIntegral ( G4double y,
G4double  up,
G4int  momOrder 
) const

Definition at line 435 of file G4PenelopeBremsstrahlungFS.cc.

438{
439 //Corresponds to the function RLMOM of Penelope
440 //This method performs the calculation of the integral of (x^momOrder)*y over the interval
441 //from x[0] to xup, obtained by linear interpolation on a table of y.
442 //The independent variable is assumed to take positive values only.
443 //
444 size_t size = fNBinsX;
445 const G4double eps = 1e-35;
446
447 //Check that the call is valid
448 if (momOrder<-1 || size<2 || theXGrid[0]<0)
449 {
450 G4Exception("G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
451 "em2011",FatalException,"Invalid call");
452 }
453
454 for (size_t i=1;i<size;i++)
455 {
456 if (theXGrid[i]<0 || theXGrid[i]<theXGrid[i-1])
457 {
459 ed << "Invalid call for bin " << i << G4endl;
460 G4Exception("G4PenelopeBremsstrahlungFS::GetMomentumIntegral()",
461 "em2012",FatalException,ed);
462 }
463 }
464
465 //Compute the integral
466 G4double result = 0;
467 if (xup < theXGrid[0])
468 return result;
469 G4bool loopAgain = true;
470 G4double xt = std::min(xup,theXGrid[size-1]);
471 G4double xtc = 0;
472 for (size_t i=0;i<size-1;i++)
473 {
474 G4double x1 = std::max(theXGrid[i],eps);
475 G4double y1 = y[i];
476 G4double x2 = std::max(theXGrid[i+1],eps);
477 G4double y2 = y[i+1];
478 if (xt < x2)
479 {
480 xtc = xt;
481 loopAgain = false;
482 }
483 else
484 xtc = x2;
485 G4double dx = x2-x1;
486 G4double dy = y2-y1;
487 G4double ds = 0;
488 if (std::fabs(dx)>1e-14*std::fabs(dy))
489 {
490 G4double b=dy/dx;
491 G4double a=y1-b*x1;
492 if (momOrder == -1)
493 ds = a*G4Log(xtc/x1)+b*(xtc-x1);
494 else if (momOrder == 0) //speed it up, not using pow()
495 ds = a*(xtc-x1) + 0.5*b*(xtc*xtc-x1*x1);
496 else
497 ds = a*(std::pow(xtc,momOrder+1)-std::pow(x1,momOrder+1))/((G4double) (momOrder + 1))
498 + b*(std::pow(xtc,momOrder+2)-std::pow(x1,momOrder+2))/((G4double) (momOrder + 2));
499 }
500 else
501 ds = 0.5*(y1+y2)*(xtc-x1)*std::pow(xtc,momOrder);
502 result += ds;
503 if (!loopAgain)
504 return result;
505 }
506 return result;
507}
static const G4double eps
bool G4bool
Definition: G4Types.hh:86
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments

References anonymous_namespace{G4QuasiElRatios.cc}::ds, eps, FatalException, G4endl, G4Exception(), G4Log(), G4INCL::Math::max(), and G4INCL::Math::min().

Referenced by BuildScaledXSTable(), G4PenelopeBremsstrahlungModel::BuildXSTable(), and InitializeEnergySampling().

◆ GetNBinsX()

size_t G4PenelopeBremsstrahlungFS::GetNBinsX ( ) const
inline

Definition at line 72 of file G4PenelopeBremsstrahlungFS.hh.

72{return fNBinsX;};

References fNBinsX.

Referenced by G4PenelopeBremsstrahlungModel::BuildXSTable().

◆ GetScaledXSTable()

const G4PhysicsTable * G4PenelopeBremsstrahlungFS::GetScaledXSTable ( const G4Material mat,
const G4double  cut 
) const

Definition at line 511 of file G4PenelopeBremsstrahlungFS.cc.

513{
514 //check if it already contains the entry
515 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
516
517 if (!(fReducedXSTable->count(theKey)))
518 {
519 G4Exception("G4PenelopeBremsstrahlungFS::GetScaledXSTable()",
520 "em2013",FatalException,"Unable to retrieve the cross section table");
521 }
522
523 return fReducedXSTable->find(theKey)->second;
524}

References FatalException, fReducedXSTable, and G4Exception().

Referenced by G4PenelopeBremsstrahlungModel::BuildXSTable().

◆ GetVerbosity()

G4int G4PenelopeBremsstrahlungFS::GetVerbosity ( )
inline

Definition at line 86 of file G4PenelopeBremsstrahlungFS.hh.

86{return fVerbosity;};

References fVerbosity.

◆ InitializeEnergySampling()

void G4PenelopeBremsstrahlungFS::InitializeEnergySampling ( const G4Material material,
G4double  cut 
)
private

Definition at line 528 of file G4PenelopeBremsstrahlungFS.cc.

530{
531 if (fVerbosity > 2)
532 G4cout << "Entering in G4PenelopeBremsstrahlungFS::InitializeEnergySampling() for " <<
533 material->GetName() << G4endl;
534
535 //This method should be accessed by the master only
536 std::pair<const G4Material*,G4double> theKey = std::make_pair(material,cut);
537
538 G4PhysicsTable* thePhysicsTable = new G4PhysicsTable();
539 // the table will contain 57 G4PhysicsFreeVectors with different
540 // values of E.
542
543 //I reserve space of the vectors.
544 for (size_t i=0;i<fNBinsE;i++)
545 thePhysicsTable->push_back(new G4PhysicsFreeVector(fNBinsX));
546
547 //Retrieve the table. Must already exist at this point, because this
548 //method is invoked by GetScaledXSTable()
549 if (!(fReducedXSTable->count(theKey)))
550 G4Exception("G4PenelopeBremsstrahlungFS::InitializeEnergySampling()",
551 "em2013",FatalException,"Unable to retrieve the cross section table");
552 G4PhysicsTable* theTableReduced = fReducedXSTable->find(theKey)->second;
553
554 for (size_t ie=0;ie<fNBinsE;ie++)
555 {
556 G4PhysicsFreeVector* theVec =
557 (G4PhysicsFreeVector*) ((*thePhysicsTable)[ie]);
558 //Fill the table
559 G4double value = 0; //first value
560 theVec->PutValues(0,theXGrid[0],value);
561 for (size_t ix=1;ix<fNBinsX;ix++)
562 {
563 //Here calculate the cumulative distribution
564 // int_{0}^{x} dSigma(x',E)/dx' (1/x') dx'
565 G4PhysicsFreeVector* v1 = (G4PhysicsFreeVector*) (*theTableReduced)[ix-1];
566 G4PhysicsFreeVector* v2 = (G4PhysicsFreeVector*) (*theTableReduced)[ix];
567
568 G4double x1=std::max(theXGrid[ix-1],1.0e-35);
569 //Remember: the table fReducedXSTable has a fake first point in energy
570 //so, it contains one more bin than fNBinsE.
571 G4double y1=G4Exp((*v1)[ie+1]);
572 G4double x2=std::max(theXGrid[ix],1.0e-35);
573 G4double y2=G4Exp((*v2)[ie+1]);
574 G4double B = (y2-y1)/(x2-x1);
575 G4double A = y1-B*x1;
576 G4double dS = A*G4Log(x2/x1)+B*(x2-x1);
577 value += dS;
578 theVec->PutValues(ix,theXGrid[ix],value);
579 }
580 //fill the PB vector
581 G4double xc = cut/theEGrid[ie];
582 //Fill a temp data vector
583 G4double* tempData = new G4double[fNBinsX];
584 for (size_t ix=0;ix<fNBinsX;ix++)
585 {
586 G4PhysicsFreeVector* vv = (G4PhysicsFreeVector*) (*theTableReduced)[ix];
587 tempData[ix] = G4Exp((*vv)[ie+1]);
588 }
589 G4double pbval = (xc<=1) ?
590 GetMomentumIntegral(tempData,xc,-1) :
591 GetMomentumIntegral(tempData,1.0,-1);
592 thePBvec->PutValues(ie,theEGrid[ie],pbval);
593 delete[] tempData;
594 }
595
596 fSamplingTable->insert(std::make_pair(theKey,thePhysicsTable));
597 fPBcut->insert(std::make_pair(theKey,thePBvec));
598 return;
599}
G4double B(G4double temperature)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
const G4double A[17]

References A, B(), FatalException, fNBinsE, fNBinsX, fPBcut, fReducedXSTable, fSamplingTable, fVerbosity, G4cout, G4endl, G4Exception(), G4Exp(), G4Log(), GetMomentumIntegral(), eplot::material, G4INCL::Math::max(), G4PhysicsTable::push_back(), G4PhysicsFreeVector::PutValues(), theEGrid, and theXGrid.

Referenced by BuildScaledXSTable().

◆ operator=()

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

◆ ReadDataFile()

void G4PenelopeBremsstrahlungFS::ReadDataFile ( G4int  Z)
private

Definition at line 366 of file G4PenelopeBremsstrahlungFS.cc.

367{
368 char* path = std::getenv("G4LEDATA");
369 if (!path)
370 {
371 G4String excep = "G4PenelopeBremsstrahlungFS - G4LEDATA environment variable not set!";
372 G4Exception("G4PenelopeBremsstrahlungFS::ReadDataFile()",
373 "em0006",FatalException,excep);
374 return;
375 }
376 /*
377 Read the cross section file
378 */
379 std::ostringstream ost;
380 if (Z>9)
381 ost << path << "/penelope/bremsstrahlung/pdebr" << Z << ".p08";
382 else
383 ost << path << "/penelope/bremsstrahlung/pdebr0" << Z << ".p08";
384 std::ifstream file(ost.str().c_str());
385 if (!file.is_open())
386 {
387 G4String excep = "G4PenelopeBremsstrahlungFS - data file " +
388 G4String(ost.str()) + " not found!";
389 G4Exception("G4PenelopeBremsstrahlungFS::ReadDataFile()",
390 "em0003",FatalException,excep);
391 return;
392 }
393
394 G4int readZ =0;
395 file >> readZ;
396
397 //check the right file is opened.
398 if (readZ != Z)
399 {
401 ed << "Corrupted data file for Z=" << Z << G4endl;
402 G4Exception("G4PenelopeBremsstrahlungFS::ReadDataFile()",
403 "em0005",FatalException,ed);
404 return;
405 }
406
407 G4DataVector* theMatrix = new G4DataVector(fNBinsE*(fNBinsX+1),0.); //initialized with zeros
408
409 for (size_t ie=0;ie<fNBinsE;ie++)
410 {
411 G4double myDouble = 0;
412 file >> myDouble; //energy (eV)
413 if (!theEGrid[ie]) //fill only the first time
414 theEGrid[ie] = myDouble*eV;
415 //
416 for (size_t ix=0;ix<fNBinsX;ix++)
417 {
418 file >> myDouble;
419 (*theMatrix)[ie*(fNBinsX+1)+ix] = myDouble*millibarn;
420 }
421 file >> myDouble; //total cross section
422 (*theMatrix)[ie*(fNBinsX+1)+fNBinsX] = myDouble*millibarn;
423 }
424
425 if (fElementData)
426 fElementData->insert(std::make_pair(Z,theMatrix));
427 else
428 delete theMatrix;
429 file.close();
430 return;
431}

References eV, FatalException, fElementData, geant4_check_module_cycles::file, fNBinsE, fNBinsX, G4endl, G4Exception(), millibarn, theEGrid, and Z.

Referenced by BuildScaledXSTable().

◆ SampleGammaEnergy()

G4double G4PenelopeBremsstrahlungFS::SampleGammaEnergy ( G4double  energy,
const G4Material mat,
const G4double  cut 
) const

Definition at line 603 of file G4PenelopeBremsstrahlungFS.cc.

605{
606 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
607 if (!(fSamplingTable->count(theKey)) || !(fPBcut->count(theKey)))
608 {
610 ed << "Unable to retrieve the SamplingTable: " <<
611 fSamplingTable->count(theKey) << " " <<
612 fPBcut->count(theKey) << G4endl;
613 G4Exception("G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
614 "em2014",FatalException,ed);
615 }
616 const G4PhysicsTable* theTableInte = fSamplingTable->find(theKey)->second;
617 const G4PhysicsTable* theTableRed = fReducedXSTable->find(theKey)->second;
618
619 //Find the energy bin using bi-partition
620 size_t eBin = 0;
621 G4bool firstOrLastBin = false;
622
623 if (energy < theEGrid[0]) //below first bin
624 {
625 eBin = 0;
626 firstOrLastBin = true;
627 }
628 else if (energy > theEGrid[fNBinsE-1]) //after last bin
629 {
630 eBin = fNBinsE-1;
631 firstOrLastBin = true;
632 }
633 else
634 {
635 size_t i=0;
636 size_t j=fNBinsE-1;
637 while ((j-i)>1)
638 {
639 size_t k = (i+j)/2;
640 if (energy > theEGrid[k])
641 i = k;
642 else
643 j = k;
644 }
645 eBin = i;
646 }
647
648 //Get the appropriate physics vector
649 const G4PhysicsFreeVector* theVec1 = (G4PhysicsFreeVector*) (*theTableInte)[eBin];
650
651 //Use a "temporary" vector which contains the linear interpolation of the x spectra
652 //in energy. The temporary vector is thread-local, so that there is no conflict.
653 //This is achieved via G4Cache. The theTempVect is allocated only once per thread
654 //(member variable), but it is overwritten at every call of this method
655 //(because the interpolation factors change!)
656 G4PhysicsFreeVector* theTempVec = fCache.Get();
657 if (!theTempVec) //First time this thread gets the cache
658 {
659 theTempVec = new G4PhysicsFreeVector(fNBinsX);
660 fCache.Put(theTempVec);
661 // The G4AutoDelete takes care here to clean up the vectors
662 G4AutoDelete::Register(theTempVec);
663 if (fVerbosity > 4)
664 G4cout << "Creating new instance of G4PhysicsFreeVector() on the worker" << G4endl;
665 }
666
667 //theTempVect is allocated only once (member variable), but it is overwritten at
668 //every call of this method (because the interpolation factors change!)
669 if (!firstOrLastBin)
670 {
671 const G4PhysicsFreeVector* theVec2 = (G4PhysicsFreeVector*) (*theTableInte)[eBin+1];
672 for (size_t iloop=0;iloop<fNBinsX;iloop++)
673 {
674 G4double val = (*theVec1)[iloop]+(((*theVec2)[iloop]-(*theVec1)[iloop]))*
675 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
676 theTempVec->PutValues(iloop,theXGrid[iloop],val);
677 }
678 }
679 else //first or last bin, no interpolation
680 {
681 for (size_t iloop=0;iloop<fNBinsX;iloop++)
682 theTempVec->PutValues(iloop,theXGrid[iloop],(*theVec1)[iloop]);
683 }
684
685 //Start the game
686 G4double pbcut = (*(fPBcut->find(theKey)->second))[eBin];
687
688 if (!firstOrLastBin) //linear interpolation on pbcut as well
689 {
690 pbcut = (*(fPBcut->find(theKey)->second))[eBin] +
691 ((*(fPBcut->find(theKey)->second))[eBin+1]-(*(fPBcut->find(theKey)->second))[eBin])*
692 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
693 }
694
695 G4double pCumulative = (*theTempVec)[fNBinsX-1]; //last value
696
697 G4double eGamma = 0;
698 G4int nIterations = 0;
699 do
700 {
701 G4double pt = pbcut + G4UniformRand()*(pCumulative - pbcut);
702 nIterations++;
703
704 //find where it is
705 size_t ibin = 0;
706 if (pt < (*theTempVec)[0])
707 ibin = 0;
708 else if (pt > (*theTempVec)[fNBinsX-1])
709 {
710 //We observed problems due to numerical rounding here (STT).
711 //delta here is a tiny positive number
712 G4double delta = pt-(*theTempVec)[fNBinsX-1];
713 if (delta < pt*1e-10) // very small! Numerical rounding only
714 {
715 ibin = fNBinsX-2;
717 ed << "Found that (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
718 " , (*theTempVec)[fNBinsX-1] = " << (*theTempVec)[fNBinsX-1] << " and delta = " <<
719 (pt-(*theTempVec)[fNBinsX-1]) << G4endl;
720 ed << "Possible symptom of problem with numerical precision" << G4endl;
721 G4Exception("G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
722 "em2015",JustWarning,ed);
723 }
724 else //real problem
725 {
727 ed << "Crash at (pt > (*theTempVec)[fNBinsX-1]) with pt = " << pt <<
728 " , (*theTempVec)[fNBinsX-1]=" << (*theTempVec)[fNBinsX-1] << " and fNBinsX = " <<
729 fNBinsX << G4endl;
730 ed << "Material: " << mat->GetName() << ", energy = " << energy/keV << " keV" <<
731 G4endl;
732 G4Exception("G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
733 "em2015",FatalException,ed);
734 }
735 }
736 else
737 {
738 size_t i=0;
739 size_t j=fNBinsX-1;
740 while ((j-i)>1)
741 {
742 size_t k = (i+j)/2;
743 if (pt > (*theTempVec)[k])
744 i = k;
745 else
746 j = k;
747 }
748 ibin = i;
749 }
750
751 G4double w1 = theXGrid[ibin];
752 G4double w2 = theXGrid[ibin+1];
753
754 const G4PhysicsFreeVector* v1 = (G4PhysicsFreeVector*) (*theTableRed)[ibin];
755 const G4PhysicsFreeVector* v2 = (G4PhysicsFreeVector*) (*theTableRed)[ibin+1];
756 //Remember: the table fReducedXSTable has a fake first point in energy
757 //so, it contains one more bin than fNBinsE.
758 G4double pdf1 = G4Exp((*v1)[eBin+1]);
759 G4double pdf2 = G4Exp((*v2)[eBin+1]);
760 G4double deltaW = w2-w1;
761 G4double dpdfb = pdf2-pdf1;
762 G4double B = dpdfb/deltaW;
763 G4double A = pdf1-B*w1;
764 //I already made an interpolation in energy, so I can use the actual value for the
765 //calculation of the wbcut, instead of the grid values (except for the last bin)
766 G4double wbcut = (cut < energy) ? cut/energy : 1.0;
767 if (firstOrLastBin) //this is an particular case: no interpolation available
768 wbcut = (cut < theEGrid[eBin]) ? cut/theEGrid[eBin] : 1.0;
769
770 if (w1 < wbcut)
771 w1 = wbcut;
772 if (w2 < w1)
773 {
774 //This configuration can happen if initially wbcut > w2 > w1. Due to the previous
775 //statement, (w1 = wbcut), it becomes wbcut = w1 > w2. In this case, it is not a
776 //real problem. It becomes a problem if w2 < w1 before the w1 = wbcut statement. Issue
777 //a warning only in this specific case.
778 if (w2 > wbcut)
779 {
781 ed << "Warning in G4PenelopeBremsstrahlungFS::SampleX()" << G4endl;
782 ed << "Conflicting end-point values: w1=" << w1 << "; w2 = " << w2 << G4endl;
783 ed << "wbcut = " << wbcut << " energy= " << energy/keV << " keV" << G4endl;
784 ed << "cut = " << cut/keV << " keV" << G4endl;
785 G4Exception("G4PenelopeBremsstrahlungFS::SampleGammaEnergy()","em2015",
786 JustWarning,ed);
787 }
788 return w1*energy;
789 }
790
791 G4double pmax = std::max(A+B*w1,A+B*w2);
792 G4bool loopAgain = false;
793 do
794 {
795 loopAgain = false;
796 eGamma = w1* std::pow((w2/w1),G4UniformRand());
797 if (G4UniformRand()*pmax > (A+B*eGamma))
798 loopAgain = true;
799 }while(loopAgain);
800 eGamma *= energy;
801 if (nIterations > 100) //protection against infinite loops
802 return eGamma;
803 }while(eGamma < cut); //repeat if sampled sub-cut!
804
805 return eGamma;
806}
@ JustWarning
#define G4UniformRand()
Definition: Randomize.hh:52
value_type & Get() const
Definition: G4Cache.hh:315
const G4String & GetName() const
Definition: G4Material.hh:173
void Register(T *inst)
Definition: G4AutoDelete.hh:65
G4double energy(const ThreeVector &p, const G4double m)

References A, B(), G4INCL::KinematicsUtils::energy(), FatalException, fCache, fNBinsE, fNBinsX, fPBcut, fReducedXSTable, fSamplingTable, fVerbosity, G4cout, G4endl, G4Exception(), G4Exp(), G4UniformRand, G4Cache< VALTYPE >::Get(), G4Material::GetName(), JustWarning, keV, G4INCL::Math::max(), G4Cache< VALTYPE >::Put(), G4PhysicsFreeVector::PutValues(), G4AutoDelete::Register(), theEGrid, and theXGrid.

Referenced by G4PenelopeBremsstrahlungModel::SampleSecondaries().

◆ SetVerbosity()

void G4PenelopeBremsstrahlungFS::SetVerbosity ( G4int  ver)
inline

Definition at line 85 of file G4PenelopeBremsstrahlungFS.hh.

85{fVerbosity=ver;};

References fVerbosity.

Field Documentation

◆ fCache

G4Cache<G4PhysicsFreeVector*> G4PenelopeBremsstrahlungFS::fCache
private

Definition at line 122 of file G4PenelopeBremsstrahlungFS.hh.

Referenced by G4PenelopeBremsstrahlungFS(), and SampleGammaEnergy().

◆ fEffectiveZSq

std::map<const G4Material*,G4double>* G4PenelopeBremsstrahlungFS::fEffectiveZSq
private

◆ fElementData

std::map<G4int,G4DataVector*>* G4PenelopeBremsstrahlungFS::fElementData
private

◆ fNBinsE

const size_t G4PenelopeBremsstrahlungFS::fNBinsE = 57
staticprivate

◆ fNBinsX

const size_t G4PenelopeBremsstrahlungFS::fNBinsX = 32
staticprivate

◆ fPBcut

std::map< std::pair<const G4Material*,G4double> , G4PhysicsFreeVector* >* G4PenelopeBremsstrahlungFS::fPBcut
private

◆ fReducedXSTable

std::map< std::pair<const G4Material*,G4double> , G4PhysicsTable*>* G4PenelopeBremsstrahlungFS::fReducedXSTable
private

◆ fSamplingTable

std::map< std::pair<const G4Material*,G4double> , G4PhysicsTable*>* G4PenelopeBremsstrahlungFS::fSamplingTable
private

◆ fVerbosity

G4int G4PenelopeBremsstrahlungFS::fVerbosity
private

◆ theEGrid

G4double G4PenelopeBremsstrahlungFS::theEGrid[fNBinsE]
private

◆ theXGrid

G4double G4PenelopeBremsstrahlungFS::theXGrid[fNBinsX]
private

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