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