Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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 ([email protected])
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
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
#define G4endl
Definition G4ios.hh:67
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:91
static G4EmParameters * Instance()
G4bool UseICRU90Data() const
static G4GenericIon * Definition()
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
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()
G4VEmAngularDistribution * GetAngularDistribution()
G4double LowEnergyLimit() const
G4int SelectRandomAtomNumber(const G4Material *) const
void SetParticleChange(G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
virtual G4double Value(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
G4double HighEnergyLimit() const
void SetAngularDistribution(G4VEmAngularDistribution *)
const G4String & GetName() const
G4double MaxSecondaryKinEnergy(const G4DynamicParticle *dynParticle)
G4ParticleChangeForLoss * GetParticleChangeForLoss()
G4double energy(const ThreeVector &p, const G4double m)
#define DBL_MAX
Definition templates.hh:62