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 std::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<std::size_t> vtmp(1,0);
220 for (
G4int imc=0; imc<(
G4int)numMatCuts; ++imc) {
229 const std::size_t numElems = elemVect->size();
230 for (std::size_t ielem=0; ielem<numElems; ++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 std::size_t indx = std::find(cVect.cbegin(), cVect.cend(), gamCut)-cVect.cbegin();
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 (std::size_t i=0; i<stZ->fNumGammaCuts-1; ++i) {
274 for (std::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<std::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 (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
291 for (std::size_t j=0; j<stZ->fGamCutIndxToMatCutIndx[i].size(); ++j) {
292 stZ->fMatCutIndxToGamCutIndx[stZ->fGamCutIndxToMatCutIndx[i][j]] = i;
296 for (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
297 stZ->fGamCutIndxToMatCutIndx[i].clear();
299 stZ->fGamCutIndxToMatCutIndx.clear();
301 for (std::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 std::size_t iKLow = (cutKappa>1.e-12)
308 ? std::lower_bound(fKappaVect.cbegin(), fKappaVect.cend(), cutKappa)
309 - fKappaVect.cbegin() -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() {
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);
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::cbegin(zTable->fGammaECuts),std::cend(zTable->fGammaECuts))
412 -std::cbegin(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 =
G4int(std::lower_bound(fElEnergyVect.cbegin(),
422 fElEnergyVect.cend(), elEmin)
423 - fElEnergyVect.cbegin() -1);
426 zTable->fMaxElEnergyIndx = 0;
427 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
428 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
431 zTable->fMaxElEnergyIndx =
G4int(std::lower_bound(fElEnergyVect.cbegin(),
432 fElEnergyVect.cend(), elEmax)
433 - fElEnergyVect.cbegin());
436 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
440 zTable->fTablesPerEnergy.resize(fNumElEnergy,
nullptr);
441 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
443 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
444 for (
G4int ik=0; ik<fNumKappa; ++ik) {
446 infile >> dum; infile >> dum; infile >> dum;
449 zTable->fTablesPerEnergy[iee] =
new STable();
450 zTable->fTablesPerEnergy[iee]->fSTable.resize(fNumKappa);
451 for (
G4int ik=0; ik<fNumKappa; ++ik) {
452 STPoint &stP = zTable->fTablesPerEnergy[iee]->fSTable[ik];
463 for (
G4int iz=0; iz<fMaxZet+1; ++iz) {
464 if (fSBSamplingTables[iz]) {
465 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
466 if (fSBSamplingTables[iz]->fTablesPerEnergy[iee]) {
467 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fSTable.clear();
468 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fCumCutValues.clear();
471 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
472 fSBSamplingTables[iz]->fGammaECuts.clear();
473 fSBSamplingTables[iz]->fLogGammaECuts.clear();
474 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
476 delete fSBSamplingTables[iz];
477 fSBSamplingTables[iz] =
nullptr;
480 fSBSamplingTables.clear();
481 fElEnergyVect.clear();
482 fLElEnergyVect.clear();
503G4int G4SBBremTable::LinSearch(
const std::vector<STPoint>& vect,
507 while (i + 3 < size) {
508 if (vect [i + 0].fCum > val)
return i + 0;
509 if (vect [i + 1].fCum > val)
return i + 1;
510 if (vect [i + 2].fCum > val)
return i + 2;
511 if (vect [i + 3].fCum > val)
return i + 3;
515 if (vect [i].fCum > val)
523void G4SBBremTable::ReadCompressedFile(
const G4String &fname,
524 std::istringstream &iss) {
525 std::string *dataString =
nullptr;
526 std::string compfilename(fname+
".z");
529 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
532 std::streamoff fileSize = in.tellg();
534 in.seekg(0,std::ios::beg);
536 Bytef *compdata =
new Bytef[fileSize];
538 in.read((
char*)compdata, fileSize);
541 uLongf complen = (uLongf)(fileSize*4);
542 Bytef *uncompdata =
new Bytef[complen];
543 while (
Z_OK!=
uncompress(uncompdata, &complen, compdata, fileSize)) {
547 uncompdata =
new Bytef[complen];
552 dataString =
new std::string((
char*)uncompdata, (
long)complen);
554 delete [] uncompdata;
556 std::string msg =
" Problem while trying to read "
557 + compfilename +
" data file.\n";
558 G4Exception(
"G4SBBremTable::ReadCompressedFile",
"em0006",
564 iss.str(*dataString);
std::vector< const G4Element * > G4ElementVector
const char * G4FindDataDir(const char *)
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)