Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4IonParametrisedLossModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// ===========================================================================
28// GEANT4 class source file
29//
30// Class: G4IonParametrisedLossModel
31//
32// Base class: G4VEmModel (utils)
33//
34// Author: Anton Lechner (Anton.Lechner@cern.ch)
35//
36// First implementation: 10. 11. 2008
37//
38// Modifications: 03. 02. 2009 - Bug fix iterators (AL)
39// 11. 03. 2009 - Introduced new table handler(G4IonDEDXHandler)
40// and modified method to add/remove tables
41// (tables are now built in init. phase),
42// Minor bug fix in ComputeDEDXPerVolume (AL)
43// 11. 05. 2009 - Introduced scaling algorithm for heavier ions:
44// G4IonDEDXScalingICRU73 (AL)
45// 12. 11. 2009 - Moved from original ICRU 73 classes to new
46// class (G4IonStoppingData), which is capable
47// of reading stopping power data files stored
48// in G4LEDATA (requires G4EMLOW6.8 or higher).
49// Simultanesouly, the upper energy limit of
50// ICRU 73 is increased to 1 GeV/nucleon.
51// - Removed nuclear stopping from Corrections-
52// AlongStep since dedicated process was created.
53// - Added function for switching off scaling
54// of heavy ions from ICRU 73 data
55// - Minor fix in ComputeLossForStep function
56// - Minor fix in ComputeDEDXPerVolume (AL)
57// 23. 11. 2009 - Changed energy loss limit from 0.15 to 0.01
58// to improve accuracy for large steps (AL)
59// 24. 11. 2009 - Bug fix: Range calculation corrected if same
60// materials appears with different cuts in diff.
61// regions (added UpdateRangeCache function and
62// modified BuildRangeVector, ComputeLossForStep
63// functions accordingly, added new cache param.)
64// - Removed GetRange function (AL)
65// 04. 11. 2010 - Moved virtual methods to the source (VI)
66//
67//
68// Class description:
69// Model for computing the energy loss of ions by employing a
70// parameterisation of dE/dx tables (by default ICRU 73 tables). For
71// ion-material combinations and/or projectile energies not covered
72// by this model, the G4BraggIonModel and G4BetheBloch models are
73// employed.
74//
75// Comments:
76//
77// ===========================================================================
80#include "G4SystemOfUnits.hh"
82#include "G4IonStoppingData.hh"
83#include "G4VIonDEDXTable.hh"
86#include "G4BraggIonModel.hh"
87#include "G4BetheBlochModel.hh"
90#include "G4LossTableManager.hh"
91#include "G4EmParameters.hh"
92#include "G4GenericIon.hh"
93#include "G4Electron.hh"
94#include "G4DeltaAngle.hh"
95#include "Randomize.hh"
96#include "G4Exp.hh"
97
98//#define PRINT_TABLE_BUILT
99// #########################################################################
100
103 const G4String& nam)
104 : G4VEmModel(nam),
105 braggIonModel(0),
106 betheBlochModel(0),
107 nmbBins(90),
108 nmbSubBins(100),
109 particleChangeLoss(0),
110 corrFactor(1.0),
111 energyLossLimit(0.01),
112 cutEnergies(0),
113 isInitialised(false)
114{
115 genericIon = G4GenericIon::Definition();
116 genericIonPDGMass = genericIon->GetPDGMass();
118
119 // The Bragg ion and Bethe Bloch models are instantiated
120 braggIonModel = new G4BraggIonModel();
121 betheBlochModel = new G4BetheBlochModel();
122
123 // The boundaries for the range tables are set
124 lowerEnergyEdgeIntegr = 0.025 * MeV;
125 upperEnergyEdgeIntegr = betheBlochModel -> HighEnergyLimit();
126
127 // Cache parameters are set
128 cacheParticle = 0;
129 cacheMass = 0;
130 cacheElecMassRatio = 0;
131 cacheChargeSquare = 0;
132
133 // Cache parameters are set
134 rangeCacheParticle = 0;
135 rangeCacheMatCutsCouple = 0;
136 rangeCacheEnergyRange = 0;
137 rangeCacheRangeEnergy = 0;
138
139 // Cache parameters are set
140 dedxCacheParticle = 0;
141 dedxCacheMaterial = 0;
142 dedxCacheEnergyCut = 0;
143 dedxCacheIter = lossTableList.end();
144 dedxCacheTransitionEnergy = 0.0;
145 dedxCacheTransitionFactor = 0.0;
146 dedxCacheGenIonMassRatio = 0.0;
147
148 // default generator
150}
151
152// #########################################################################
153
155
156 // dE/dx table objects are deleted and the container is cleared
157 LossTableList::iterator iterTables = lossTableList.begin();
158 LossTableList::iterator iterTables_end = lossTableList.end();
159
160 for(;iterTables != iterTables_end; ++iterTables) { delete *iterTables; }
161 lossTableList.clear();
162
163 // range table
164 RangeEnergyTable::iterator itr = r.begin();
165 RangeEnergyTable::iterator itr_end = r.end();
166 for(;itr != itr_end; ++itr) { delete itr->second; }
167 r.clear();
168
169 // inverse range
170 EnergyRangeTable::iterator ite = E.begin();
171 EnergyRangeTable::iterator ite_end = E.end();
172 for(;ite != ite_end; ++ite) { delete ite->second; }
173 E.clear();
174
175}
176
177// #########################################################################
178
181 const G4MaterialCutsCouple* couple) {
182
184}
185
186// #########################################################################
187
189 const G4ParticleDefinition* particle,
190 G4double kineticEnergy) {
191
192 // ############## Maximum energy of secondaries ##########################
193 // Function computes maximum energy of secondary electrons which are
194 // released by an ion
195 //
196 // See Geant4 physics reference manual (version 9.1), section 9.1.1
197 //
198 // Ref.: W.M. Yao et al, Jour. of Phys. G 33 (2006) 1.
199 // C.Caso et al. (Part. Data Group), Europ. Phys. Jour. C 3 1 (1998).
200 // B. Rossi, High energy particles, New York, NY: Prentice-Hall (1952).
201 //
202 // (Implementation adapted from G4BraggIonModel)
203
204 if(particle != cacheParticle) UpdateCache(particle);
205
206 G4double tau = kineticEnergy/cacheMass;
207 G4double tmax = 2.0 * electron_mass_c2 * tau * (tau + 2.) /
208 (1. + 2.0 * (tau + 1.) * cacheElecMassRatio +
209 cacheElecMassRatio * cacheElecMassRatio);
210
211 return tmax;
212}
213
214// #########################################################################
215
217 const G4ParticleDefinition* particle,
218 const G4Material* material,
219 G4double kineticEnergy) { // Kinetic energy
220
221 G4double chargeSquareRatio = corrections ->
222 EffectiveChargeSquareRatio(particle,
223 material,
224 kineticEnergy);
225 corrFactor = chargeSquareRatio *
226 corrections -> EffectiveChargeCorrection(particle,
227 material,
228 kineticEnergy);
229 return corrFactor;
230}
231
232// #########################################################################
233
235 const G4ParticleDefinition* particle,
236 const G4Material* material,
237 G4double kineticEnergy) { // Kinetic energy
238
239 return corrections -> GetParticleCharge(particle, material, kineticEnergy);
240}
241
242// #########################################################################
243
245 const G4ParticleDefinition* particle,
246 const G4DataVector& cuts) {
247
248 // Cached parameters are reset
249 cacheParticle = 0;
250 cacheMass = 0;
251 cacheElecMassRatio = 0;
252 cacheChargeSquare = 0;
253
254 // Cached parameters are reset
255 rangeCacheParticle = 0;
256 rangeCacheMatCutsCouple = 0;
257 rangeCacheEnergyRange = 0;
258 rangeCacheRangeEnergy = 0;
259
260 // Cached parameters are reset
261 dedxCacheParticle = 0;
262 dedxCacheMaterial = 0;
263 dedxCacheEnergyCut = 0;
264 dedxCacheIter = lossTableList.end();
265 dedxCacheTransitionEnergy = 0.0;
266 dedxCacheTransitionFactor = 0.0;
267 dedxCacheGenIonMassRatio = 0.0;
268
269 // By default ICRU 73 stopping power tables are loaded:
270 if(!isInitialised) {
272 isInitialised = true;
273 AddDEDXTable("ICRU73",
274 new G4IonStoppingData("ion_stopping_data/icru",icru90),
276 }
277 // The cache of loss tables is cleared
278 LossTableList::iterator iterTables = lossTableList.begin();
279 LossTableList::iterator iterTables_end = lossTableList.end();
280
281 for(;iterTables != iterTables_end; ++iterTables) {
282 (*iterTables) -> ClearCache();
283 }
284
285 // Range vs energy and energy vs range vectors from previous runs are
286 // cleared
287 RangeEnergyTable::iterator iterRange = r.begin();
288 RangeEnergyTable::iterator iterRange_end = r.end();
289
290 for(;iterRange != iterRange_end; ++iterRange) {
291 delete iterRange->second;
292 }
293 r.clear();
294
295 EnergyRangeTable::iterator iterEnergy = E.begin();
296 EnergyRangeTable::iterator iterEnergy_end = E.end();
297
298 for(;iterEnergy != iterEnergy_end; ++iterEnergy) {
299 delete iterEnergy->second;
300 }
301 E.clear();
302
303 // The cut energies
304 cutEnergies = cuts;
305
306 // All dE/dx vectors are built
307 const G4ProductionCutsTable* coupleTable=
309 G4int nmbCouples = (G4int)coupleTable->GetTableSize();
310
311#ifdef PRINT_TABLE_BUILT
312 G4cout << "G4IonParametrisedLossModel::Initialise():"
313 << " Building dE/dx vectors:"
314 << G4endl;
315#endif
316
317 for (G4int i = 0; i < nmbCouples; ++i) {
318
319 const G4MaterialCutsCouple* couple = coupleTable->GetMaterialCutsCouple(i);
320 const G4Material* material = couple->GetMaterial();
321
322 for(G4int atomicNumberIon = 3; atomicNumberIon < 102; ++atomicNumberIon) {
323
324 LossTableList::iterator iter = lossTableList.begin();
325 LossTableList::iterator iter_end = lossTableList.end();
326
327 for(;iter != iter_end; ++iter) {
328
329 if(*iter == 0) {
330 G4cout << "G4IonParametrisedLossModel::Initialise():"
331 << " Skipping illegal table."
332 << G4endl;
333 }
334
335 if((*iter)->BuildDEDXTable(atomicNumberIon, material)) {
336
337#ifdef PRINT_TABLE_BUILT
338 G4cout << " Atomic Number Ion = " << atomicNumberIon
339 << ", Material = " << material -> GetName()
340 << ", Table = " << (*iter) -> GetName()
341 << G4endl;
342#endif
343 break;
344 }
345 }
346 }
347 }
348
349 // The particle change object
350 if(! particleChangeLoss) {
351 particleChangeLoss = GetParticleChangeForLoss();
352 braggIonModel->SetParticleChange(particleChangeLoss, 0);
353 betheBlochModel->SetParticleChange(particleChangeLoss, 0);
354 }
355
356 // The G4BraggIonModel and G4BetheBlochModel instances are initialised with
357 // the same settings as the current model:
358 braggIonModel -> Initialise(particle, cuts);
359 betheBlochModel -> Initialise(particle, cuts);
360}
361
362// #########################################################################
363
365 const G4ParticleDefinition* particle,
366 G4double kineticEnergy,
367 G4double atomicNumber,
368 G4double,
369 G4double cutEnergy,
370 G4double maxKinEnergy) {
371
372 // ############## Cross section per atom ################################
373 // Function computes ionization cross section per atom
374 //
375 // See Geant4 physics reference manual (version 9.1), section 9.1.3
376 //
377 // Ref.: W.M. Yao et al, Jour. of Phys. G 33 (2006) 1.
378 // B. Rossi, High energy particles, New York, NY: Prentice-Hall (1952).
379 //
380 // (Implementation adapted from G4BraggIonModel)
381
382 G4double crosssection = 0.0;
383 G4double tmax = MaxSecondaryEnergy(particle, kineticEnergy);
384 G4double maxEnergy = std::min(tmax, maxKinEnergy);
385
386 if(cutEnergy < tmax) {
387
388 G4double energy = kineticEnergy + cacheMass;
389 G4double betaSquared = kineticEnergy *
390 (energy + cacheMass) / (energy * energy);
391
392 crosssection = 1.0 / cutEnergy - 1.0 / maxEnergy -
393 betaSquared * std::log(maxEnergy / cutEnergy) / tmax;
394
395 crosssection *= twopi_mc2_rcl2 * cacheChargeSquare / betaSquared;
396 }
397
398#ifdef PRINT_DEBUG_CS
399 G4cout << "########################################################"
400 << G4endl
401 << "# G4IonParametrisedLossModel::ComputeCrossSectionPerAtom"
402 << G4endl
403 << "# particle =" << particle -> GetParticleName()
404 << G4endl
405 << "# cut(MeV) = " << cutEnergy/MeV
406 << G4endl;
407
408 G4cout << "#"
409 << std::setw(13) << std::right << "E(MeV)"
410 << std::setw(14) << "CS(um)"
411 << std::setw(14) << "E_max_sec(MeV)"
412 << G4endl
413 << "# ------------------------------------------------------"
414 << G4endl;
415
416 G4cout << std::setw(14) << std::right << kineticEnergy / MeV
417 << std::setw(14) << crosssection / (um * um)
418 << std::setw(14) << tmax / MeV
419 << G4endl;
420#endif
421
422 crosssection *= atomicNumber;
423
424 return crosssection;
425}
426
427// #########################################################################
428
430 const G4Material* material,
431 const G4ParticleDefinition* particle,
432 G4double kineticEnergy,
433 G4double cutEnergy,
434 G4double maxEnergy) {
435
436 G4double nbElecPerVolume = material -> GetTotNbOfElectPerVolume();
437 G4double cross = ComputeCrossSectionPerAtom(particle,
438 kineticEnergy,
439 nbElecPerVolume, 0,
440 cutEnergy,
441 maxEnergy);
442
443 return cross;
444}
445
446// #########################################################################
447
449 const G4Material* material,
450 const G4ParticleDefinition* particle,
451 G4double kineticEnergy,
452 G4double cutEnergy) {
453
454 // ############## dE/dx ##################################################
455 // Function computes dE/dx values, where following rules are adopted:
456 // A. If the ion-material pair is covered by any native ion data
457 // parameterisation, then:
458 // * This parameterization is used for energies below a given energy
459 // limit,
460 // * whereas above the limit the Bethe-Bloch model is applied, in
461 // combination with an effective charge estimate and high order
462 // correction terms.
463 // A smoothing procedure is applied to dE/dx values computed with
464 // the second approach. The smoothing factor is based on the dE/dx
465 // values of both approaches at the transition energy (high order
466 // correction terms are included in the calculation of the transition
467 // factor).
468 // B. If the particle is a generic ion, the BraggIon and Bethe-Bloch
469 // models are used and a smoothing procedure is applied to values
470 // obtained with the second approach.
471 // C. If the ion-material is not covered by any ion data parameterization
472 // then:
473 // * The BraggIon model is used for energies below a given energy
474 // limit,
475 // * whereas above the limit the Bethe-Bloch model is applied, in
476 // combination with an effective charge estimate and high order
477 // correction terms.
478 // Also in this case, a smoothing procedure is applied to dE/dx values
479 // computed with the second model.
480
481 G4double dEdx = 0.0;
482 UpdateDEDXCache(particle, material, cutEnergy);
483
484 LossTableList::iterator iter = dedxCacheIter;
485
486 if(iter != lossTableList.end()) {
487
488 G4double transitionEnergy = dedxCacheTransitionEnergy;
489
490 if(transitionEnergy > kineticEnergy) {
491
492 dEdx = (*iter) -> GetDEDX(particle, material, kineticEnergy);
493
494 G4double dEdxDeltaRays = DeltaRayMeanEnergyTransferRate(material,
495 particle,
496 kineticEnergy,
497 cutEnergy);
498 dEdx -= dEdxDeltaRays;
499 }
500 else {
501 G4double massRatio = dedxCacheGenIonMassRatio;
502
503 G4double chargeSquare =
504 GetChargeSquareRatio(particle, material, kineticEnergy);
505
506 G4double scaledKineticEnergy = kineticEnergy * massRatio;
507 G4double scaledTransitionEnergy = transitionEnergy * massRatio;
508
509 G4double lowEnergyLimit = betheBlochModel -> LowEnergyLimit();
510
511 if(scaledTransitionEnergy >= lowEnergyLimit) {
512
513 dEdx = betheBlochModel -> ComputeDEDXPerVolume(
514 material, genericIon,
515 scaledKineticEnergy, cutEnergy);
516
517 dEdx *= chargeSquare;
518
519 dEdx += corrections -> ComputeIonCorrections(particle,
520 material, kineticEnergy);
521
522 G4double factor = 1.0 + dedxCacheTransitionFactor /
523 kineticEnergy;
524
525 dEdx *= factor;
526 }
527 }
528 }
529 else {
530 G4double massRatio = 1.0;
531 G4double chargeSquare = 1.0;
532
533 if(particle != genericIon) {
534
535 chargeSquare = GetChargeSquareRatio(particle, material, kineticEnergy);
536 massRatio = genericIonPDGMass / particle -> GetPDGMass();
537 }
538
539 G4double scaledKineticEnergy = kineticEnergy * massRatio;
540
541 G4double lowEnergyLimit = betheBlochModel -> LowEnergyLimit();
542 if(scaledKineticEnergy < lowEnergyLimit) {
543 dEdx = braggIonModel -> ComputeDEDXPerVolume(
544 material, genericIon,
545 scaledKineticEnergy, cutEnergy);
546
547 dEdx *= chargeSquare;
548 }
549 else {
550 G4double dEdxLimitParam = braggIonModel -> ComputeDEDXPerVolume(
551 material, genericIon,
552 lowEnergyLimit, cutEnergy);
553
554 G4double dEdxLimitBetheBloch = betheBlochModel -> ComputeDEDXPerVolume(
555 material, genericIon,
556 lowEnergyLimit, cutEnergy);
557
558 if(particle != genericIon) {
559 G4double chargeSquareLowEnergyLimit =
560 GetChargeSquareRatio(particle, material,
561 lowEnergyLimit / massRatio);
562
563 dEdxLimitParam *= chargeSquareLowEnergyLimit;
564 dEdxLimitBetheBloch *= chargeSquareLowEnergyLimit;
565
566 dEdxLimitBetheBloch +=
567 corrections -> ComputeIonCorrections(particle,
568 material, lowEnergyLimit / massRatio);
569 }
570
571 G4double factor = (1.0 + (dEdxLimitParam/dEdxLimitBetheBloch - 1.0)
572 * lowEnergyLimit / scaledKineticEnergy);
573
574 dEdx = betheBlochModel -> ComputeDEDXPerVolume(
575 material, genericIon,
576 scaledKineticEnergy, cutEnergy);
577
578 dEdx *= chargeSquare;
579
580 if(particle != genericIon) {
581 dEdx += corrections -> ComputeIonCorrections(particle,
582 material, kineticEnergy);
583 }
584
585 dEdx *= factor;
586 }
587
588 }
589
590 if (dEdx < 0.0) dEdx = 0.0;
591
592 return dEdx;
593}
594
595// #########################################################################
596
598 const G4ParticleDefinition* particle, // Projectile (ion)
599 const G4Material* material, // Absorber material
600 G4double lowerBoundary, // Minimum energy per nucleon
601 G4double upperBoundary, // Maximum energy per nucleon
602 G4int numBins, // Number of bins
603 G4bool logScaleEnergy) { // Logarithmic scaling of energy
604
605 G4double atomicMassNumber = particle -> GetAtomicMass();
606 G4double materialDensity = material -> GetDensity();
607
608 G4cout << "# dE/dx table for " << particle -> GetParticleName()
609 << " in material " << material -> GetName()
610 << " of density " << materialDensity / g * cm3
611 << " g/cm3"
612 << G4endl
613 << "# Projectile mass number A1 = " << atomicMassNumber
614 << G4endl
615 << "# ------------------------------------------------------"
616 << G4endl;
617 G4cout << "#"
618 << std::setw(13) << std::right << "E"
619 << std::setw(14) << "E/A1"
620 << std::setw(14) << "dE/dx"
621 << std::setw(14) << "1/rho*dE/dx"
622 << G4endl;
623 G4cout << "#"
624 << std::setw(13) << std::right << "(MeV)"
625 << std::setw(14) << "(MeV)"
626 << std::setw(14) << "(MeV/cm)"
627 << std::setw(14) << "(MeV*cm2/mg)"
628 << G4endl
629 << "# ------------------------------------------------------"
630 << G4endl;
631
632 G4double energyLowerBoundary = lowerBoundary * atomicMassNumber;
633 G4double energyUpperBoundary = upperBoundary * atomicMassNumber;
634
635 if(logScaleEnergy) {
636
637 energyLowerBoundary = std::log(energyLowerBoundary);
638 energyUpperBoundary = std::log(energyUpperBoundary);
639 }
640
641 G4double deltaEnergy = (energyUpperBoundary - energyLowerBoundary) /
642 G4double(nmbBins);
643
644 for(int i = 0; i < numBins + 1; i++) {
645
646 G4double energy = energyLowerBoundary + i * deltaEnergy;
647 if(logScaleEnergy) energy = G4Exp(energy);
648
649 G4double dedx = ComputeDEDXPerVolume(material, particle, energy, DBL_MAX);
650 G4cout.precision(6);
651 G4cout << std::setw(14) << std::right << energy / MeV
652 << std::setw(14) << energy / atomicMassNumber / MeV
653 << std::setw(14) << dedx / MeV * cm
654 << std::setw(14) << dedx / materialDensity / (MeV*cm2/(0.001*g))
655 << G4endl;
656 }
657}
658
659// #########################################################################
660
662 const G4ParticleDefinition* particle, // Projectile (ion)
663 const G4Material* material, // Absorber material
664 G4double lowerBoundary, // Minimum energy per nucleon
665 G4double upperBoundary, // Maximum energy per nucleon
666 G4int numBins, // Number of bins
667 G4bool logScaleEnergy) { // Logarithmic scaling of energy
668
669 LossTableList::iterator iter = lossTableList.begin();
670 LossTableList::iterator iter_end = lossTableList.end();
671
672 for(;iter != iter_end; iter++) {
673 G4bool isApplicable = (*iter) -> IsApplicable(particle, material);
674 if(isApplicable) {
675 (*iter) -> PrintDEDXTable(particle, material,
676 lowerBoundary, upperBoundary,
677 numBins,logScaleEnergy);
678 break;
679 }
680 }
681}
682
683// #########################################################################
684
686 std::vector<G4DynamicParticle*>* secondaries,
687 const G4MaterialCutsCouple* couple,
688 const G4DynamicParticle* particle,
689 G4double cutKinEnergySec,
690 G4double userMaxKinEnergySec) {
691 // ############## Sampling of secondaries #################################
692 // The probability density function (pdf) of the kinetic energy T of a
693 // secondary electron may be written as:
694 // pdf(T) = f(T) * g(T)
695 // where
696 // f(T) = (Tmax - Tcut) / (Tmax * Tcut) * (1 / T^2)
697 // g(T) = 1 - beta^2 * T / Tmax
698 // where Tmax is the maximum kinetic energy of the secondary, Tcut
699 // is the lower energy cut and beta is the kinetic energy of the
700 // projectile.
701 //
702 // Sampling of the kinetic energy of a secondary electron:
703 // 1) T0 is sampled from f(T) using the cumulated distribution function
704 // F(T) = int_Tcut^T f(T')dT'
705 // 2) T is accepted or rejected by evaluating the rejection function g(T)
706 // at the sampled energy T0 against a randomly sampled value
707 //
708 //
709 // See Geant4 physics reference manual (version 9.1), section 9.1.4
710 //
711 //
712 // Reference pdf: W.M. Yao et al, Jour. of Phys. G 33 (2006) 1.
713 //
714 // (Implementation adapted from G4BraggIonModel)
715
716 G4double rossiMaxKinEnergySec = MaxSecondaryKinEnergy(particle);
717 G4double maxKinEnergySec =
718 std::min(rossiMaxKinEnergySec, userMaxKinEnergySec);
719
720 if(cutKinEnergySec >= maxKinEnergySec) return;
721
722 G4double kineticEnergy = particle -> GetKineticEnergy();
723
724 G4double energy = kineticEnergy + cacheMass;
725 G4double betaSquared = kineticEnergy * (energy + cacheMass)
726 / (energy * energy);
727
728 G4double kinEnergySec;
729 G4double grej;
730
731 do {
732
733 // Sampling kinetic energy from f(T) (using F(T)):
734 G4double xi = G4UniformRand();
735 kinEnergySec = cutKinEnergySec * maxKinEnergySec /
736 (maxKinEnergySec * (1.0 - xi) + cutKinEnergySec * xi);
737
738 // Deriving the value of the rejection function at the obtained kinetic
739 // energy:
740 grej = 1.0 - betaSquared * kinEnergySec / rossiMaxKinEnergySec;
741
742 if(grej > 1.0) {
743 G4cout << "G4IonParametrisedLossModel::SampleSecondary Warning: "
744 << "Majorant 1.0 < "
745 << grej << " for e= " << kinEnergySec
746 << G4endl;
747 }
748
749 } while( G4UniformRand() >= grej );
750
751 const G4Material* mat = couple->GetMaterial();
753
754 const G4ParticleDefinition* electron = G4Electron::Electron();
755
756 G4DynamicParticle* delta = new G4DynamicParticle(electron,
757 GetAngularDistribution()->SampleDirection(particle, kinEnergySec,
758 Z, mat),
759 kinEnergySec);
760
761 secondaries->push_back(delta);
762
763 // Change kinematics of primary particle
764 G4ThreeVector direction = particle ->GetMomentumDirection();
765 G4double totalMomentum = std::sqrt(kineticEnergy*(energy + cacheMass));
766
767 G4ThreeVector finalP = totalMomentum*direction - delta->GetMomentum();
768 finalP = finalP.unit();
769
770 kineticEnergy -= kinEnergySec;
771
772 particleChangeLoss->SetProposedKineticEnergy(kineticEnergy);
773 particleChangeLoss->SetProposedMomentumDirection(finalP);
774}
775
776// #########################################################################
777
778void G4IonParametrisedLossModel::UpdateRangeCache(
779 const G4ParticleDefinition* particle,
780 const G4MaterialCutsCouple* matCutsCouple) {
781
782 // ############## Caching ##################################################
783 // If the ion-material-cut combination is covered by any native ion data
784 // parameterisation (for low energies), range vectors are computed
785
786 if(particle == rangeCacheParticle &&
787 matCutsCouple == rangeCacheMatCutsCouple) {
788 }
789 else{
790 rangeCacheParticle = particle;
791 rangeCacheMatCutsCouple = matCutsCouple;
792
793 const G4Material* material = matCutsCouple -> GetMaterial();
794 LossTableList::iterator iter = IsApplicable(particle, material);
795
796 // If any table is applicable, the transition factor is computed:
797 if(iter != lossTableList.end()) {
798
799 // Build range-energy and energy-range vectors if they don't exist
800 IonMatCouple ionMatCouple = std::make_pair(particle, matCutsCouple);
801 RangeEnergyTable::iterator iterRange = r.find(ionMatCouple);
802
803 if(iterRange == r.end()) BuildRangeVector(particle, matCutsCouple);
804
805 rangeCacheEnergyRange = E[ionMatCouple];
806 rangeCacheRangeEnergy = r[ionMatCouple];
807 }
808 else {
809 rangeCacheEnergyRange = 0;
810 rangeCacheRangeEnergy = 0;
811 }
812 }
813}
814
815// #########################################################################
816
817void G4IonParametrisedLossModel::UpdateDEDXCache(
818 const G4ParticleDefinition* particle,
819 const G4Material* material,
820 G4double cutEnergy) {
821
822 // ############## Caching ##################################################
823 // If the ion-material combination is covered by any native ion data
824 // parameterisation (for low energies), a transition factor is computed
825 // which is applied to Bethe-Bloch results at higher energies to
826 // guarantee a smooth transition.
827 // This factor only needs to be calculated for the first step an ion
828 // performs inside a certain material.
829
830 if(particle == dedxCacheParticle &&
831 material == dedxCacheMaterial &&
832 cutEnergy == dedxCacheEnergyCut) {
833 }
834 else {
835
836 dedxCacheParticle = particle;
837 dedxCacheMaterial = material;
838 dedxCacheEnergyCut = cutEnergy;
839
840 G4double massRatio = genericIonPDGMass / particle -> GetPDGMass();
841 dedxCacheGenIonMassRatio = massRatio;
842
843 LossTableList::iterator iter = IsApplicable(particle, material);
844 dedxCacheIter = iter;
845
846 // If any table is applicable, the transition factor is computed:
847 if(iter != lossTableList.end()) {
848
849 // Retrieving the transition energy from the parameterisation table
850 G4double transitionEnergy =
851 (*iter) -> GetUpperEnergyEdge(particle, material);
852 dedxCacheTransitionEnergy = transitionEnergy;
853
854 // Computing dE/dx from low-energy parameterisation at
855 // transition energy
856 G4double dEdxParam = (*iter) -> GetDEDX(particle, material,
857 transitionEnergy);
858
859 G4double dEdxDeltaRays = DeltaRayMeanEnergyTransferRate(material,
860 particle,
861 transitionEnergy,
862 cutEnergy);
863 dEdxParam -= dEdxDeltaRays;
864
865 // Computing dE/dx from Bethe-Bloch formula at transition
866 // energy
867 G4double transitionChargeSquare =
868 GetChargeSquareRatio(particle, material, transitionEnergy);
869
870 G4double scaledTransitionEnergy = transitionEnergy * massRatio;
871
872 G4double dEdxBetheBloch =
873 betheBlochModel -> ComputeDEDXPerVolume(
874 material, genericIon,
875 scaledTransitionEnergy, cutEnergy);
876 dEdxBetheBloch *= transitionChargeSquare;
877
878 // Additionally, high order corrections are added
879 dEdxBetheBloch +=
880 corrections -> ComputeIonCorrections(particle,
881 material, transitionEnergy);
882
883 // Computing transition factor from both dE/dx values
884 dedxCacheTransitionFactor =
885 (dEdxParam - dEdxBetheBloch)/dEdxBetheBloch
886 * transitionEnergy;
887 }
888 else {
889
890 dedxCacheParticle = particle;
891 dedxCacheMaterial = material;
892 dedxCacheEnergyCut = cutEnergy;
893
894 dedxCacheGenIonMassRatio =
895 genericIonPDGMass / particle -> GetPDGMass();
896
897 dedxCacheTransitionEnergy = 0.0;
898 dedxCacheTransitionFactor = 0.0;
899 }
900 }
901}
902
903// #########################################################################
904
906 const G4MaterialCutsCouple* couple,
907 const G4DynamicParticle* dynamicParticle,
908 const G4double& length,
909 G4double& eloss) {
910
911 // ############## Corrections for along step energy loss calculation ######
912 // The computed energy loss (due to electronic stopping) is overwritten
913 // by this function if an ion data parameterization is available for the
914 // current ion-material pair.
915 // No action on the energy loss (due to electronic stopping) is performed
916 // if no parameterization is available. In this case the original
917 // generic ion tables (in combination with the effective charge) are used
918 // in the along step DoIt function.
919 //
920 //
921 // (Implementation partly adapted from G4BraggIonModel/G4BetheBlochModel)
922
923 const G4ParticleDefinition* particle = dynamicParticle -> GetDefinition();
924 const G4Material* material = couple -> GetMaterial();
925
926 G4double kineticEnergy = dynamicParticle -> GetKineticEnergy();
927
928 if(kineticEnergy == eloss) { return; }
929
930 G4double cutEnergy = DBL_MAX;
931 std::size_t cutIndex = couple -> GetIndex();
932 cutEnergy = cutEnergies[cutIndex];
933
934 UpdateDEDXCache(particle, material, cutEnergy);
935
936 LossTableList::iterator iter = dedxCacheIter;
937
938 // If parameterization for ions is available the electronic energy loss
939 // is overwritten
940 if(iter != lossTableList.end()) {
941
942 // The energy loss is calculated using the ComputeDEDXPerVolume function
943 // and the step length (it is assumed that dE/dx does not change
944 // considerably along the step)
945 eloss =
946 length * ComputeDEDXPerVolume(material, particle,
947 kineticEnergy, cutEnergy);
948
949#ifdef PRINT_DEBUG
950 G4cout.precision(6);
951 G4cout << "########################################################"
952 << G4endl
953 << "# G4IonParametrisedLossModel::CorrectionsAlongStep"
954 << G4endl
955 << "# cut(MeV) = " << cutEnergy/MeV
956 << G4endl;
957
958 G4cout << "#"
959 << std::setw(13) << std::right << "E(MeV)"
960 << std::setw(14) << "l(um)"
961 << std::setw(14) << "l*dE/dx(MeV)"
962 << std::setw(14) << "(l*dE/dx)/E"
963 << G4endl
964 << "# ------------------------------------------------------"
965 << G4endl;
966
967 G4cout << std::setw(14) << std::right << kineticEnergy / MeV
968 << std::setw(14) << length / um
969 << std::setw(14) << eloss / MeV
970 << std::setw(14) << eloss / kineticEnergy * 100.0
971 << G4endl;
972#endif
973
974 // If the energy loss exceeds a certain fraction of the kinetic energy
975 // (the fraction is indicated by the parameter "energyLossLimit") then
976 // the range tables are used to derive a more accurate value of the
977 // energy loss
978 if(eloss > energyLossLimit * kineticEnergy) {
979
980 eloss = ComputeLossForStep(couple, particle,
981 kineticEnergy,length);
982
983#ifdef PRINT_DEBUG
984 G4cout << "# Correction applied:"
985 << G4endl;
986
987 G4cout << std::setw(14) << std::right << kineticEnergy / MeV
988 << std::setw(14) << length / um
989 << std::setw(14) << eloss / MeV
990 << std::setw(14) << eloss / kineticEnergy * 100.0
991 << G4endl;
992#endif
993
994 }
995 }
996
997 // For all corrections below a kinetic energy between the Pre- and
998 // Post-step energy values is used
999 G4double energy = kineticEnergy - eloss * 0.5;
1000 if(energy < 0.0) energy = kineticEnergy * 0.5;
1001
1002 G4double chargeSquareRatio = corrections ->
1003 EffectiveChargeSquareRatio(particle,
1004 material,
1005 energy);
1006 GetModelOfFluctuations() -> SetParticleAndCharge(particle,
1007 chargeSquareRatio);
1008
1009 // A correction is applied considering the change of the effective charge
1010 // along the step (the parameter "corrFactor" refers to the effective
1011 // charge at the beginning of the step). Note: the correction is not
1012 // applied for energy loss values deriving directly from parameterized
1013 // ion stopping power tables
1014 G4double transitionEnergy = dedxCacheTransitionEnergy;
1015
1016 if(iter != lossTableList.end() && transitionEnergy < kineticEnergy) {
1017 chargeSquareRatio *= corrections -> EffectiveChargeCorrection(particle,
1018 material,
1019 energy);
1020
1021 G4double chargeSquareRatioCorr = chargeSquareRatio/corrFactor;
1022 eloss *= chargeSquareRatioCorr;
1023 }
1024 else if (iter == lossTableList.end()) {
1025
1026 chargeSquareRatio *= corrections -> EffectiveChargeCorrection(particle,
1027 material,
1028 energy);
1029
1030 G4double chargeSquareRatioCorr = chargeSquareRatio/corrFactor;
1031 eloss *= chargeSquareRatioCorr;
1032 }
1033
1034 // Ion high order corrections are applied if the current model does not
1035 // overwrite the energy loss (i.e. when the effective charge approach is
1036 // used)
1037 if(iter == lossTableList.end()) {
1038
1039 G4double scaledKineticEnergy = kineticEnergy * dedxCacheGenIonMassRatio;
1040 G4double lowEnergyLimit = betheBlochModel -> LowEnergyLimit();
1041
1042 // Corrections are only applied in the Bethe-Bloch energy region
1043 if(scaledKineticEnergy > lowEnergyLimit)
1044 eloss += length *
1045 corrections -> IonHighOrderCorrections(particle, couple, energy);
1046 }
1047}
1048
1049// #########################################################################
1050
1051void G4IonParametrisedLossModel::BuildRangeVector(
1052 const G4ParticleDefinition* particle,
1053 const G4MaterialCutsCouple* matCutsCouple) {
1054
1055 G4double cutEnergy = DBL_MAX;
1056 std::size_t cutIndex = matCutsCouple -> GetIndex();
1057 cutEnergy = cutEnergies[cutIndex];
1058
1059 const G4Material* material = matCutsCouple -> GetMaterial();
1060
1061 G4double massRatio = genericIonPDGMass / particle -> GetPDGMass();
1062
1063 G4double lowerEnergy = lowerEnergyEdgeIntegr / massRatio;
1064 G4double upperEnergy = upperEnergyEdgeIntegr / massRatio;
1065
1066 G4double logLowerEnergyEdge = std::log(lowerEnergy);
1067 G4double logUpperEnergyEdge = std::log(upperEnergy);
1068
1069 G4double logDeltaEnergy = (logUpperEnergyEdge - logLowerEnergyEdge) /
1070 G4double(nmbBins);
1071
1072 G4double logDeltaIntegr = logDeltaEnergy / G4double(nmbSubBins);
1073
1074 G4PhysicsFreeVector* energyRangeVector =
1075 new G4PhysicsFreeVector(nmbBins+1,
1076 lowerEnergy,
1077 upperEnergy,
1078 /*spline=*/true);
1079
1080 G4double dedxLow = ComputeDEDXPerVolume(material,
1081 particle,
1082 lowerEnergy,
1083 cutEnergy);
1084
1085 G4double range = 2.0 * lowerEnergy / dedxLow;
1086
1087 energyRangeVector -> PutValues(0, lowerEnergy, range);
1088
1089 G4double logEnergy = std::log(lowerEnergy);
1090 for(std::size_t i = 1; i < nmbBins+1; ++i) {
1091
1092 G4double logEnergyIntegr = logEnergy;
1093
1094 for(std::size_t j = 0; j < nmbSubBins; ++j) {
1095
1096 G4double binLowerBoundary = G4Exp(logEnergyIntegr);
1097 logEnergyIntegr += logDeltaIntegr;
1098
1099 G4double binUpperBoundary = G4Exp(logEnergyIntegr);
1100 G4double deltaIntegr = binUpperBoundary - binLowerBoundary;
1101
1102 G4double energyIntegr = binLowerBoundary + 0.5 * deltaIntegr;
1103
1104 G4double dedxValue = ComputeDEDXPerVolume(material,
1105 particle,
1106 energyIntegr,
1107 cutEnergy);
1108
1109 if(dedxValue > 0.0) range += deltaIntegr / dedxValue;
1110
1111#ifdef PRINT_DEBUG_DETAILS
1112 G4cout << " E = "<< energyIntegr/MeV
1113 << " MeV -> dE = " << deltaIntegr/MeV
1114 << " MeV -> dE/dx = " << dedxValue/MeV*mm
1115 << " MeV/mm -> dE/(dE/dx) = " << deltaIntegr /
1116 dedxValue / mm
1117 << " mm -> range = " << range / mm
1118 << " mm " << G4endl;
1119#endif
1120 }
1121
1122 logEnergy += logDeltaEnergy;
1123
1124 G4double energy = G4Exp(logEnergy);
1125
1126 energyRangeVector -> PutValues(i, energy, range);
1127
1128#ifdef PRINT_DEBUG_DETAILS
1129 G4cout << "G4IonParametrisedLossModel::BuildRangeVector() bin = "
1130 << i <<", E = "
1131 << energy / MeV << " MeV, R = "
1132 << range / mm << " mm"
1133 << G4endl;
1134#endif
1135
1136 }
1137 //vector is filled: activate spline
1138 energyRangeVector -> FillSecondDerivatives();
1139
1140 G4double lowerRangeEdge =
1141 energyRangeVector -> Value(lowerEnergy);
1142 G4double upperRangeEdge =
1143 energyRangeVector -> Value(upperEnergy);
1144
1145 G4PhysicsFreeVector* rangeEnergyVector
1146 = new G4PhysicsFreeVector(nmbBins+1,
1147 lowerRangeEdge,
1148 upperRangeEdge,
1149 /*spline=*/true);
1150
1151 for(std::size_t i = 0; i < nmbBins+1; ++i) {
1152 G4double energy = energyRangeVector -> Energy(i);
1153 rangeEnergyVector ->
1154 PutValues(i, energyRangeVector -> Value(energy), energy);
1155 }
1156
1157 rangeEnergyVector -> FillSecondDerivatives();
1158
1159#ifdef PRINT_DEBUG_TABLES
1160 G4cout << *energyLossVector
1161 << *energyRangeVector
1162 << *rangeEnergyVector << G4endl;
1163#endif
1164
1165 IonMatCouple ionMatCouple = std::make_pair(particle, matCutsCouple);
1166
1167 E[ionMatCouple] = energyRangeVector;
1168 r[ionMatCouple] = rangeEnergyVector;
1169}
1170
1171// #########################################################################
1172
1174 const G4MaterialCutsCouple* matCutsCouple,
1175 const G4ParticleDefinition* particle,
1176 G4double kineticEnergy,
1177 G4double stepLength) {
1178
1179 G4double loss = 0.0;
1180
1181 UpdateRangeCache(particle, matCutsCouple);
1182
1183 G4PhysicsVector* energyRange = rangeCacheEnergyRange;
1184 G4PhysicsVector* rangeEnergy = rangeCacheRangeEnergy;
1185
1186 if(energyRange != 0 && rangeEnergy != 0) {
1187
1188 G4double lowerEnEdge = energyRange -> Energy( 0 );
1189 G4double lowerRangeEdge = rangeEnergy -> Energy( 0 );
1190
1191 // Computing range for pre-step kinetic energy:
1192 G4double range = energyRange -> Value(kineticEnergy);
1193
1194 // Energy below vector boundary:
1195 if(kineticEnergy < lowerEnEdge) {
1196
1197 range = energyRange -> Value(lowerEnEdge);
1198 range *= std::sqrt(kineticEnergy / lowerEnEdge);
1199 }
1200
1201#ifdef PRINT_DEBUG
1202 G4cout << "G4IonParametrisedLossModel::ComputeLossForStep() range = "
1203 << range / mm << " mm, step = " << stepLength / mm << " mm"
1204 << G4endl;
1205#endif
1206
1207 // Remaining range:
1208 G4double remRange = range - stepLength;
1209
1210 // If range is smaller than step length, the loss is set to kinetic
1211 // energy
1212 if(remRange < 0.0) loss = kineticEnergy;
1213 else if(remRange < lowerRangeEdge) {
1214
1215 G4double ratio = remRange / lowerRangeEdge;
1216 loss = kineticEnergy - ratio * ratio * lowerEnEdge;
1217 }
1218 else {
1219
1220 G4double energy = rangeEnergy -> Value(range - stepLength);
1221 loss = kineticEnergy - energy;
1222 }
1223 }
1224
1225 if(loss < 0.0) loss = 0.0;
1226
1227 return loss;
1228}
1229
1230// #########################################################################
1231
1233 const G4String& nam,
1234 G4VIonDEDXTable* table,
1235 G4VIonDEDXScalingAlgorithm* algorithm) {
1236
1237 if(table == 0) {
1238 G4cout << "G4IonParametrisedLossModel::AddDEDXTable() Cannot "
1239 << " add table: Invalid pointer."
1240 << G4endl;
1241
1242 return false;
1243 }
1244
1245 // Checking uniqueness of name
1246 LossTableList::iterator iter = lossTableList.begin();
1247 LossTableList::iterator iter_end = lossTableList.end();
1248
1249 for(;iter != iter_end; ++iter) {
1250 const G4String& tableName = (*iter)->GetName();
1251
1252 if(tableName == nam) {
1253 G4cout << "G4IonParametrisedLossModel::AddDEDXTable() Cannot "
1254 << " add table: Name already exists."
1255 << G4endl;
1256
1257 return false;
1258 }
1259 }
1260
1261 G4VIonDEDXScalingAlgorithm* scalingAlgorithm = algorithm;
1262 if(scalingAlgorithm == 0)
1263 scalingAlgorithm = new G4VIonDEDXScalingAlgorithm;
1264
1265 G4IonDEDXHandler* handler =
1266 new G4IonDEDXHandler(table, scalingAlgorithm, nam);
1267
1268 lossTableList.push_front(handler);
1269
1270 return true;
1271}
1272
1273// #########################################################################
1274
1276 const G4String& nam) {
1277
1278 LossTableList::iterator iter = lossTableList.begin();
1279 LossTableList::iterator iter_end = lossTableList.end();
1280
1281 for(;iter != iter_end; iter++) {
1282 G4String tableName = (*iter) -> GetName();
1283
1284 if(tableName == nam) {
1285 delete (*iter);
1286
1287 // Remove from table list
1288 lossTableList.erase(iter);
1289
1290 // Range vs energy and energy vs range vectors are cleared
1291 RangeEnergyTable::iterator iterRange = r.begin();
1292 RangeEnergyTable::iterator iterRange_end = r.end();
1293
1294 for(;iterRange != iterRange_end; iterRange++)
1295 delete iterRange -> second;
1296 r.clear();
1297
1298 EnergyRangeTable::iterator iterEnergy = E.begin();
1299 EnergyRangeTable::iterator iterEnergy_end = E.end();
1300
1301 for(;iterEnergy != iterEnergy_end; iterEnergy++)
1302 delete iterEnergy -> second;
1303 E.clear();
1304
1305 return true;
1306 }
1307 }
1308
1309 return false;
1310}
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
std::pair< const G4ParticleDefinition *, const G4MaterialCutsCouple * > IonMatCouple
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
const G4ThreeVector & GetMomentumDirection() const
G4ThreeVector GetMomentum() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
static G4EmParameters * Instance()
G4bool UseICRU90Data() const
static G4GenericIon * Definition()
Definition: G4GenericIon.cc:48
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double, G4double, G4double, G4double, G4double) override
G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *) override
G4double MaxSecondaryEnergy(const G4ParticleDefinition *, G4double) override
void CorrectionsAlongStep(const G4MaterialCutsCouple *, const G4DynamicParticle *, const G4double &, G4double &) override
LossTableList::iterator IsApplicable(const G4ParticleDefinition *, const G4Material *)
G4double GetChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, G4double) override
G4bool AddDEDXTable(const G4String &name, G4VIonDEDXTable *table, G4VIonDEDXScalingAlgorithm *algorithm=nullptr)
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4IonParametrisedLossModel(const G4ParticleDefinition *particle=nullptr, const G4String &name="ParamICRU73")
void PrintDEDXTableHandlers(const G4ParticleDefinition *, const G4Material *, G4double, G4double, G4int, G4bool)
G4double DeltaRayMeanEnergyTransferRate(const G4Material *, const G4ParticleDefinition *, G4double, G4double)
G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double, G4double) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double, G4double) override
G4bool RemoveDEDXTable(const G4String &name)
G4double ComputeLossForStep(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double, G4double)
G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double, G4double, G4double) override
G4double GetParticleCharge(const G4ParticleDefinition *, const G4Material *, G4double) override
void PrintDEDXTable(const G4ParticleDefinition *, const G4Material *, G4double, G4double, G4int, G4bool)
G4double GetMeanExcitationEnergy() const
static G4LossTableManager * Instance()
G4EmCorrections * EmCorrections()
const G4Material * GetMaterial() const
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:221
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4VEmFluctuationModel * GetModelOfFluctuations()
Definition: G4VEmModel.hh:593
G4VEmAngularDistribution * GetAngularDistribution()
Definition: G4VEmModel.hh:600
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:641
G4int SelectRandomAtomNumber(const G4Material *) const
Definition: G4VEmModel.cc:253
void SetParticleChange(G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
Definition: G4VEmModel.cc:390
virtual G4double Value(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
Definition: G4VEmModel.cc:349
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:634
void SetAngularDistribution(G4VEmAngularDistribution *)
Definition: G4VEmModel.hh:607
const G4String & GetName() const
Definition: G4VEmModel.hh:816
G4double MaxSecondaryKinEnergy(const G4DynamicParticle *dynParticle)
Definition: G4VEmModel.hh:501
G4ParticleChangeForLoss * GetParticleChangeForLoss()
Definition: G4VEmModel.cc:109
G4double energy(const ThreeVector &p, const G4double m)
#define DBL_MAX
Definition: templates.hh:62