64 : fMaxZet(-1), fNumElEnergy(-1), fNumKappa(-1), fUsedLowEenergy(-1.),
65 fUsedHighEenergy(-1.), fLogMinElEnergy(-1.), fILDeltaElEnergy(-1.)
75 fUsedLowEenergy = lowe;
76 fUsedHighEenergy = highe;
77 BuildSamplingTables();
88 const G4int matCutIndx,
91 static const G4double kAlpha2Pi = CLHEP::twopi*CLHEP::fine_structure_const;
93 const G4int izet = std::max(std::min(fMaxZet, iZet),1);
98 const SamplingTablePerZ* stZ = fSBSamplingTables[izet];
100 const size_t gamCutIndx = stZ->fMatCutIndxToGamCutIndx[matCutIndx];
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) +
". ";
108 const G4double lGCut = stZ->fLogGammaECuts[gamCutIndx];
114 G4int elEnergyIndx = stZ->fMaxElEnergyIndx;
116 if (eekin < fElEnergyVect[elEnergyIndx]) {
117 const G4double val = (lElEnergy-fLogMinElEnergy)*fILDeltaElEnergy;
118 elEnergyIndx = (
G4int)val;
121 if (fElEnergyVect[elEnergyIndx]<=gcut) {
123 pIndxH = (lElEnergy-lGCut)/(fLElEnergyVect[elEnergyIndx+1]-lGCut);
127 if (rndmEngine->
flat()<pIndxH) {
129 }
else if (isCorner) {
136 if (!stZ->fTablesPerEnergy[elEnergyIndx]) {
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];
150 const G4double lCurKappaC = lGCut - leekin;
151 const G4double lUsedKappaC = lGCut - fLElEnergyVect[elEnergyIndx];
160 const G4double cumRV = rndm[0]*(1.-minVal)+minVal;
163 const G4int cumLIndx = LinSearch(pVect, fNumKappa, cumRV)-1;
167 const STPoint& stPL = pVect[cumLIndx];
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);
178 const G4double lKappa = lKL+dm2/dm3*(lKH-lKL);
180 kappa =
G4Exp(lKappa*lCurKappaC/lUsedKappaC);
184 kappa = 1.-rndm[0]*(1.-gcut/eekin);
187 eGamma = kappa*eekin;
188 const G4double invEGamma = 1./eGamma;
190 suppression = 1./(1.+dielSupConst*invEGamma*invEGamma);
194 const G4double iBeta1 = (e1 + CLHEP::electron_mass_c2)
195 / std::sqrt(e1*(e1 + 2.*CLHEP::electron_mass_c2));
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.;
202 }
while (rndm[1] > suppression);
209void G4SBBremTable::BuildSamplingTables() {
218 std::vector<size_t> vtmp(1,0);
220 for (
size_t imc=0; imc<numMatCuts; ++imc) {
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]) {
238 fSBSamplingTables[izet] =
new SamplingTablePerZ();
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()) {
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;
251 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx[indx].push_back(imc);
257void G4SBBremTable::InitSamplingTables() {
260 for (
G4int iz=1; iz<fMaxZet+1; ++iz) {
261 SamplingTablePerZ* stZ = fSBSamplingTables[iz];
264 LoadSamplingTables(iz);
266 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
267 if (!stZ->fTablesPerEnergy[iee])
269 const G4double elEnergy = fElEnergyVect[iee];
271 stZ->fTablesPerEnergy[iee]->fCumCutValues.resize(stZ->fNumGammaCuts,1.);
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;
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;
296 for (
size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
297 stZ->fGamCutIndxToMatCutIndx[i].clear();
299 stZ->fGamCutIndxToMatCutIndx.clear();
301 for (
size_t ic=0; ic<stZ->fNumGammaCuts; ++ic) {
302 const G4double gamCut = stZ->fGammaECuts[ic];
303 if (elEnergy>gamCut) {
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
311 const STPoint* stpL = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow]);
312 const STPoint* stpH = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow+1]);
318 /
G4Log(fKappaVect[iKLow+1]/fKappaVect[iKLow]);
319 const G4double dum = pA*(alph-1.)-1.-pB;
322 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
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;
335void G4SBBremTable::LoadSTGrid() {
336 char* path = std::getenv(
"G4LEDATA");
338 G4Exception(
"G4SBBremTable::LoadSTGrid()",
"em0006",
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",
352 infile >> fNumElEnergy;
356 fElEnergyVect.resize(fNumElEnergy);
357 fLElEnergyVect.resize(fNumElEnergy);
358 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
361 fElEnergyVect[iee] = dum*CLHEP::MeV;
362 fLElEnergyVect[iee] =
G4Log(fElEnergyVect[iee]);
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]);
372 fSBSamplingTables.resize(fMaxZet+1,
nullptr);
376 const G4double elEmin = 100.0*CLHEP::eV;
377 const G4double elEmax = 10.0*CLHEP::GeV;
378 fLogMinElEnergy =
G4Log(elEmin);
379 fILDeltaElEnergy = 1./(
G4Log(elEmax/elEmin)/(fNumElEnergy-1.0));
381 fUsedLowEenergy = std::max(fUsedLowEenergy ,elEmin);
382 fUsedHighEenergy = std::min(fUsedHighEenergy,elEmax);
387void G4SBBremTable::LoadSamplingTables(
G4int iz) {
393 iz = std::max(std::min(fMaxZet, iz),1);
394 char* path = std::getenv(
"G4LEDATA");
396 G4Exception(
"G4SBBremTable::LoadSamplingTables()",
"em0006",
401 + std::to_string(iz);
402 std::istringstream infile(std::ios::in);
404 ReadCompressedFile(fname, infile);
407 SamplingTablePerZ* zTable = fSBSamplingTables[iz];
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;
417 zTable->fMinElEnergyIndx = 0;
418 if (elEmin>=fElEnergyVect[fNumElEnergy-1]) {
419 zTable->fMinElEnergyIndx = fNumElEnergy-1;
421 zTable->fMinElEnergyIndx = std::lower_bound(fElEnergyVect.begin(),
422 fElEnergyVect.end(), elEmin) - fElEnergyVect.begin() -1;
425 zTable->fMaxElEnergyIndx = 0;
426 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
427 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
430 zTable->fMaxElEnergyIndx = std::lower_bound(fElEnergyVect.begin(),
431 fElEnergyVect.end(), elEmax) - fElEnergyVect.begin();
434 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
438 zTable->fTablesPerEnergy.resize(fNumElEnergy,
nullptr);
439 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
441 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
442 for (
G4int ik=0; ik<fNumKappa; ++ik) {
444 infile >> dum; infile >> dum; infile >> dum;
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];
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();
469 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
470 fSBSamplingTables[iz]->fGammaECuts.clear();
471 fSBSamplingTables[iz]->fLogGammaECuts.clear();
472 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
474 delete fSBSamplingTables[iz];
475 fSBSamplingTables[iz] =
nullptr;
478 fSBSamplingTables.clear();
479 fElEnergyVect.clear();
480 fLElEnergyVect.clear();
501G4int G4SBBremTable::LinSearch(
const std::vector<STPoint>& vect,
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;
513 if (vect [i].fCum > val)
521void G4SBBremTable::ReadCompressedFile(
const G4String &fname,
522 std::istringstream &iss) {
523 std::string *dataString =
nullptr;
524 std::string compfilename(fname+
".z");
527 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
530 int fileSize = in.tellg();
532 in.seekg(0,std::ios::beg);
534 Bytef *compdata =
new Bytef[fileSize];
536 in.read((
char*)compdata, fileSize);
539 uLongf complen = (uLongf)(fileSize*4);
540 Bytef *uncompdata =
new Bytef[complen];
541 while (
Z_OK!=
uncompress(uncompdata, &complen, compdata, fileSize)) {
545 uncompdata =
new Bytef[complen];
550 dataString =
new std::string((
char*)uncompdata, (
long)complen);
552 delete [] uncompdata;
554 std::string msg =
" Problem while trying to read "
555 + compfilename +
" data file.\n";
556 G4Exception(
"G4SBBremTable::ReadCompressedFile",
"em0006",
562 iss.str(*dataString);
std::vector< G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
virtual void flatArray(const int size, double *vect)=0
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
double SampleEnergyTransfer(const G4double eekin, const G4double leekin, const G4double gcut, const G4double dielSupConst, const G4int izet, const G4int matCutIndx, const bool iselectron)
void Initialize(const G4double lowe, const G4double highe)
void ClearSamplingTables()
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)