Geant4-11
Public Member Functions | Private Member Functions | Private Attributes
G4PenelopeIonisationXSHandler Class Reference

#include <G4PenelopeIonisationXSHandler.hh>

Public Member Functions

void BuildXSTable (const G4Material *, G4double cut, const G4ParticleDefinition *, G4bool isMaster=true)
 This can be inkoved only by the master. More...
 
 G4PenelopeIonisationXSHandler (const G4PenelopeIonisationXSHandler &)=delete
 
 G4PenelopeIonisationXSHandler (size_t nBins=200)
 
const G4PenelopeCrossSectionGetCrossSectionTableForCouple (const G4ParticleDefinition *, const G4Material *, const G4double cut) const
 
G4double GetDensityCorrection (const G4Material *, const G4double energy) const
 Returns the density coeection for the material at the given energy. More...
 
G4PenelopeIonisationXSHandleroperator= (const G4PenelopeIonisationXSHandler &right)=delete
 
void SetVerboseLevel (G4int vl)
 Setter for the verbosity level. More...
 
virtual ~G4PenelopeIonisationXSHandler ()
 Destructor. Clean all tables. More...
 

Private Member Functions

void BuildDeltaTable (const G4Material *)
 
G4DataVectorComputeShellCrossSectionsElectron (G4PenelopeOscillator *, G4double energy, G4double cut, G4double delta)
 
G4DataVectorComputeShellCrossSectionsPositron (G4PenelopeOscillator *, G4double energy, G4double cut, G4double delta)
 

Private Attributes

std::map< const G4Material *, G4PhysicsFreeVector * > * fDeltaTable
 
G4PhysicsLogVectorfEnergyGrid
 
size_t fNBins
 
G4PenelopeOscillatorManagerfOscManager
 
G4int fVerboseLevel
 
std::map< std::pair< const G4Material *, G4double >, G4PenelopeCrossSection * > * fXSTableElectron
 
std::map< std::pair< const G4Material *, G4double >, G4PenelopeCrossSection * > * fXSTablePositron
 

Detailed Description

Definition at line 59 of file G4PenelopeIonisationXSHandler.hh.

Constructor & Destructor Documentation

◆ G4PenelopeIonisationXSHandler() [1/2]

G4PenelopeIonisationXSHandler::G4PenelopeIonisationXSHandler ( size_t  nBins = 200)
explicit

Constructor. nBins is the number of intervals in the energy grid. By default the energy grid goes from 100 eV to 100 GeV.

Definition at line 46 of file G4PenelopeIonisationXSHandler.cc.

47 :fXSTableElectron(nullptr),fXSTablePositron(nullptr),
48 fDeltaTable(nullptr),fEnergyGrid(nullptr)
49{
50 fNBins = nb;
51 G4double LowEnergyLimit = 100.0*eV;
52 G4double HighEnergyLimit = 100.0*GeV;
54 fXSTableElectron = new
55 std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
56 fXSTablePositron = new
57 std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
58
59 fDeltaTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
60 fEnergyGrid = new G4PhysicsLogVector(LowEnergyLimit,
61 HighEnergyLimit,
62 fNBins-1); //one hidden bin is added
63 fVerboseLevel = 0;
64}
static constexpr double eV
Definition: G4SIunits.hh:201
static constexpr double GeV
Definition: G4SIunits.hh:203
double G4double
Definition: G4Types.hh:83
std::map< std::pair< const G4Material *, G4double >, G4PenelopeCrossSection * > * fXSTablePositron
G4PenelopeOscillatorManager * fOscManager
std::map< std::pair< const G4Material *, G4double >, G4PenelopeCrossSection * > * fXSTableElectron
std::map< const G4Material *, G4PhysicsFreeVector * > * fDeltaTable
static G4PenelopeOscillatorManager * GetOscillatorManager()

References eV, fDeltaTable, fEnergyGrid, fNBins, fOscManager, fVerboseLevel, fXSTableElectron, fXSTablePositron, G4PenelopeOscillatorManager::GetOscillatorManager(), and GeV.

◆ ~G4PenelopeIonisationXSHandler()

G4PenelopeIonisationXSHandler::~G4PenelopeIonisationXSHandler ( )
virtual

Destructor. Clean all tables.

Definition at line 68 of file G4PenelopeIonisationXSHandler.cc.

69{
71 {
72 for (auto& item : (*fXSTableElectron))
73 {
74 //G4PenelopeCrossSection* tab = i->second;
75 delete item.second;
76 }
77 delete fXSTableElectron;
78 fXSTableElectron = nullptr;
79 }
80
82 {
83 for (auto& item : (*fXSTablePositron))
84 {
85 //G4PenelopeCrossSection* tab = i->second;
86 delete item.second;
87 }
88 delete fXSTablePositron;
89 fXSTablePositron = nullptr;
90 }
91 if (fDeltaTable)
92 {
93 for (auto& item : (*fDeltaTable))
94 delete item.second;
95 delete fDeltaTable;
96 fDeltaTable = nullptr;
97 }
98 if (fEnergyGrid)
99 delete fEnergyGrid;
100
101 if (fVerboseLevel > 2)
102 G4cout << "G4PenelopeIonisationXSHandler. Tables have been cleared"
103 << G4endl;
104}
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout

References fDeltaTable, fEnergyGrid, fVerboseLevel, fXSTableElectron, fXSTablePositron, G4cout, and G4endl.

◆ G4PenelopeIonisationXSHandler() [2/2]

G4PenelopeIonisationXSHandler::G4PenelopeIonisationXSHandler ( const G4PenelopeIonisationXSHandler )
delete

Member Function Documentation

◆ BuildDeltaTable()

void G4PenelopeIonisationXSHandler::BuildDeltaTable ( const G4Material mat)
private

Definition at line 321 of file G4PenelopeIonisationXSHandler.cc.

322{
325 G4double totalZ = fOscManager->GetTotalZ(mat);
326 size_t numberOfOscillators = theTable->size();
327
329 {
331 ed << "Energy Grid for Delta table looks not initialized" << G4endl;
332 ed << fNBins << " " << fEnergyGrid->GetVectorLength() << G4endl;
333 G4Exception("G4PenelopeIonisationXSHandler::BuildDeltaTable()",
334 "em2030",FatalException,ed);
335 }
336
338
339 //loop on the energy grid
340 for (size_t bin=0;bin<fNBins;bin++)
341 {
342 G4double delta = 0.;
344
345 //Here calculate delta
347 G4double gamSq = gam*gam;
348
349 G4double TST = totalZ/(gamSq*plasmaSq);
350 G4double wl2 = 0;
351 G4double fdel = 0;
352
353 //loop on oscillators
354 for (size_t i=0;i<numberOfOscillators;i++)
355 {
356 G4PenelopeOscillator* theOsc = (*theTable)[i];
357 G4double wri = theOsc->GetResonanceEnergy();
358 fdel += theOsc->GetOscillatorStrength()/(wri*wri+wl2);
359 }
360 if (fdel >= TST) //if fdel < TST, delta = 0
361 {
362 //get last oscillator
363 G4PenelopeOscillator* theOsc = (*theTable)[numberOfOscillators-1];
364 wl2 = theOsc->GetResonanceEnergy()*theOsc->GetResonanceEnergy();
365
366 //First iteration
367 G4bool loopAgain = false;
368 do
369 {
370 loopAgain = false;
371 wl2 += wl2;
372 fdel = 0.;
373 for (size_t i=0;i<numberOfOscillators;i++)
374 {
375 G4PenelopeOscillator* theOscLocal1 = (*theTable)[i];
376 G4double wri = theOscLocal1->GetResonanceEnergy();
377 fdel += theOscLocal1->GetOscillatorStrength()/(wri*wri+wl2);
378 }
379 if (fdel > TST)
380 loopAgain = true;
381 }while(loopAgain);
382
383 G4double wl2l = 0;
384 G4double wl2u = wl2;
385 //second iteration
386 do
387 {
388 loopAgain = false;
389 wl2 = 0.5*(wl2l+wl2u);
390 fdel = 0;
391 for (size_t i=0;i<numberOfOscillators;i++)
392 {
393 G4PenelopeOscillator* theOscLocal2 = (*theTable)[i];
394 G4double wri = theOscLocal2->GetResonanceEnergy();
395 fdel += theOscLocal2->GetOscillatorStrength()/(wri*wri+wl2);
396 }
397 if (fdel > TST)
398 wl2l = wl2;
399 else
400 wl2u = wl2;
401 if ((wl2u-wl2l)>1e-12*wl2)
402 loopAgain = true;
403 }while(loopAgain);
404
405 //Eventually get density correction
406 delta = 0.;
407 for (size_t i=0;i<numberOfOscillators;i++)
408 {
409 G4PenelopeOscillator* theOscLocal3 = (*theTable)[i];
410 G4double wri = theOscLocal3->GetResonanceEnergy();
411 delta += theOscLocal3->GetOscillatorStrength()*
412 G4Log(1.0+(wl2/(wri*wri)));
413 }
414 delta = (delta/totalZ)-wl2/(gamSq*plasmaSq);
415 }
416 energy = std::max(1e-9*eV,energy); //prevents log(0)
417 theVector->PutValue(bin,G4Log(energy),delta);
418 }
419 fDeltaTable->insert(std::make_pair(mat,theVector));
420 return;
421}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4double G4Log(G4double x)
Definition: G4Log.hh:226
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
bool G4bool
Definition: G4Types.hh:86
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
G4double GetPlasmaEnergySquared(const G4Material *)
Returns the squared plasma energy.
G4double GetTotalZ(const G4Material *)
G4double GetResonanceEnergy() const
void PutValue(const std::size_t index, const G4double e, const G4double value)
G4double GetLowEdgeEnergy(const std::size_t index) const
std::size_t GetVectorLength() const
G4double energy(const ThreeVector &p, const G4double m)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
float electron_mass_c2
Definition: hepunit.py:273

References source.hepunit::electron_mass_c2, G4INCL::KinematicsUtils::energy(), eV, FatalException, fDeltaTable, fEnergyGrid, fNBins, fOscManager, G4endl, G4Exception(), G4Log(), G4InuclParticleNames::gam, G4PhysicsVector::GetLowEdgeEnergy(), G4PenelopeOscillator::GetOscillatorStrength(), G4PenelopeOscillatorManager::GetOscillatorTableIonisation(), G4PenelopeOscillatorManager::GetPlasmaEnergySquared(), G4PenelopeOscillator::GetResonanceEnergy(), G4PenelopeOscillatorManager::GetTotalZ(), G4PhysicsVector::GetVectorLength(), G4INCL::Math::max(), and G4PhysicsFreeVector::PutValue().

Referenced by BuildXSTable().

◆ BuildXSTable()

void G4PenelopeIonisationXSHandler::BuildXSTable ( const G4Material mat,
G4double  cut,
const G4ParticleDefinition part,
G4bool  isMaster = true 
)

This can be inkoved only by the master.

Definition at line 158 of file G4PenelopeIonisationXSHandler.cc.

161{
162 //Just to check
163 if (!isMaster)
164 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
165 "em0100",FatalException,"Worker thread in this method");
166
167 //
168 //This method fills the G4PenelopeCrossSection containers for electrons or positrons
169 //and for the given material/cut couple. The calculation is done as sum over the
170 //individual shells.
171 //Equivalent of subroutines EINaT and PINaT of Penelope
172 //
173 if (fVerboseLevel > 2)
174 {
175 G4cout << "G4PenelopeIonisationXSHandler: going to build cross section table " << G4endl;
176 G4cout << "for " << part->GetParticleName() << " in " << mat->GetName() << G4endl;
177 G4cout << "Cut= " << cut/keV << " keV" << G4endl;
178 }
179
180 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
181 //Check if the table already exists
182 if (part == G4Electron::Electron())
183 {
184 if (fXSTableElectron->count(theKey)) //table already built
185 return;
186 }
187 if (part == G4Positron::Positron())
188 {
189 if (fXSTablePositron->count(theKey)) //table already built
190 return;
191 }
192
193 //check if the material has been built
194 if (!(fDeltaTable->count(mat)))
195 BuildDeltaTable(mat);
196
197
198 //Tables have been already created (checked by GetCrossSectionTableForCouple)
200 size_t numberOfOscillators = theTable->size();
201
203 {
205 ed << "Energy Grid looks not initialized" << G4endl;
206 ed << fNBins << " " << fEnergyGrid->GetVectorLength() << G4endl;
207 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
208 "em2030",FatalException,ed);
209 }
210
211 G4PenelopeCrossSection* XSEntry = new G4PenelopeCrossSection(fNBins,numberOfOscillators);
212
213 //loop on the energy grid
214 for (size_t bin=0;bin<fNBins;bin++)
215 {
217 G4double XH0=0, XH1=0, XH2=0;
218 G4double XS0=0, XS1=0, XS2=0;
219
220 //oscillator loop
221 for (size_t iosc=0;iosc<numberOfOscillators;iosc++)
222 {
223 G4DataVector* tempStorage = nullptr;
224
225 G4PenelopeOscillator* theOsc = (*theTable)[iosc];
227 if (part == G4Electron::Electron())
228 tempStorage = ComputeShellCrossSectionsElectron(theOsc,energy,cut,delta);
229 else if (part == G4Positron::Positron())
230 tempStorage = ComputeShellCrossSectionsPositron(theOsc,energy,cut,delta);
231 //check results are all right
232 if (!tempStorage)
233 {
235 ed << "Problem in calculating the shell XS for shell # "
236 << iosc << G4endl;
237 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
238 "em2031",FatalException,ed);
239 delete XSEntry;
240 return;
241 }
242 if (tempStorage->size() != 6)
243 {
245 ed << "Problem in calculating the shell XS " << G4endl;
246 ed << "Result has dimension " << tempStorage->size() << " instead of 6" << G4endl;
247 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
248 "em2031",FatalException,ed);
249 }
250 G4double stre = theOsc->GetOscillatorStrength();
251
252 XH0 += stre*(*tempStorage)[0];
253 XH1 += stre*(*tempStorage)[1];
254 XH2 += stre*(*tempStorage)[2];
255 XS0 += stre*(*tempStorage)[3];
256 XS1 += stre*(*tempStorage)[4];
257 XS2 += stre*(*tempStorage)[5];
258 XSEntry->AddShellCrossSectionPoint(bin,iosc,energy,stre*(*tempStorage)[0]);
259 if (tempStorage)
260 {
261 delete tempStorage;
262 tempStorage = nullptr;
263 }
264 }
265 XSEntry->AddCrossSectionPoint(bin,energy,XH0,XH1,XH2,XS0,XS1,XS2);
266 }
267 //Do (only once) the final normalization
269
270 //Insert in the appropriate table
271 if (part == G4Electron::Electron())
272 fXSTableElectron->insert(std::make_pair(theKey,XSEntry));
273 else if (part == G4Positron::Positron())
274 fXSTablePositron->insert(std::make_pair(theKey,XSEntry));
275 else
276 delete XSEntry;
277
278 return;
279}
static constexpr double keV
Definition: G4SIunits.hh:202
static G4Electron * Electron()
Definition: G4Electron.cc:93
const G4String & GetName() const
Definition: G4Material.hh:173
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 *, const G4double energy) const
Returns the density coeection for the material at the given energy.
G4DataVector * ComputeShellCrossSectionsPositron(G4PenelopeOscillator *, G4double energy, G4double cut, G4double delta)
G4DataVector * ComputeShellCrossSectionsElectron(G4PenelopeOscillator *, G4double energy, G4double cut, G4double delta)
static G4Positron * Positron()
Definition: G4Positron.cc:93

References G4PenelopeCrossSection::AddCrossSectionPoint(), G4PenelopeCrossSection::AddShellCrossSectionPoint(), BuildDeltaTable(), ComputeShellCrossSectionsElectron(), ComputeShellCrossSectionsPositron(), G4Electron::Electron(), G4INCL::KinematicsUtils::energy(), FatalException, fDeltaTable, fEnergyGrid, fNBins, fOscManager, fVerboseLevel, fXSTableElectron, fXSTablePositron, G4cout, G4endl, G4Exception(), GetDensityCorrection(), G4PhysicsVector::GetLowEdgeEnergy(), G4Material::GetName(), G4PenelopeOscillator::GetOscillatorStrength(), G4PenelopeOscillatorManager::GetOscillatorTableIonisation(), G4ParticleDefinition::GetParticleName(), G4PhysicsVector::GetVectorLength(), keV, G4PenelopeCrossSection::NormalizeShellCrossSections(), and G4Positron::Positron().

Referenced by G4PenelopeIonisationModel::ComputeDEDXPerVolume(), G4PenelopeIonisationCrossSection::CrossSection(), G4PenelopeIonisationModel::CrossSectionPerVolume(), and G4PenelopeIonisationModel::Initialise().

◆ ComputeShellCrossSectionsElectron()

G4DataVector * G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron ( G4PenelopeOscillator theOsc,
G4double  energy,
G4double  cut,
G4double  delta 
)
private

Definition at line 424 of file G4PenelopeIonisationXSHandler.cc.

428{
429 //
430 //This method calculates the hard and soft cross sections (H0-H1-H2-S0-S1-S2) for
431 //the given oscillator/cut and at the given energy.
432 //It returns a G4DataVector* with 6 entries (H0-H1-H2-S0-S1-S2)
433 //Equivalent of subroutines EINaT1 of Penelope
434 //
435 // Results are _per target electron_
436 //
437 G4DataVector* result = new G4DataVector();
438 for (size_t i=0;i<6;i++)
439 result->push_back(0.);
440 G4double ionEnergy = theOsc->GetIonisationEnergy();
441
442 //return a set of zero's if the energy it too low to excite the current oscillator
443 if (energy < ionEnergy)
444 return result;
445
446 G4double H0=0.,H1=0.,H2=0.;
447 G4double S0=0.,S1=0.,S2=0.;
448
449 //Define useful constants to be used in the calculation
450 G4double gamma = 1.0+energy/electron_mass_c2;
451 G4double gammaSq = gamma*gamma;
452 G4double beta = (gammaSq-1.0)/gammaSq;
454 G4double constant = pielr2*2.0*electron_mass_c2/beta;
455 G4double XHDT0 = G4Log(gammaSq)-beta;
456
458 G4double cp = std::sqrt(cpSq);
460
461 //
462 // Distant interactions
463 //
464 G4double resEne = theOsc->GetResonanceEnergy();
465 G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
466 if (energy > resEne)
467 {
468 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
469 G4double cp1 = std::sqrt(cp1Sq);
470
471 //Distant longitudinal interactions
472 G4double QM = 0;
473 if (resEne > 1e-6*energy)
474 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
475 else
476 {
477 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
478 QM = QM*(1.0-0.5*QM/electron_mass_c2);
479 }
480 G4double SDL1 = 0;
481 if (QM < cutoffEne)
482 SDL1 = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
483
484 //Distant transverse interactions
485 if (SDL1)
486 {
487 G4double SDT1 = std::max(XHDT0-delta,0.0);
488 G4double SD1 = SDL1+SDT1;
489 if (cut > resEne)
490 {
491 S1 = SD1; //XS1
492 S0 = SD1/resEne; //XS0
493 S2 = SD1*resEne; //XS2
494 }
495 else
496 {
497 H1 = SD1; //XH1
498 H0 = SD1/resEne; //XH0
499 H2 = SD1*resEne; //XH2
500 }
501 }
502 }
503 //
504 // Close collisions (Moller's cross section)
505 //
506 G4double wl = std::max(cut,cutoffEne);
507 G4double ee = energy + ionEnergy;
508 G4double wu = 0.5*ee;
509 if (wl < wu-(1e-5*eV))
510 {
511 H0 += (1.0/(ee-wu)) - (1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
512 (1.0-amol)*G4Log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
513 amol*(wu-wl)/(ee*ee);
514 H1 += G4Log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
515 (2.0-amol)*G4Log((ee-wu)/(ee-wl)) +
516 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
517 H2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
518 (wl*(2.0*ee-wl)/(ee-wl)) +
519 (3.0-amol)*ee*G4Log((ee-wu)/(ee-wl)) +
520 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
521 wu = wl;
522 }
523 wl = cutoffEne;
524
525 if (wl > wu-(1e-5*eV))
526 {
527 (*result)[0] = constant*H0;
528 (*result)[1] = constant*H1;
529 (*result)[2] = constant*H2;
530 (*result)[3] = constant*S0;
531 (*result)[4] = constant*S1;
532 (*result)[5] = constant*S2;
533 return result;
534 }
535
536 S0 += (1.0/(ee-wu))-(1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
537 (1.0-amol)*G4Log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
538 amol*(wu-wl)/(ee*ee);
539 S1 += G4Log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
540 (2.0-amol)*G4Log((ee-wu)/(ee-wl)) +
541 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
542 S2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
543 (wl*(2.0*ee-wl)/(ee-wl)) +
544 (3.0-amol)*ee*G4Log((ee-wu)/(ee-wl)) +
545 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
546
547 (*result)[0] = constant*H0;
548 (*result)[1] = constant*H1;
549 (*result)[2] = constant*H2;
550 (*result)[3] = constant*S0;
551 (*result)[4] = constant*S1;
552 (*result)[5] = constant*S2;
553 return result;
554}
static const G4double cp
static constexpr double pi
Definition: G4SIunits.hh:55
G4double GetCutoffRecoilResonantEnergy()
int classic_electr_radius
Definition: hepunit.py:287

References anonymous_namespace{G4PionRadiativeDecayChannel.cc}::beta, source.hepunit::classic_electr_radius, cp, source.hepunit::electron_mass_c2, G4INCL::KinematicsUtils::energy(), eV, G4Log(), G4PenelopeOscillator::GetCutoffRecoilResonantEnergy(), G4PenelopeOscillator::GetIonisationEnergy(), G4PenelopeOscillator::GetResonanceEnergy(), G4INCL::Math::max(), and pi.

Referenced by BuildXSTable().

◆ ComputeShellCrossSectionsPositron()

G4DataVector * G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron ( G4PenelopeOscillator theOsc,
G4double  energy,
G4double  cut,
G4double  delta 
)
private

Definition at line 556 of file G4PenelopeIonisationXSHandler.cc.

560{
561 //
562 //This method calculates the hard and soft cross sections (H0-H1-H2-S0-S1-S2) for
563 //the given oscillator/cut and at the given energy.
564 //It returns a G4DataVector* with 6 entries (H0-H1-H2-S0-S1-S2)
565 //Equivalent of subroutines PINaT1 of Penelope
566 //
567 // Results are _per target electron_
568 //
569 G4DataVector* result = new G4DataVector();
570 for (size_t i=0;i<6;i++)
571 result->push_back(0.);
572 G4double ionEnergy = theOsc->GetIonisationEnergy();
573
574 //return a set of zero's if the energy it too low to excite the current oscillator
575 if (energy < ionEnergy)
576 return result;
577
578 G4double H0=0.,H1=0.,H2=0.;
579 G4double S0=0.,S1=0.,S2=0.;
580
581 //Define useful constants to be used in the calculation
582 G4double gamma = 1.0+energy/electron_mass_c2;
583 G4double gammaSq = gamma*gamma;
584 G4double beta = (gammaSq-1.0)/gammaSq;
586 G4double constant = pielr2*2.0*electron_mass_c2/beta;
587 G4double XHDT0 = G4Log(gammaSq)-beta;
588
590 G4double cp = std::sqrt(cpSq);
592 G4double g12 = (gamma+1.0)*(gamma+1.0);
593 //Bhabha coefficients
594 G4double bha1 = amol*(2.0*g12-1.0)/(gammaSq-1.0);
595 G4double bha2 = amol*(3.0+1.0/g12);
596 G4double bha3 = amol*2.0*gamma*(gamma-1.0)/g12;
597 G4double bha4 = amol*(gamma-1.0)*(gamma-1.0)/g12;
598
599 //
600 // Distant interactions
601 //
602 G4double resEne = theOsc->GetResonanceEnergy();
603 G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
604 if (energy > resEne)
605 {
606 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
607 G4double cp1 = std::sqrt(cp1Sq);
608
609 //Distant longitudinal interactions
610 G4double QM = 0;
611 if (resEne > 1e-6*energy)
612 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
613 else
614 {
615 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
616 QM = QM*(1.0-0.5*QM/electron_mass_c2);
617 }
618 G4double SDL1 = 0;
619 if (QM < cutoffEne)
620 SDL1 = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
621
622 //Distant transverse interactions
623 if (SDL1)
624 {
625 G4double SDT1 = std::max(XHDT0-delta,0.0);
626 G4double SD1 = SDL1+SDT1;
627 if (cut > resEne)
628 {
629 S1 = SD1; //XS1
630 S0 = SD1/resEne; //XS0
631 S2 = SD1*resEne; //XS2
632 }
633 else
634 {
635 H1 = SD1; //XH1
636 H0 = SD1/resEne; //XH0
637 H2 = SD1*resEne; //XH2
638 }
639 }
640 }
641 //
642 // Close collisions (Bhabha's cross section)
643 //
644 G4double wl = std::max(cut,cutoffEne);
645 G4double wu = energy;
646 G4double energySq = energy*energy;
647 if (wl < wu-(1e-5*eV))
648 {
649 G4double wlSq = wl*wl;
650 G4double wuSq = wu*wu;
651 H0 += (1.0/wl) - (1.0/wu)- bha1*G4Log(wu/wl)/energy
652 + bha2*(wu-wl)/energySq
653 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
654 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
655 H1 += G4Log(wu/wl) - bha1*(wu-wl)/energy
656 + bha2*(wuSq-wlSq)/(2.0*energySq)
657 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
658 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
659 H2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
660 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
661 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
662 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
663 wu = wl;
664 }
665 wl = cutoffEne;
666
667 if (wl > wu-(1e-5*eV))
668 {
669 (*result)[0] = constant*H0;
670 (*result)[1] = constant*H1;
671 (*result)[2] = constant*H2;
672 (*result)[3] = constant*S0;
673 (*result)[4] = constant*S1;
674 (*result)[5] = constant*S2;
675 return result;
676 }
677
678 G4double wlSq = wl*wl;
679 G4double wuSq = wu*wu;
680
681 S0 += (1.0/wl) - (1.0/wu) - bha1*G4Log(wu/wl)/energy
682 + bha2*(wu-wl)/energySq
683 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
684 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
685
686 S1 += G4Log(wu/wl) - bha1*(wu-wl)/energy
687 + bha2*(wuSq-wlSq)/(2.0*energySq)
688 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
689 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
690
691 S2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
692 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
693 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
694 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
695
696 (*result)[0] = constant*H0;
697 (*result)[1] = constant*H1;
698 (*result)[2] = constant*H2;
699 (*result)[3] = constant*S0;
700 (*result)[4] = constant*S1;
701 (*result)[5] = constant*S2;
702
703 return result;
704}

References anonymous_namespace{G4PionRadiativeDecayChannel.cc}::beta, source.hepunit::classic_electr_radius, cp, source.hepunit::electron_mass_c2, G4INCL::KinematicsUtils::energy(), eV, G4Log(), G4PenelopeOscillator::GetCutoffRecoilResonantEnergy(), G4PenelopeOscillator::GetIonisationEnergy(), G4PenelopeOscillator::GetResonanceEnergy(), G4INCL::Math::max(), and pi.

Referenced by BuildXSTable().

◆ GetCrossSectionTableForCouple()

const G4PenelopeCrossSection * G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple ( const G4ParticleDefinition part,
const G4Material mat,
const G4double  cut 
) const

Returns the table of cross sections for the given particle, given material and given cut as a G4PenelopeCrossSection* pointer.

Definition at line 109 of file G4PenelopeIonisationXSHandler.cc.

112{
113 if (part != G4Electron::Electron() && part != G4Positron::Positron())
114 {
116 ed << "Invalid particle: " << part->GetParticleName() << G4endl;
117 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
118 "em0001",FatalException,ed);
119 return nullptr;
120 }
121
122 if (part == G4Electron::Electron())
123 {
124 if (!fXSTableElectron)
125 {
126 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
127 "em0028",FatalException,
128 "The Cross Section Table for e- was not initialized correctly!");
129 return nullptr;
130 }
131 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
132 if (fXSTableElectron->count(theKey)) //table already built
133 return fXSTableElectron->find(theKey)->second;
134 else
135 return nullptr;
136 }
137
138 if (part == G4Positron::Positron())
139 {
140 if (!fXSTablePositron)
141 {
142 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
143 "em0028",FatalException,
144 "The Cross Section Table for e+ was not initialized correctly!");
145 return nullptr;
146 }
147 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
148 if (fXSTablePositron->count(theKey)) //table already built
149 return fXSTablePositron->find(theKey)->second;
150 else
151 return nullptr;
152 }
153 return nullptr;
154}

References G4Electron::Electron(), FatalException, fXSTableElectron, fXSTablePositron, G4endl, G4Exception(), G4ParticleDefinition::GetParticleName(), and G4Positron::Positron().

Referenced by G4PenelopeIonisationModel::ComputeDEDXPerVolume(), G4PenelopeIonisationCrossSection::CrossSection(), G4PenelopeIonisationModel::CrossSectionPerVolume(), G4PenelopeIonisationModel::SampleFinalStateElectron(), and G4PenelopeIonisationModel::SampleFinalStatePositron().

◆ GetDensityCorrection()

G4double G4PenelopeIonisationXSHandler::GetDensityCorrection ( const G4Material mat,
const G4double  energy 
) const

Returns the density coeection for the material at the given energy.

Definition at line 284 of file G4PenelopeIonisationXSHandler.cc.

286{
287 G4double result = 0;
288 if (!fDeltaTable)
289 {
290 G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
291 "em2032",FatalException,
292 "Delta Table not initialized. Was Initialise() run?");
293 return 0;
294 }
295 if (energy <= 0*eV)
296 {
297 G4cout << "G4PenelopeIonisationXSHandler::GetDensityCorrection()" << G4endl;
298 G4cout << "Invalid energy " << energy/eV << " eV " << G4endl;
299 return 0;
300 }
301 G4double logene = G4Log(energy);
302
303 if (fDeltaTable->count(mat))
304 {
305 const G4PhysicsFreeVector* vec = fDeltaTable->find(mat)->second;
306 result = vec->Value(logene); //the table has delta vs. ln(E)
307 }
308 else
309 {
311 ed << "Unable to build table for " << mat->GetName() << G4endl;
312 G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
313 "em2033",FatalException,ed);
314 }
315
316 return result;
317}
G4double Value(const G4double energy, std::size_t &lastidx) const

References G4INCL::KinematicsUtils::energy(), eV, FatalException, fDeltaTable, G4cout, G4endl, G4Exception(), G4Log(), G4Material::GetName(), and G4PhysicsVector::Value().

Referenced by BuildXSTable(), G4PenelopeIonisationModel::SampleFinalStateElectron(), and G4PenelopeIonisationModel::SampleFinalStatePositron().

◆ operator=()

G4PenelopeIonisationXSHandler & G4PenelopeIonisationXSHandler::operator= ( const G4PenelopeIonisationXSHandler right)
delete

◆ SetVerboseLevel()

void G4PenelopeIonisationXSHandler::SetVerboseLevel ( G4int  vl)
inline

Setter for the verbosity level.

Definition at line 77 of file G4PenelopeIonisationXSHandler.hh.

77{fVerboseLevel = vl;};

References fVerboseLevel.

Referenced by G4PenelopeIonisationModel::Initialise().

Field Documentation

◆ fDeltaTable

std::map<const G4Material*,G4PhysicsFreeVector*>* G4PenelopeIonisationXSHandler::fDeltaTable
private

◆ fEnergyGrid

G4PhysicsLogVector* G4PenelopeIonisationXSHandler::fEnergyGrid
private

◆ fNBins

size_t G4PenelopeIonisationXSHandler::fNBins
private

◆ fOscManager

G4PenelopeOscillatorManager* G4PenelopeIonisationXSHandler::fOscManager
private

◆ fVerboseLevel

G4int G4PenelopeIonisationXSHandler::fVerboseLevel
private

◆ fXSTableElectron

std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>* G4PenelopeIonisationXSHandler::fXSTableElectron
private

◆ fXSTablePositron

std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>* G4PenelopeIonisationXSHandler::fXSTablePositron
private

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