65 : fMaxZet(-1), fNumElEnergy(-1), fNumKappa(-1), fUsedLowEenergy(-1.),
66 fUsedHighEenergy(-1.), fLogMinElEnergy(-1.), fILDeltaElEnergy(-1.)
76 fUsedLowEenergy = lowe;
77 fUsedHighEenergy = highe;
78 BuildSamplingTables();
89 const G4int matCutIndx,
92 static const G4double kAlpha2Pi = CLHEP::twopi*CLHEP::fine_structure_const;
94 const G4int izet = std::max(std::min(fMaxZet, iZet),1);
99 const SamplingTablePerZ* stZ = fSBSamplingTables[izet];
101 const std::size_t gamCutIndx = stZ->fMatCutIndxToGamCutIndx[matCutIndx];
103 if (gamCutIndx >= stZ->fNumGammaCuts || stZ->fGammaECuts[gamCutIndx]!=gcut) {
104 G4String msg =
" Gamma cut="+std::to_string(gcut) +
" [MeV] was not found ";
105 msg +=
"in case of Z = " + std::to_string(iZet) +
". ";
109 const G4double lGCut = stZ->fLogGammaECuts[gamCutIndx];
115 G4int elEnergyIndx = stZ->fMaxElEnergyIndx;
117 if (eekin < fElEnergyVect[elEnergyIndx]) {
118 const G4double val = (lElEnergy-fLogMinElEnergy)*fILDeltaElEnergy;
119 elEnergyIndx = (
G4int)val;
122 if (fElEnergyVect[elEnergyIndx]<=gcut) {
124 pIndxH = (lElEnergy-lGCut)/(fLElEnergyVect[elEnergyIndx+1]-lGCut);
128 if (rndmEngine->
flat()<pIndxH) {
130 }
else if (isCorner) {
137 if (!stZ->fTablesPerEnergy[elEnergyIndx]) {
141 const STable *st = stZ->fTablesPerEnergy[elEnergyIndx];
142 const std::vector<G4double>& cVect = st->fCumCutValues;
143 const std::vector<STPoint>& pVect = st->fSTable;
144 const G4double minVal = cVect[gamCutIndx];
151 const G4double lCurKappaC = lGCut - leekin;
152 const G4double lUsedKappaC = lGCut - fLElEnergyVect[elEnergyIndx];
161 const G4double cumRV = rndm[0]*(1.-minVal)+minVal;
164 const G4int cumLIndx = LinSearch(pVect, fNumKappa, cumRV)-1;
168 const STPoint& stPL = pVect[cumLIndx];
172 const G4double cumH = pVect[cumLIndx+1].fCum;
173 const G4double lKL = fLKappaVect[cumLIndx];
174 const G4double lKH = fLKappaVect[cumLIndx+1];
175 const G4double dm1 = (cumRV-cumL)/(cumH-cumL);
176 const G4double dm2 = (1.+pA+pB)*dm1;
177 const G4double dm3 = 1.+dm1*(pA+pB*dm1);
179 const G4double lKappa = lKL+dm2/dm3*(lKH-lKL);
181 kappa =
G4Exp(lKappa*lCurKappaC/lUsedKappaC);
185 kappa = 1.-rndm[0]*(1.-gcut/eekin);
188 eGamma = kappa*eekin;
189 const G4double invEGamma = 1./eGamma;
191 suppression = 1./(1.+dielSupConst*invEGamma*invEGamma);
195 const G4double iBeta1 = (e1 + CLHEP::electron_mass_c2)
196 / std::sqrt(e1*(e1 + 2.*CLHEP::electron_mass_c2));
198 const G4double iBeta2 = (e2 + CLHEP::electron_mass_c2)
199 / std::sqrt(e2*(e2 + 2.*CLHEP::electron_mass_c2));
200 const G4double dum = kAlpha2Pi*zet*(iBeta1 - iBeta2);
201 suppression = (dum > -12.) ? suppression*
G4Exp(dum) : 0.;
203 }
while (rndm[1] > suppression);
210void G4SBBremTable::BuildSamplingTables() {
219 std::vector<std::size_t> vtmp(1,0);
221 for (
G4int imc=0; imc<(
G4int)numMatCuts; ++imc) {
230 const std::size_t numElems = elemVect->size();
231 for (std::size_t ielem=0; ielem<numElems; ++ielem) {
233 const G4int izet = std::max(std::min(fMaxZet,
elem->GetZasInt()),1);
234 if (!fSBSamplingTables[izet]) {
239 fSBSamplingTables[izet] =
new SamplingTablePerZ();
243 const std::vector<double> &cVect = fSBSamplingTables[izet]->fGammaECuts;
244 std::size_t indx = std::find(cVect.cbegin(), cVect.cend(), gamCut)-cVect.cbegin();
245 if (indx==cVect.size()) {
247 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx.push_back(vtmp);
248 fSBSamplingTables[izet]->fGammaECuts.push_back(gamCut);
249 fSBSamplingTables[izet]->fLogGammaECuts.push_back(
G4Log(gamCut));
250 ++fSBSamplingTables[izet]->fNumGammaCuts;
252 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx[indx].push_back(imc);
258void G4SBBremTable::InitSamplingTables() {
261 for (
G4int iz=1; iz<fMaxZet+1; ++iz) {
262 SamplingTablePerZ* stZ = fSBSamplingTables[iz];
265 LoadSamplingTables(iz);
267 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
268 if (!stZ->fTablesPerEnergy[iee])
270 const G4double elEnergy = fElEnergyVect[iee];
272 stZ->fTablesPerEnergy[iee]->fCumCutValues.resize(stZ->fNumGammaCuts,1.);
274 for (std::size_t i=0; i<stZ->fNumGammaCuts-1; ++i) {
275 for (std::size_t j=i+1; j<stZ->fNumGammaCuts; ++j) {
276 if (stZ->fGammaECuts[j]<stZ->fGammaECuts[i]) {
277 G4double dum0 = stZ->fGammaECuts[i];
278 G4double dum1 = stZ->fLogGammaECuts[i];
279 std::vector<std::size_t> dumv = stZ->fGamCutIndxToMatCutIndx[i];
280 stZ->fGammaECuts[i] = stZ->fGammaECuts[j];
281 stZ->fLogGammaECuts[i] = stZ->fLogGammaECuts[j];
282 stZ->fGamCutIndxToMatCutIndx[i] = stZ->fGamCutIndxToMatCutIndx[j];
283 stZ->fGammaECuts[j] = dum0;
284 stZ->fLogGammaECuts[j] = dum1;
285 stZ->fGamCutIndxToMatCutIndx[j] = dumv;
290 stZ->fMatCutIndxToGamCutIndx.resize(numMatCuts,-1);
291 for (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
292 for (std::size_t j=0; j<stZ->fGamCutIndxToMatCutIndx[i].size(); ++j) {
293 stZ->fMatCutIndxToGamCutIndx[stZ->fGamCutIndxToMatCutIndx[i][j]] = i;
297 for (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
298 stZ->fGamCutIndxToMatCutIndx[i].clear();
300 stZ->fGamCutIndxToMatCutIndx.clear();
302 for (std::size_t ic=0; ic<stZ->fNumGammaCuts; ++ic) {
303 const G4double gamCut = stZ->fGammaECuts[ic];
304 if (elEnergy>gamCut) {
307 const G4double cutKappa = std::max(1.e-12, gamCut/elEnergy);
308 const std::size_t iKLow = (cutKappa>1.e-12)
309 ? std::lower_bound(fKappaVect.cbegin(), fKappaVect.cend(), cutKappa)
310 - fKappaVect.cbegin() -1
312 const STPoint* stpL = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow]);
313 const STPoint* stpH = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow+1]);
319 /
G4Log(fKappaVect[iKLow+1]/fKappaVect[iKLow]);
320 const G4double dum = pA*(alph-1.)-1.-pB;
323 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
325 val = -(dum+std::sqrt(dum*dum-4.*pB*alph*alph))/(2.*pB*alph);
326 val = val*(etaH-etaL)+etaL;
327 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
336void G4SBBremTable::LoadSTGrid() {
338 std::ifstream infile(fname,std::ios::in);
339 if (!infile.is_open()) {
340 G4String msgc =
"Cannot open file: " + fname;
341 G4Exception(
"G4SBBremTable::LoadSTGrid()",
"em0006",
347 infile >> fNumElEnergy;
351 fElEnergyVect.resize(fNumElEnergy);
352 fLElEnergyVect.resize(fNumElEnergy);
353 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
356 fElEnergyVect[iee] = dum*CLHEP::MeV;
357 fLElEnergyVect[iee] =
G4Log(fElEnergyVect[iee]);
360 fKappaVect.resize(fNumKappa);
361 fLKappaVect.resize(fNumKappa);
362 for (
G4int ik=0; ik<fNumKappa; ++ik) {
363 infile >> fKappaVect[ik];
364 fLKappaVect[ik] =
G4Log(fKappaVect[ik]);
367 fSBSamplingTables.resize(fMaxZet+1,
nullptr);
371 const G4double elEmin = 100.0*CLHEP::eV;
372 const G4double elEmax = 10.0*CLHEP::GeV;
373 fLogMinElEnergy =
G4Log(elEmin);
374 fILDeltaElEnergy = 1./(
G4Log(elEmax/elEmin)/(fNumElEnergy-1.0));
376 fUsedLowEenergy = std::max(fUsedLowEenergy ,elEmin);
377 fUsedHighEenergy = std::min(fUsedHighEenergy,elEmax);
382void G4SBBremTable::LoadSamplingTables(
G4int iz) {
388 iz = std::max(std::min(fMaxZet, iz),1);
391 + std::to_string(iz);
392 std::istringstream infile(std::ios::in);
394 ReadCompressedFile(fname, infile);
397 SamplingTablePerZ* zTable = fSBSamplingTables[iz];
400 const G4double minGammaCut = zTable->fGammaECuts[ std::min_element(
401 std::cbegin(zTable->fGammaECuts),std::cend(zTable->fGammaECuts))
402 -std::cbegin(zTable->fGammaECuts)];
403 const G4double elEmin = std::max(fUsedLowEenergy, minGammaCut);
404 const G4double elEmax = fUsedHighEenergy;
407 zTable->fMinElEnergyIndx = 0;
408 if (elEmin>=fElEnergyVect[fNumElEnergy-1]) {
409 zTable->fMinElEnergyIndx = fNumElEnergy-1;
411 zTable->fMinElEnergyIndx =
G4int(std::lower_bound(fElEnergyVect.cbegin(),
412 fElEnergyVect.cend(), elEmin)
413 - fElEnergyVect.cbegin() -1);
416 zTable->fMaxElEnergyIndx = 0;
417 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
418 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
421 zTable->fMaxElEnergyIndx =
G4int(std::lower_bound(fElEnergyVect.cbegin(),
422 fElEnergyVect.cend(), elEmax)
423 - fElEnergyVect.cbegin());
426 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
430 zTable->fTablesPerEnergy.resize(fNumElEnergy,
nullptr);
431 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
433 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
434 for (
G4int ik=0; ik<fNumKappa; ++ik) {
436 infile >> dum; infile >> dum; infile >> dum;
439 zTable->fTablesPerEnergy[iee] =
new STable();
440 zTable->fTablesPerEnergy[iee]->fSTable.resize(fNumKappa);
441 for (
G4int ik=0; ik<fNumKappa; ++ik) {
442 STPoint &stP = zTable->fTablesPerEnergy[iee]->fSTable[ik];
453 for (
G4int iz=0; iz<fMaxZet+1; ++iz) {
454 if (fSBSamplingTables[iz]) {
455 for (
G4int iee=0; iee<fNumElEnergy; ++iee) {
456 if (fSBSamplingTables[iz]->fTablesPerEnergy[iee]) {
457 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fSTable.clear();
458 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fCumCutValues.clear();
461 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
462 fSBSamplingTables[iz]->fGammaECuts.clear();
463 fSBSamplingTables[iz]->fLogGammaECuts.clear();
464 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
466 delete fSBSamplingTables[iz];
467 fSBSamplingTables[iz] =
nullptr;
470 fSBSamplingTables.clear();
471 fElEnergyVect.clear();
472 fLElEnergyVect.clear();
493G4int G4SBBremTable::LinSearch(
const std::vector<STPoint>& vect,
497 while (i + 3 < size) {
498 if (vect [i + 0].fCum > val)
return i + 0;
499 if (vect [i + 1].fCum > val)
return i + 1;
500 if (vect [i + 2].fCum > val)
return i + 2;
501 if (vect [i + 3].fCum > val)
return i + 3;
505 if (vect [i].fCum > val)
513void G4SBBremTable::ReadCompressedFile(
const G4String &fname,
514 std::istringstream &iss) {
515 std::string *dataString =
nullptr;
516 std::string compfilename(fname+
".z");
519 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
522 std::streamoff fileSize = in.tellg();
524 in.seekg(0,std::ios::beg);
526 Bytef *compdata =
new Bytef[fileSize];
528 in.read((
char*)compdata, fileSize);
531 uLongf complen = (uLongf)(fileSize*4);
532 Bytef *uncompdata =
new Bytef[complen];
533 while (
Z_OK!=
uncompress(uncompdata, &complen, compdata, fileSize)) {
537 uncompdata =
new Bytef[complen];
542 dataString =
new std::string((
char*)uncompdata, (
long)complen);
544 delete [] uncompdata;
546 std::string msg =
" Problem while trying to read "
547 + compfilename +
" data file.\n";
548 G4Exception(
"G4SBBremTable::ReadCompressedFile",
"em0006",
554 iss.str(*dataString);
std::vector< const 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
static G4EmParameters * Instance()
const G4String & GetDirLEDATA() const
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)