Geant4-11
Data Structures | Public Member Functions | Private Member Functions | Private Attributes
G4SBBremTable Class Reference

#include <G4SBBremTable.hh>

Data Structures

struct  SamplingTablePerZ
 
struct  STable
 
struct  STPoint
 

Public Member Functions

void ClearSamplingTables ()
 
 G4SBBremTable ()
 
void Initialize (const G4double lowe, const G4double highe)
 
double SampleEnergyTransfer (const G4double eekin, const G4double leekin, const G4double gcut, const G4double dielSupConst, const G4int izet, const G4int matCutIndx, const bool iselectron)
 
 ~G4SBBremTable ()
 

Private Member Functions

void BuildSamplingTables ()
 
void InitSamplingTables ()
 
G4int LinSearch (const std::vector< STPoint > &vect, const G4int size, const G4double val)
 
void LoadSamplingTables (G4int iz)
 
void LoadSTGrid ()
 
void ReadCompressedFile (const G4String &fname, std::istringstream &iss)
 

Private Attributes

std::vector< G4doublefElEnergyVect
 
G4double fILDeltaElEnergy
 
std::vector< G4doublefKappaVect
 
std::vector< G4doublefLElEnergyVect
 
std::vector< G4doublefLKappaVect
 
G4double fLogMinElEnergy
 
G4int fMaxZet
 
G4int fNumElEnergy
 
G4int fNumKappa
 
std::vector< SamplingTablePerZ * > fSBSamplingTables
 
G4double fUsedHighEenergy
 
G4double fUsedLowEenergy
 

Detailed Description

Definition at line 63 of file G4SBBremTable.hh.

Constructor & Destructor Documentation

◆ G4SBBremTable()

G4SBBremTable::G4SBBremTable ( )

Definition at line 63 of file G4SBBremTable.cc.

64 : fMaxZet(-1), fNumElEnergy(-1), fNumKappa(-1), fUsedLowEenergy(-1.),
66{}
G4double fUsedHighEenergy
G4double fUsedLowEenergy
G4double fLogMinElEnergy
G4double fILDeltaElEnergy

◆ ~G4SBBremTable()

G4SBBremTable::~G4SBBremTable ( )

Definition at line 68 of file G4SBBremTable.cc.

69{
71}
void ClearSamplingTables()

References ClearSamplingTables().

Member Function Documentation

◆ BuildSamplingTables()

void G4SBBremTable::BuildSamplingTables ( )
private

Definition at line 209 of file G4SBBremTable.cc.

209 {
210 // claer
212 LoadSTGrid();
213 // First elements and gamma cuts data structures need to be built:
214 // loop over all material-cuts and add gamma cut to the list of elements
217 // a temporary vector to store one element
218 std::vector<size_t> vtmp(1,0);
219 size_t numMatCuts = thePCTable->GetTableSize();
220 for (size_t imc=0; imc<numMatCuts; ++imc) {
221 const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
222 if (!matCut->IsUsed()) {
223 continue;
224 }
225 const G4Material* mat = matCut->GetMaterial();
226 const G4ElementVector* elemVect = mat->GetElementVector();
227 const G4int indxMC = matCut->GetIndex();
228 const G4double gamCut = (*(thePCTable->GetEnergyCutsVector(0)))[indxMC];
229 const size_t numElems = elemVect->size();
230 for (size_t ielem=0; ielem<numElems; ++ielem) {
231 const G4Element *elem = (*elemVect)[ielem];
232 const G4int izet = std::max(std::min(fMaxZet, elem->GetZasInt()),1);
233 if (!fSBSamplingTables[izet]) {
234 // create data structure but do not load sampling tables yet: will be
235 // loaded after we know what are the min/max e- energies where sampling
236 // will be needed during the simulation for this Z
237 // LoadSamplingTables(izet);
238 fSBSamplingTables[izet] = new SamplingTablePerZ();
239 }
240 // add current gamma cut to the list of this element data (only if this
241 // cut value is still not tehre)
242 const std::vector<double> &cVect = fSBSamplingTables[izet]->fGammaECuts;
243 size_t indx = std::find(cVect.begin(), cVect.end(), gamCut)-cVect.begin();
244 if (indx==cVect.size()) {
245 vtmp[0] = imc;
246 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx.push_back(vtmp);
247 fSBSamplingTables[izet]->fGammaECuts.push_back(gamCut);
248 fSBSamplingTables[izet]->fLogGammaECuts.push_back(G4Log(gamCut));
249 ++fSBSamplingTables[izet]->fNumGammaCuts;
250 } else {
251 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx[indx].push_back(imc);
252 }
253 }
254 }
255}
std::vector< const G4Element * > G4ElementVector
G4double G4Log(G4double x)
Definition: G4Log.hh:226
#define elem(i, j)
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:186
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
std::vector< SamplingTablePerZ * > fSBSamplingTables
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 ClearSamplingTables(), elem, fMaxZet, fSBSamplingTables, G4Log(), G4Material::GetElementVector(), G4ProductionCutsTable::GetEnergyCutsVector(), G4MaterialCutsCouple::GetIndex(), G4MaterialCutsCouple::GetMaterial(), G4ProductionCutsTable::GetMaterialCutsCouple(), G4ProductionCutsTable::GetProductionCutsTable(), G4ProductionCutsTable::GetTableSize(), G4MaterialCutsCouple::IsUsed(), LoadSTGrid(), G4INCL::Math::max(), and G4INCL::Math::min().

Referenced by Initialize().

◆ ClearSamplingTables()

void G4SBBremTable::ClearSamplingTables ( )

Definition at line 460 of file G4SBBremTable.cc.

460 {
461 for (G4int iz=0; iz<fMaxZet+1; ++iz) {
462 if (fSBSamplingTables[iz]) {
463 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
464 if (fSBSamplingTables[iz]->fTablesPerEnergy[iee]) {
465 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fSTable.clear();
466 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fCumCutValues.clear();
467 }
468 }
469 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
470 fSBSamplingTables[iz]->fGammaECuts.clear();
471 fSBSamplingTables[iz]->fLogGammaECuts.clear();
472 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
473 //
474 delete fSBSamplingTables[iz];
475 fSBSamplingTables[iz] = nullptr;
476 }
477 }
478 fSBSamplingTables.clear();
479 fElEnergyVect.clear();
480 fLElEnergyVect.clear();
481 fKappaVect.clear();
482 fLKappaVect.clear();
483 fMaxZet = -1;
484}
std::vector< G4double > fElEnergyVect
std::vector< G4double > fKappaVect
std::vector< G4double > fLKappaVect
std::vector< G4double > fLElEnergyVect

References fElEnergyVect, fKappaVect, fLElEnergyVect, fLKappaVect, fMaxZet, fNumElEnergy, and fSBSamplingTables.

Referenced by BuildSamplingTables(), and ~G4SBBremTable().

◆ Initialize()

void G4SBBremTable::Initialize ( const G4double  lowe,
const G4double  highe 
)

Definition at line 73 of file G4SBBremTable.cc.

74{
75 fUsedLowEenergy = lowe;
76 fUsedHighEenergy = highe;
79// Dump();
80}
void BuildSamplingTables()
void InitSamplingTables()

References BuildSamplingTables(), fUsedHighEenergy, fUsedLowEenergy, and InitSamplingTables().

Referenced by G4SeltzerBergerModel::Initialise().

◆ InitSamplingTables()

void G4SBBremTable::InitSamplingTables ( )
private

Definition at line 257 of file G4SBBremTable.cc.

257 {
258 const size_t numMatCuts = G4ProductionCutsTable::GetProductionCutsTable()
259 ->GetTableSize();
260 for (G4int iz=1; iz<fMaxZet+1; ++iz) {
261 SamplingTablePerZ* stZ = fSBSamplingTables[iz];
262 if (!stZ) continue;
263 // Load-in sampling table data:
265 // init data
266 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
267 if (!stZ->fTablesPerEnergy[iee])
268 continue;
269 const G4double elEnergy = fElEnergyVect[iee];
270 // 1 indicates that gamma production is not possible at this e- energy
271 stZ->fTablesPerEnergy[iee]->fCumCutValues.resize(stZ->fNumGammaCuts,1.);
272 // sort gamma cuts and other members accordingly
273 for (size_t i=0; i<stZ->fNumGammaCuts-1; ++i) {
274 for (size_t j=i+1; j<stZ->fNumGammaCuts; ++j) {
275 if (stZ->fGammaECuts[j]<stZ->fGammaECuts[i]) {
276 G4double dum0 = stZ->fGammaECuts[i];
277 G4double dum1 = stZ->fLogGammaECuts[i];
278 std::vector<size_t> dumv = stZ->fGamCutIndxToMatCutIndx[i];
279 stZ->fGammaECuts[i] = stZ->fGammaECuts[j];
280 stZ->fLogGammaECuts[i] = stZ->fLogGammaECuts[j];
281 stZ->fGamCutIndxToMatCutIndx[i] = stZ->fGamCutIndxToMatCutIndx[j];
282 stZ->fGammaECuts[j] = dum0;
283 stZ->fLogGammaECuts[j] = dum1;
284 stZ->fGamCutIndxToMatCutIndx[j] = dumv;
285 }
286 }
287 }
288 // set couple indices to store the corresponding gamma cut index
289 stZ->fMatCutIndxToGamCutIndx.resize(numMatCuts,-1);
290 for (size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
291 for (size_t j=0; j<stZ->fGamCutIndxToMatCutIndx[i].size(); ++j) {
292 stZ->fMatCutIndxToGamCutIndx[stZ->fGamCutIndxToMatCutIndx[i][j]] = i;
293 }
294 }
295 // clear temporary vector
296 for (size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
297 stZ->fGamCutIndxToMatCutIndx[i].clear();
298 }
299 stZ->fGamCutIndxToMatCutIndx.clear();
300 // init for each gamma cut that are below the e- energy
301 for (size_t ic=0; ic<stZ->fNumGammaCuts; ++ic) {
302 const G4double gamCut = stZ->fGammaECuts[ic];
303 if (elEnergy>gamCut) {
304 // find lower kappa index; compute the 'xi' i.e. cummulative value for
305 // gamCut/elEnergy
306 const G4double cutKappa = std::max(1.e-12, gamCut/elEnergy);
307 const G4int iKLow = (cutKappa>1.e-12)
308 ? std::lower_bound(fKappaVect.begin(), fKappaVect.end(), cutKappa)
309 - fKappaVect.begin() -1
310 : 0;
311 const STPoint* stpL = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow]);
312 const STPoint* stpH = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow+1]);
313 const G4double pA = stpL->fParA;
314 const G4double pB = stpL->fParB;
315 const G4double etaL = stpL->fCum;
316 const G4double etaH = stpH->fCum;
317 const G4double alph = G4Log(cutKappa/fKappaVect[iKLow])
318 /G4Log(fKappaVect[iKLow+1]/fKappaVect[iKLow]);
319 const G4double dum = pA*(alph-1.)-1.-pB;
320 G4double val = etaL;
321 if (alph==0.) {
322 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
323 } else {
324 val = -(dum+std::sqrt(dum*dum-4.*pB*alph*alph))/(2.*pB*alph);
325 val = val*(etaH-etaL)+etaL;
326 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
327 }
328 }
329 }
330 }
331 }
332}
void LoadSamplingTables(G4int iz)

References G4SBBremTable::STPoint::fCum, fElEnergyVect, G4SBBremTable::SamplingTablePerZ::fGamCutIndxToMatCutIndx, G4SBBremTable::SamplingTablePerZ::fGammaECuts, fKappaVect, G4SBBremTable::SamplingTablePerZ::fLogGammaECuts, G4SBBremTable::SamplingTablePerZ::fMatCutIndxToGamCutIndx, fMaxZet, fNumElEnergy, G4SBBremTable::SamplingTablePerZ::fNumGammaCuts, G4SBBremTable::STPoint::fParA, G4SBBremTable::STPoint::fParB, fSBSamplingTables, G4SBBremTable::SamplingTablePerZ::fTablesPerEnergy, G4Log(), G4ProductionCutsTable::GetProductionCutsTable(), G4ProductionCutsTable::GetTableSize(), LoadSamplingTables(), and G4INCL::Math::max().

Referenced by Initialize().

◆ LinSearch()

G4int G4SBBremTable::LinSearch ( const std::vector< STPoint > &  vect,
const G4int  size,
const G4double  val 
)
private

Definition at line 501 of file G4SBBremTable.cc.

503 {
504 G4int i= 0;
505 while (i + 3 < size) {
506 if (vect [i + 0].fCum > val) return i + 0;
507 if (vect [i + 1].fCum > val) return i + 1;
508 if (vect [i + 2].fCum > val) return i + 2;
509 if (vect [i + 3].fCum > val) return i + 3;
510 i += 4;
511 }
512 while (i < size) {
513 if (vect [i].fCum > val)
514 break;
515 ++i;
516 }
517 return i;
518}

Referenced by SampleEnergyTransfer().

◆ LoadSamplingTables()

void G4SBBremTable::LoadSamplingTables ( G4int  iz)
private

Definition at line 387 of file G4SBBremTable.cc.

387 {
388 // check if grid needs to be loaded first
389 if (fMaxZet<0) {
390 LoadSTGrid();
391 }
392 // load data for a given Z only once
393 iz = std::max(std::min(fMaxZet, iz),1);
394 char* path = std::getenv("G4LEDATA");
395 if (!path) {
396 G4Exception("G4SBBremTable::LoadSamplingTables()","em0006",
397 FatalException, "Environment variable G4LEDATA not defined");
398 return;
399 }
400 const G4String fname = G4String(path) + "/brem_SB/SBTables/sTableSB_"
401 + std::to_string(iz);
402 std::istringstream infile(std::ios::in);
403 // read the compressed data file into the stream
404 ReadCompressedFile(fname, infile);
405 // the SamplingTablePerZ object was already created, set size of containers
406 // then load sampling table data for each electron energies
407 SamplingTablePerZ* zTable = fSBSamplingTables[iz];
408 //
409 // Determine min/max elektron kinetic energies and indices
410 const G4double minGammaCut = zTable->fGammaECuts[ std::min_element(
411 std::begin(zTable->fGammaECuts),std::end(zTable->fGammaECuts))
412 -std::begin(zTable->fGammaECuts)];
413 const G4double elEmin = std::max(fUsedLowEenergy, minGammaCut);
414 const G4double elEmax = fUsedHighEenergy;
415 // find low/high elecrton energy indices where tables will be needed
416 // low:
417 zTable->fMinElEnergyIndx = 0;
418 if (elEmin>=fElEnergyVect[fNumElEnergy-1]) {
419 zTable->fMinElEnergyIndx = fNumElEnergy-1;
420 } else {
421 zTable->fMinElEnergyIndx = std::lower_bound(fElEnergyVect.begin(),
422 fElEnergyVect.end(), elEmin) - fElEnergyVect.begin() -1;
423 }
424 // high:
425 zTable->fMaxElEnergyIndx = 0;
426 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
427 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
428 } else {
429 // lower + 1
430 zTable->fMaxElEnergyIndx = std::lower_bound(fElEnergyVect.begin(),
431 fElEnergyVect.end(), elEmax) - fElEnergyVect.begin();
432 }
433 // protect
434 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
435 return;
436 }
437 // load sampling tables that are needed: file is already in the stream
438 zTable->fTablesPerEnergy.resize(fNumElEnergy, nullptr);
439 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
440 // go over data that are not needed
441 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
442 for (G4int ik=0; ik<fNumKappa; ++ik) {
443 G4double dum;
444 infile >> dum; infile >> dum; infile >> dum;
445 }
446 } else { // load data that are needed
447 zTable->fTablesPerEnergy[iee] = new STable();
448 zTable->fTablesPerEnergy[iee]->fSTable.resize(fNumKappa);
449 for (G4int ik=0; ik<fNumKappa; ++ik) {
450 STPoint &stP = zTable->fTablesPerEnergy[iee]->fSTable[ik];
451 infile >> stP.fCum;
452 infile >> stP.fParA;
453 infile >> stP.fParB;
454 }
455 }
456 }
457}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
void ReadCompressedFile(const G4String &fname, std::istringstream &iss)
string fname
Definition: test.py:308

References FatalException, G4SBBremTable::STPoint::fCum, fElEnergyVect, G4SBBremTable::SamplingTablePerZ::fGammaECuts, G4SBBremTable::SamplingTablePerZ::fMaxElEnergyIndx, fMaxZet, G4SBBremTable::SamplingTablePerZ::fMinElEnergyIndx, test::fname, fNumElEnergy, fNumKappa, G4SBBremTable::STPoint::fParA, G4SBBremTable::STPoint::fParB, fSBSamplingTables, G4SBBremTable::SamplingTablePerZ::fTablesPerEnergy, fUsedHighEenergy, fUsedLowEenergy, G4Exception(), LoadSTGrid(), G4INCL::Math::max(), G4INCL::Math::min(), and ReadCompressedFile().

Referenced by InitSamplingTables().

◆ LoadSTGrid()

void G4SBBremTable::LoadSTGrid ( )
private

Definition at line 335 of file G4SBBremTable.cc.

335 {
336 char* path = std::getenv("G4LEDATA");
337 if (!path) {
338 G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
339 FatalException, "Environment variable G4LEDATA not defined");
340 return;
341 }
342 const G4String fname = G4String(path) + "/brem_SB/SBTables/grid";
343 std::ifstream infile(fname,std::ios::in);
344 if (!infile.is_open()) {
345 G4String msgc = "Cannot open file: " + fname;
346 G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
347 FatalException, msgc.c_str());
348 return;
349 }
350 // get max Z, # electron energies and # kappa values
351 infile >> fMaxZet;
352 infile >> fNumElEnergy;
353 infile >> fNumKappa;
354 // allocate space for the data and get them in:
355 // (1.) first eletron energy grid
358 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
359 G4double dum;
360 infile >> dum;
361 fElEnergyVect[iee] = dum*CLHEP::MeV;
363 }
364 // (2.) then the kappa grid
365 fKappaVect.resize(fNumKappa);
366 fLKappaVect.resize(fNumKappa);
367 for (G4int ik=0; ik<fNumKappa; ++ik) {
368 infile >> fKappaVect[ik];
369 fLKappaVect[ik] = G4Log(fKappaVect[ik]);
370 }
371 // (3.) set size of the main container for sampling tables
372 fSBSamplingTables.resize(fMaxZet+1,nullptr);
373 // init electron energy grid related variables: use accurate values !!!
374// fLogMinElEnergy = G4Log(fElEnergyVect[0]);
375// fILDeltaElEnergy = 1./G4Log(fElEnergyVect[1]/fElEnergyVect[0]);
376 const G4double elEmin = 100.0*CLHEP::eV; //fElEnergyVect[0];
377 const G4double elEmax = 10.0*CLHEP::GeV;//fElEnergyVect[fNumElEnergy-1];
378 fLogMinElEnergy = G4Log(elEmin);
379 fILDeltaElEnergy = 1./(G4Log(elEmax/elEmin)/(fNumElEnergy-1.0));
380 // reset min/max energies if needed
383 //
384 infile.close();
385}
static constexpr double GeV
static constexpr double MeV
static constexpr double eV

References CLHEP::eV, FatalException, fElEnergyVect, fILDeltaElEnergy, fKappaVect, fLElEnergyVect, fLKappaVect, fLogMinElEnergy, fMaxZet, test::fname, fNumElEnergy, fNumKappa, fSBSamplingTables, fUsedHighEenergy, fUsedLowEenergy, G4Exception(), G4Log(), CLHEP::GeV, G4INCL::Math::max(), CLHEP::MeV, and G4INCL::Math::min().

Referenced by BuildSamplingTables(), and LoadSamplingTables().

◆ ReadCompressedFile()

void G4SBBremTable::ReadCompressedFile ( const G4String fname,
std::istringstream &  iss 
)
private

Definition at line 521 of file G4SBBremTable.cc.

522 {
523 std::string *dataString = nullptr;
524 std::string compfilename(fname+".z");
525 // create input stream with binary mode operation and positioning at the end
526 // of the file
527 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
528 if (in.good()) {
529 // get current position in the stream (was set to the end)
530 int fileSize = in.tellg();
531 // set current position being the beginning of the stream
532 in.seekg(0,std::ios::beg);
533 // create (zlib) byte buffer for the data
534 Bytef *compdata = new Bytef[fileSize];
535 while(in) {
536 in.read((char*)compdata, fileSize);
537 }
538 // create (zlib) byte buffer for the uncompressed data
539 uLongf complen = (uLongf)(fileSize*4);
540 Bytef *uncompdata = new Bytef[complen];
541 while (Z_OK!=uncompress(uncompdata, &complen, compdata, fileSize)) {
542 // increase uncompressed byte buffer
543 delete[] uncompdata;
544 complen *= 2;
545 uncompdata = new Bytef[complen];
546 }
547 // delete the compressed data buffer
548 delete [] compdata;
549 // create a string from the uncompressed data (will be deleted by the caller)
550 dataString = new std::string((char*)uncompdata, (long)complen);
551 // delete the uncompressed data buffer
552 delete [] uncompdata;
553 } else {
554 std::string msg = " Problem while trying to read "
555 + compfilename + " data file.\n";
556 G4Exception("G4SBBremTable::ReadCompressedFile","em0006",
557 FatalException,msg.c_str());
558 return;
559 }
560 // create the input string stream from the data string
561 if (dataString) {
562 iss.str(*dataString);
563 in.close();
564 delete dataString;
565 }
566}
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: uncompr.c:85
#define Z_OK
Definition: zlib.h:177

References FatalException, test::fname, G4Exception(), uncompress(), and Z_OK.

Referenced by LoadSamplingTables().

◆ SampleEnergyTransfer()

double G4SBBremTable::SampleEnergyTransfer ( const G4double  eekin,
const G4double  leekin,
const G4double  gcut,
const G4double  dielSupConst,
const G4int  izet,
const G4int  matCutIndx,
const bool  iselectron 
)

Definition at line 83 of file G4SBBremTable.cc.

90{
91 static const G4double kAlpha2Pi = CLHEP::twopi*CLHEP::fine_structure_const;
92 const G4double zet = (G4double)iZet;
93 const G4int izet = std::max(std::min(fMaxZet, iZet),1);
94 G4double eGamma = 0.;
95 // this should be checked in the caller
96 // if (eekin<=gcut) return kappa;
97 const G4double lElEnergy = leekin;
98 const SamplingTablePerZ* stZ = fSBSamplingTables[izet];
99 // get the gamma cut of this Z that corresponds to the current mat-cuts
100 const size_t gamCutIndx = stZ->fMatCutIndxToGamCutIndx[matCutIndx];
101 // gcut was not found: should never happen (only in verbose mode)
102 if (gamCutIndx >= stZ->fNumGammaCuts || stZ->fGammaECuts[gamCutIndx]!=gcut) {
103 G4String msg = " Gamma cut="+std::to_string(gcut) + " [MeV] was not found ";
104 msg += "in case of Z = " + std::to_string(iZet) + ". ";
105 G4Exception("G4SBBremTable::SampleEnergyTransfer()","em0X",FatalException,
106 msg.c_str());
107 }
108 const G4double lGCut = stZ->fLogGammaECuts[gamCutIndx];
109 // get the random engine
110 CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
111 // find lower e- energy bin
112 G4bool isCorner = false; // indicate that the lower edge e- energy < gam-gut
113 G4bool isSimply = false; // simply sampling: isCorner+lower egde is selected
114 G4int elEnergyIndx = stZ->fMaxElEnergyIndx;
115 // only if e- ekin is below the maximum value(use table at maximum otherwise)
116 if (eekin < fElEnergyVect[elEnergyIndx]) {
117 const G4double val = (lElEnergy-fLogMinElEnergy)*fILDeltaElEnergy;
118 elEnergyIndx = (G4int)val;
119 G4double pIndxH = val-elEnergyIndx;
120 // check if we are at limiting case: lower edge e- energy < gam-gut
121 if (fElEnergyVect[elEnergyIndx]<=gcut) {
122 // recompute the probability of taking the higher e- energy bin()
123 pIndxH = (lElEnergy-lGCut)/(fLElEnergyVect[elEnergyIndx+1]-lGCut);
124 isCorner = true;
125 }
126 //
127 if (rndmEngine->flat()<pIndxH) {
128 ++elEnergyIndx; // take the table at the higher e- energy bin
129 } else if (isCorner) { // take the table at the lower e- energy bin
130 // special sampling need to be done if lower edge e- energy < gam-gut:
131 // actually, we "sample" from a table "built" at the gamm-cut i.e. delta
132 isSimply = true;
133 }
134 }
135 // should never happen under normal conditions but add protection
136 if (!stZ->fTablesPerEnergy[elEnergyIndx]) {
137 return 0.;
138 }
139 // Do the photon energy sampling:
140 const STable *st = stZ->fTablesPerEnergy[elEnergyIndx];
141 const std::vector<G4double>& cVect = st->fCumCutValues;
142 const std::vector<STPoint>& pVect = st->fSTable;
143 const G4double minVal = cVect[gamCutIndx];
144
145 // should never happen under normal conditions but add protection
146 if (minVal >= 1.) {
147 return 0.;
148 }
149 // some transfomrmtion variables used in the looop
150 const G4double lCurKappaC = lGCut - leekin;
151 const G4double lUsedKappaC = lGCut - fLElEnergyVect[elEnergyIndx];
152 // dielectric (always) and e+ correction suppressions (if the primary is e+)
153 G4double suppression = 1.;
154 G4double rndm[2];
155 // rejection loop starts here
156 do {
157 rndmEngine->flatArray(2, rndm);
158 G4double kappa = 1.0;
159 if (!isSimply) {
160 const G4double cumRV = rndm[0]*(1.-minVal)+minVal;
161 // find lower index of the values in the Cumulative Function: use linear
162 // instead of binary search because it's faster in our case
163 const G4int cumLIndx = LinSearch(pVect, fNumKappa, cumRV)-1;
164// const G4int cumLIndx = std::lower_bound( pVect.begin(), pVect.end(), cumRV,
165// [](const STPoint& p, const double& cumV) {
166// return p.fCum<cumV; } ) - pVect.begin() -1;
167 const STPoint& stPL = pVect[cumLIndx];
168 const G4double pA = stPL.fParA;
169 const G4double pB = stPL.fParB;
170 const G4double cumL = stPL.fCum;
171 const G4double cumH = pVect[cumLIndx+1].fCum;
172 const G4double lKL = fLKappaVect[cumLIndx];
173 const G4double lKH = fLKappaVect[cumLIndx+1];
174 const G4double dm1 = (cumRV-cumL)/(cumH-cumL);
175 const G4double dm2 = (1.+pA+pB)*dm1;
176 const G4double dm3 = 1.+dm1*(pA+pB*dm1);
177 // kappa sampled at E_i e- energy
178 const G4double lKappa = lKL+dm2/dm3*(lKH-lKL);
179 // transform lKappa to [log(gcut/eekin),0] form [log(gcut/E_i),0]
180 kappa = G4Exp(lKappa*lCurKappaC/lUsedKappaC);
181 } else {
182// const G4double upLimit = std::min(1.*CLHEP::eV,eekin-gcut);
183// kappa = (gcut+rndm[0]*upLimit)/eekin;
184 kappa = 1.-rndm[0]*(1.-gcut/eekin);
185 }
186 // compute the emitted photon energy: k
187 eGamma = kappa*eekin;
188 const G4double invEGamma = 1./eGamma;
189 // compute dielectric suppression: 1/(1+[gk_p/k]^2)
190 suppression = 1./(1.+dielSupConst*invEGamma*invEGamma);
191 // add positron correction if particle is e+
192 if (!isElectron) {
193 const G4double e1 = eekin - gcut;
194 const G4double iBeta1 = (e1 + CLHEP::electron_mass_c2)
195 / std::sqrt(e1*(e1 + 2.*CLHEP::electron_mass_c2));
196 const G4double e2 = eekin - eGamma;
197 const G4double iBeta2 = (e2 + CLHEP::electron_mass_c2)
198 / std::sqrt(e2*(e2 + 2.*CLHEP::electron_mass_c2));
199 const G4double dum = kAlpha2Pi*zet*(iBeta1 - iBeta2);
200 suppression = (dum > -12.) ? suppression*G4Exp(dum) : 0.;
201 }
202 } while (rndm[1] > suppression);
203 // end of rejection loop
204 // return the sampled photon energy value k
205 return eGamma;
206}
static const G4double e1[44]
static const G4double e2[44]
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
bool G4bool
Definition: G4Types.hh:86
virtual double flat()=0
virtual void flatArray(const int size, double *vect)=0
G4int LinSearch(const std::vector< STPoint > &vect, const G4int size, const G4double val)
static constexpr double electron_mass_c2
static constexpr double fine_structure_const
static constexpr double twopi
Definition: SystemOfUnits.h:56
G4bool isElectron(G4int ityp)

References e1, e2, CLHEP::electron_mass_c2, FatalException, G4SBBremTable::STPoint::fCum, G4SBBremTable::STable::fCumCutValues, fElEnergyVect, G4SBBremTable::SamplingTablePerZ::fGammaECuts, fILDeltaElEnergy, CLHEP::fine_structure_const, CLHEP::HepRandomEngine::flat(), CLHEP::HepRandomEngine::flatArray(), fLElEnergyVect, fLKappaVect, G4SBBremTable::SamplingTablePerZ::fLogGammaECuts, fLogMinElEnergy, G4SBBremTable::SamplingTablePerZ::fMatCutIndxToGamCutIndx, G4SBBremTable::SamplingTablePerZ::fMaxElEnergyIndx, fMaxZet, G4SBBremTable::SamplingTablePerZ::fNumGammaCuts, fNumKappa, G4SBBremTable::STPoint::fParA, G4SBBremTable::STPoint::fParB, fSBSamplingTables, G4SBBremTable::STable::fSTable, G4SBBremTable::SamplingTablePerZ::fTablesPerEnergy, G4Exception(), G4Exp(), G4InuclParticleNames::isElectron(), LinSearch(), G4INCL::Math::max(), G4INCL::Math::min(), and CLHEP::twopi.

Referenced by G4SeltzerBergerModel::SampleSecondaries().

Field Documentation

◆ fElEnergyVect

std::vector<G4double> G4SBBremTable::fElEnergyVect
private

◆ fILDeltaElEnergy

G4double G4SBBremTable::fILDeltaElEnergy
private

Definition at line 149 of file G4SBBremTable.hh.

Referenced by LoadSTGrid(), and SampleEnergyTransfer().

◆ fKappaVect

std::vector<G4double> G4SBBremTable::fKappaVect
private

Definition at line 154 of file G4SBBremTable.hh.

Referenced by ClearSamplingTables(), InitSamplingTables(), and LoadSTGrid().

◆ fLElEnergyVect

std::vector<G4double> G4SBBremTable::fLElEnergyVect
private

Definition at line 153 of file G4SBBremTable.hh.

Referenced by ClearSamplingTables(), LoadSTGrid(), and SampleEnergyTransfer().

◆ fLKappaVect

std::vector<G4double> G4SBBremTable::fLKappaVect
private

Definition at line 155 of file G4SBBremTable.hh.

Referenced by ClearSamplingTables(), LoadSTGrid(), and SampleEnergyTransfer().

◆ fLogMinElEnergy

G4double G4SBBremTable::fLogMinElEnergy
private

Definition at line 148 of file G4SBBremTable.hh.

Referenced by LoadSTGrid(), and SampleEnergyTransfer().

◆ fMaxZet

G4int G4SBBremTable::fMaxZet
private

◆ fNumElEnergy

G4int G4SBBremTable::fNumElEnergy
private

◆ fNumKappa

G4int G4SBBremTable::fNumKappa
private

Definition at line 143 of file G4SBBremTable.hh.

Referenced by LoadSamplingTables(), LoadSTGrid(), and SampleEnergyTransfer().

◆ fSBSamplingTables

std::vector<SamplingTablePerZ*> G4SBBremTable::fSBSamplingTables
private

◆ fUsedHighEenergy

G4double G4SBBremTable::fUsedHighEenergy
private

Definition at line 147 of file G4SBBremTable.hh.

Referenced by Initialize(), LoadSamplingTables(), and LoadSTGrid().

◆ fUsedLowEenergy

G4double G4SBBremTable::fUsedLowEenergy
private

Definition at line 146 of file G4SBBremTable.hh.

Referenced by Initialize(), LoadSamplingTables(), and LoadSTGrid().


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