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