48 :XSTableElectron(0),XSTablePositron(0),
49 theDeltaTable(0),energyGrid(0)
53 G4double HighEnergyLimit = 100.0*GeV;
60 theDeltaTable =
new std::map<const G4Material*,G4PhysicsFreeVector*>;
75 for (i=XSTableElectron->begin(); i != XSTableElectron->end(); i++)
80 delete XSTableElectron;
86 for (i=XSTablePositron->begin(); i != XSTablePositron->end(); i++)
91 delete XSTablePositron;
95 std::map<const G4Material*,G4PhysicsFreeVector*>::iterator k;
98 for (k=theDeltaTable->begin();k!=theDeltaTable->end();k++)
100 delete theDeltaTable;
107 if (verboseLevel > 2)
108 G4cout <<
"G4PenelopeIonisationXSHandler. Tables have been cleared"
123 G4Exception(
"G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
130 if (!XSTableElectron)
132 G4Exception(
"G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
134 "The Cross Section Table for e- was not initialized correctly!");
137 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
138 if (XSTableElectron->count(theKey))
139 return XSTableElectron->find(theKey)->second;
142 BuildXSTable(mat,cut,part);
143 if (XSTableElectron->count(theKey))
144 return XSTableElectron->find(theKey)->second;
148 ed <<
"Unable to build e- table for " << mat->
GetName() <<
G4endl;
149 G4Exception(
"G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
157 if (!XSTablePositron)
159 G4Exception(
"G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
161 "The Cross Section Table for e+ was not initialized correctly!");
164 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
165 if (XSTablePositron->count(theKey))
166 return XSTablePositron->find(theKey)->second;
169 BuildXSTable(mat,cut,part);
170 if (XSTablePositron->count(theKey))
171 return XSTablePositron->find(theKey)->second;
175 ed <<
"Unable to build e+ table for " << mat->
GetName() <<
G4endl;
176 G4Exception(
"G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
195 if (verboseLevel > 2)
197 G4cout <<
"G4PenelopeIonisationXSHandler: going to build cross section table " <<
G4endl;
203 size_t numberOfOscillators = theTable->size();
208 ed <<
"Energy Grid looks not initialized" <<
G4endl;
210 G4Exception(
"G4PenelopeIonisationXSHandler::BuildXSTable()",
217 for (
size_t bin=0;bin<nBins;bin++)
224 for (
size_t iosc=0;iosc<numberOfOscillators;iosc++)
231 tempStorage = ComputeShellCrossSectionsElectron(theOsc,energy,cut,delta);
233 tempStorage = ComputeShellCrossSectionsPositron(theOsc,energy,cut,delta);
238 ed <<
"Problem in calculating the shell XS for shell # "
240 G4Exception(
"G4PenelopeIonisationXSHandler::BuildXSTable()",
245 if (tempStorage->size() != 6)
248 ed <<
"Problem in calculating the shell XS " <<
G4endl;
249 ed <<
"Result has dimension " << tempStorage->size() <<
" instead of 6" <<
G4endl;
250 G4Exception(
"G4PenelopeIonisationXSHandler::BuildXSTable()",
255 XH0 += stre*(*tempStorage)[0];
256 XH1 += stre*(*tempStorage)[1];
257 XH2 += stre*(*tempStorage)[2];
258 XS0 += stre*(*tempStorage)[3];
259 XS1 += stre*(*tempStorage)[4];
260 XS2 += stre*(*tempStorage)[5];
272 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
274 XSTableElectron->insert(std::make_pair(theKey,XSEntry));
276 XSTablePositron->insert(std::make_pair(theKey,XSEntry));
292 G4Exception(
"G4PenelopeIonisationXSHandler::GetDensityCorrection()",
294 "Delta Table not initialized. Was Initialise() run?");
299 G4cout <<
"G4PenelopeIonisationXSHandler::GetDensityCorrection()" <<
G4endl;
300 G4cout <<
"Invalid energy " << energy/eV <<
" eV " <<
G4endl;
306 if (!(theDeltaTable->count(mat)))
307 BuildDeltaTable(mat);
309 if (theDeltaTable->count(mat))
312 result = vec->
Value(logene);
317 ed <<
"Unable to build table for " << mat->
GetName() <<
G4endl;
318 G4Exception(
"G4PenelopeIonisationXSHandler::GetDensityCorrection()",
327void G4PenelopeIonisationXSHandler::BuildDeltaTable(
const G4Material* mat)
332 size_t numberOfOscillators = theTable->size();
337 ed <<
"Energy Grid for Delta table looks not initialized" <<
G4endl;
339 G4Exception(
"G4PenelopeIonisationXSHandler::BuildDeltaTable()",
346 for (
size_t bin=0;bin<nBins;bin++)
355 G4double TST = totalZ/(gamSq*plasmaSq);
360 for (
size_t i=0;i<numberOfOscillators;i++)
379 for (
size_t i=0;i<numberOfOscillators;i++)
395 wl2 = 0.5*(wl2l+wl2u);
397 for (
size_t i=0;i<numberOfOscillators;i++)
407 if ((wl2u-wl2l)>1e-12*wl2)
413 for (
size_t i=0;i<numberOfOscillators;i++)
418 std::log(1.0+(wl2/(wri*wri)));
420 delta = (delta/totalZ)-wl2/(gamSq*plasmaSq);
422 energy = std::max(1e-9*eV,energy);
423 theVector->
PutValue(bin,std::log(energy),delta);
425 theDeltaTable->insert(std::make_pair(mat,theVector));
444 for (
size_t i=0;i<6;i++)
445 result->push_back(0.);
449 if (energy < ionEnergy)
456 G4double gamma = 1.0+energy/electron_mass_c2;
458 G4double beta = (gammaSq-1.0)/gammaSq;
459 G4double pielr2 =
pi*classic_electr_radius*classic_electr_radius;
460 G4double constant = pielr2*2.0*electron_mass_c2/beta;
461 G4double XHDT0 = std::log(gammaSq)-beta;
463 G4double cpSq = energy*(energy+2.0*electron_mass_c2);
465 G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
474 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
479 if (resEne > 1e-6*energy)
480 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
483 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
484 QM = QM*(1.0-0.5*QM/electron_mass_c2);
488 SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
493 G4double SDT1 = std::max(XHDT0-delta,0.0);
512 G4double wl = std::max(cut,cutoffEne);
515 if (wl < wu-(1e-5*eV))
517 H0 += (1.0/(ee-wu)) - (1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
518 (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
519 amol*(wu-wl)/(ee*ee);
520 H1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
521 (2.0-amol)*std::log((ee-wu)/(ee-wl)) +
522 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
523 H2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
524 (wl*(2.0*ee-wl)/(ee-wl)) +
525 (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
526 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
531 if (wl > wu-(1e-5*eV))
533 (*result)[0] = constant*H0;
534 (*result)[1] = constant*H1;
535 (*result)[2] = constant*H2;
536 (*result)[3] = constant*S0;
537 (*result)[4] = constant*S1;
538 (*result)[5] = constant*S2;
542 S0 += (1.0/(ee-wu))-(1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
543 (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
544 amol*(wu-wl)/(ee*ee);
545 S1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
546 (2.0-amol)*std::log((ee-wu)/(ee-wl)) +
547 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
548 S2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
549 (wl*(2.0*ee-wl)/(ee-wl)) +
550 (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
551 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
553 (*result)[0] = constant*H0;
554 (*result)[1] = constant*H1;
555 (*result)[2] = constant*H2;
556 (*result)[3] = constant*S0;
557 (*result)[4] = constant*S1;
558 (*result)[5] = constant*S2;
576 for (
size_t i=0;i<6;i++)
577 result->push_back(0.);
581 if (energy < ionEnergy)
588 G4double gamma = 1.0+energy/electron_mass_c2;
590 G4double beta = (gammaSq-1.0)/gammaSq;
591 G4double pielr2 =
pi*classic_electr_radius*classic_electr_radius;
592 G4double constant = pielr2*2.0*electron_mass_c2/beta;
593 G4double XHDT0 = std::log(gammaSq)-beta;
595 G4double cpSq = energy*(energy+2.0*electron_mass_c2);
597 G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
598 G4double g12 = (gamma+1.0)*(gamma+1.0);
600 G4double bha1 = amol*(2.0*g12-1.0)/(gammaSq-1.0);
602 G4double bha3 = amol*2.0*gamma*(gamma-1.0)/g12;
603 G4double bha4 = amol*(gamma-1.0)*(gamma-1.0)/g12;
612 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
617 if (resEne > 1e-6*energy)
618 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
621 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
622 QM = QM*(1.0-0.5*QM/electron_mass_c2);
626 SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
631 G4double SDT1 = std::max(XHDT0-delta,0.0);
651 G4double wl = std::max(cut,cutoffEne);
654 if (wl < wu-(1e-5*eV))
658 H0 += (1.0/wl) - (1.0/wu)- bha1*std::log(wu/wl)/energy
659 + bha2*(wu-wl)/energySq
660 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
661 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
662 H1 += std::log(wu/wl) - bha1*(wu-wl)/energy
663 + bha2*(wuSq-wlSq)/(2.0*energySq)
664 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
665 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
666 H2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
667 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
668 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
669 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
674 if (wl > wu-(1e-5*eV))
676 (*result)[0] = constant*H0;
677 (*result)[1] = constant*H1;
678 (*result)[2] = constant*H2;
679 (*result)[3] = constant*S0;
680 (*result)[4] = constant*S1;
681 (*result)[5] = constant*S2;
688 S0 += (1.0/wl) - (1.0/wu) - bha1*std::log(wu/wl)/energy
689 + bha2*(wu-wl)/energySq
690 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
691 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
693 S1 += std::log(wu/wl) - bha1*(wu-wl)/energy
694 + bha2*(wuSq-wlSq)/(2.0*energySq)
695 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
696 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
698 S2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
699 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
700 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
701 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
703 (*result)[0] = constant*H0;
704 (*result)[1] = constant*H1;
705 (*result)[2] = constant*H2;
706 (*result)[3] = constant*S0;
707 (*result)[4] = constant*S1;
708 (*result)[5] = constant*S2;
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
G4DLLIMPORT std::ostream G4cout
static G4Electron * Electron()
const G4String & GetName() const
const G4String & GetParticleName() const
void AddShellCrossSectionPoint(size_t binNumber, size_t shellID, G4double energy, G4double xs)
void AddCrossSectionPoint(size_t binNumber, G4double energy, G4double XH0, G4double XH1, G4double XH2, G4double XS0, G4double XS1, G4double XS2)
G4double GetDensityCorrection(const G4Material *, G4double energy)
Returns the density coeection for the material at the given energy.
G4PenelopeIonisationXSHandler(size_t nBins=200)
virtual ~G4PenelopeIonisationXSHandler()
Destructor. Clean all tables.
G4PenelopeCrossSection * GetCrossSectionTableForCouple(const G4ParticleDefinition *, const G4Material *, G4double cut)
static G4PenelopeOscillatorManager * GetOscillatorManager()
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
G4double GetPlasmaEnergySquared(const G4Material *)
Returns the squared plasma energy.
G4double GetTotalZ(const G4Material *)
G4double GetIonisationEnergy()
G4double GetResonanceEnergy() const
G4double GetCutoffRecoilResonantEnergy()
G4double GetOscillatorStrength()
void PutValue(size_t binNumber, G4double binValue, G4double dataValue)
G4double Value(G4double theEnergy)
size_t GetVectorLength() const
virtual G4double GetLowEdgeEnergy(size_t binNumber) const
static G4Positron * Positron()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::ostringstream G4ExceptionDescription