Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VRadioactiveDecay.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// G4VRadioactiveDecay
31//
32// Author: D.H. Wright (SLAC)
33// Date: 9 August 2017
34//
35// Based on the code of F. Lei and P.R. Truscott.
36//
37////////////////////////////////////////////////////////////////////////////////
38
41
42#include "G4SystemOfUnits.hh"
43#include "G4UnitsTable.hh"
44#include "G4NuclideTable.hh"
45#include "G4DynamicParticle.hh"
46#include "G4DecayProducts.hh"
47#include "G4DecayTable.hh"
49#include "G4ITDecay.hh"
50#include "G4BetaDecayType.hh"
51#include "G4BetaMinusDecay.hh"
52#include "G4BetaPlusDecay.hh"
53#include "G4ECDecay.hh"
54#include "G4AlphaDecay.hh"
55#include "G4TritonDecay.hh"
56#include "G4ProtonDecay.hh"
57#include "G4NeutronDecay.hh"
58#include "G4SFDecay.hh"
59#include "G4VDecayChannel.hh"
60#include "G4NuclearDecay.hh"
62#include "G4Fragment.hh"
63#include "G4Ions.hh"
64#include "G4IonTable.hh"
65#include "G4BetaDecayType.hh"
66#include "Randomize.hh"
68#include "G4NuclearLevelData.hh"
70#include "G4LevelManager.hh"
71#include "G4ThreeVector.hh"
72#include "G4Electron.hh"
73#include "G4Positron.hh"
74#include "G4Neutron.hh"
75#include "G4Gamma.hh"
76#include "G4Alpha.hh"
77#include "G4Triton.hh"
78#include "G4Proton.hh"
79
83#include "G4LossTableManager.hh"
88
90#include "G4AutoLock.hh"
91
92#include <vector>
93#include <sstream>
94#include <algorithm>
95#include <fstream>
96
97using namespace CLHEP;
98
100const G4ThreeVector G4VRadioactiveDecay::origin(0.,0.,0.);
101
103std::map<G4int, G4String>* G4VRadioactiveDecay::theUserRDataFiles = nullptr;
104G4String G4VRadioactiveDecay::dirPath = "";
105
106namespace
107{
108 G4Mutex radioactiveDecayMutex = G4MUTEX_INITIALIZER;
109}
110
112 const G4double timeThreshold)
113 : G4VRestDiscreteProcess(processName, fDecay),
114 fThresholdForVeryLongDecayTime( 1.0*CLHEP::year )
115{
116 if (GetVerboseLevel() > 1) {
117 G4cout << "G4VRadioactiveDecay constructor: processName = " << processName
118 << G4endl;
119 }
120
122
125
126 // Check data directory
127 if (dirPath.empty()) {
128 const char* path_var = G4FindDataDir("G4RADIOACTIVEDATA");
129 if (nullptr == path_var) {
130 G4Exception("G4VRadioactiveDecay()", "HAD_RDM_200", FatalException,
131 "Environment variable G4RADIOACTIVEDATA is not set");
132 } else {
133 dirPath = path_var; // convert to string
134 std::ostringstream os;
135 os << dirPath << "/z1.a3"; // used as a dummy
136 std::ifstream testFile;
137 testFile.open(os.str() );
138 if ( !testFile.is_open() )
139 G4Exception("G4VRadioactiveDecay()","HAD_RDM_201",FatalException,
140 "Environment variable G4RADIOACTIVEDATA is set, but does not point to correct directory");
141 }
142 }
143 // Set up photon evaporation for use in G4ITDecay
145 photonEvaporation->RDMForced(true);
146 photonEvaporation->SetICM(true);
148
149 // Instantiate the map of decay tables
150 if (nullptr == master_dkmap) {
152 }
153 if (nullptr == theUserRDataFiles) {
154 theUserRDataFiles = new std::map<G4int, G4String>;
155 }
156
157 // RDM applies to all logical volumes by default
160
161 // The time threshold for radioactive decays can be set in 3 ways:
162 // 1. Via C++ interface: G4HadronicParameters::Instance()->SetTimeThresholdForRadioactiveDecay(value)
163 // 2. Via the second parameter of the G4VRadioactiveDecay constructor
164 // 3. Via UI command: /process/had/rdm/thresholdForVeryLongDecayTime value
165 // If both 1. and 2. are specified (at the moment when the G4VRadioactiveDecay constructor is called),
166 // then we take the larger value, to be conservative.
167 // If, later on (after invoking the G4VRadioactiveDecay constructor) 3. is specified,
168 // then this value is used (and the eventual values 1. and/or 2. are ignored).
170 if ( timeThreshold > 0.0 || timeThresholdBis > 0.0 ) {
171 if ( timeThreshold > timeThresholdBis ) timeThresholdBis = timeThreshold;
172 fThresholdForVeryLongDecayTime = timeThresholdBis;
173 }
174}
175
177{
179 delete photonEvaporation;
180 delete decayIT;
181 if (nullptr != master_dkmap) {
182 G4AutoLock lk(&radioactiveDecayMutex);
183 if (nullptr != master_dkmap) {
184 for (auto const & i : *master_dkmap) {
185 delete i.second;
186 }
187 master_dkmap->clear();
188 delete master_dkmap;
189 master_dkmap = nullptr;
190 }
191 delete theUserRDataFiles;
192 theUserRDataFiles = nullptr;
193 lk.unlock();
194 }
195}
196
197
199{
200 const G4String& pname = aParticle.GetParticleName();
201 if (pname == "GenericIon" || pname == "triton") { return true; }
202 // All particles other than G4Ions, are rejected by default
203 const G4Ions* p = dynamic_cast<const G4Ions*>(&aParticle);
204 if (nullptr == p) { return false; }
205
206 // excited isomere may decay via gamma evaporation
207 if (p->GetExcitationEnergy() > 0.0) { return true; }
208
209 // Check on life time
210 G4double lifeTime = p->GetPDGLifeTime();
211 if (lifeTime < 0.0 || lifeTime > fThresholdForVeryLongDecayTime) {
212 return false;
213 }
214
215 // Determine whether the nuclide falls into the correct A and Z range
216 G4int A = p->GetAtomicMass();
217 G4int Z = p->GetAtomicNumber();
218
219 if (A > theNucleusLimits.GetAMax() || A < theNucleusLimits.GetAMin() ||
220 Z > theNucleusLimits.GetZMax() || Z < theNucleusLimits.GetZMin()) {
221 return false;
222 }
223
224 return true;
225}
226
227
229 const G4Step& theStep)
230{
231 return DecayIt(theTrack, theStep);
232}
233
234
236 const G4Step& theStep)
237{
238 return DecayIt(theTrack, theStep);
239}
240
241
242void G4VRadioactiveDecay::ProcessDescription(std::ostream& outFile) const
243{
244 outFile << "The radioactive decay process (G4VRadioactiveDecay) handles the\n"
245 << "alpha, beta+, beta-, electron capture and isomeric transition\n"
246 << "decays of nuclei (G4GenericIon) with masses A > 4.\n"
247 << "The required half-lives and decay schemes are retrieved from\n"
248 << "the RadioactiveDecay database which was derived from ENSDF.\n";
249}
250
251
252
253
255{
256 G4String key = aNucleus->GetParticleName();
257 auto ptr = master_dkmap->find(key);
258
259 G4DecayTable* theDecayTable = nullptr;
260 if ( ptr == master_dkmap->end() ) {
261 // Load new file if table not there
262 const G4Ions* ion = dynamic_cast<const G4Ions*>(aNucleus);
263 if (nullptr != ion) {
264 theDecayTable = LoadDecayTable(ion);
265 }
266 } else {
267 theDecayTable = ptr->second;
268 }
269 return theDecayTable;
270}
271
272
274{
276 G4LogicalVolume* volume = nullptr;
277 volume = theLogicalVolumes->GetVolume(aVolume);
278 if (volume != nullptr)
279 {
280 ValidVolumes.push_back(aVolume);
281 std::sort(ValidVolumes.begin(), ValidVolumes.end());
282 // sort need for performing binary_search
283
284 if (GetVerboseLevel() > 0)
285 G4cout << " Radioactive decay applied to " << aVolume << G4endl;
286 }
287 else
288 {
290 ed << aVolume << " is not a valid logical volume name."
291 << " Decay not activated for it."
292 << G4endl;
293 G4Exception("G4VRadioactiveDecay::SelectAVolume()", "HAD_RDM_300",
294 JustWarning, ed);
295 }
296}
297
298
300{
302 G4LogicalVolume* volume = nullptr;
303 volume = theLogicalVolumes->GetVolume(aVolume);
304 if (volume != nullptr)
305 {
306 auto location= std::find(ValidVolumes.cbegin(),ValidVolumes.cend(),aVolume);
307 if (location != ValidVolumes.cend() )
308 {
309 ValidVolumes.erase(location);
310 std::sort(ValidVolumes.begin(), ValidVolumes.end());
311 isAllVolumesMode = false;
312 if (GetVerboseLevel() > 0)
313 G4cout << " G4VRadioactiveDecay::DeselectAVolume: " << aVolume
314 << " is removed from list " << G4endl;
315 }
316 else
317 {
319 ed << aVolume << " is not in the list. No action taken." << G4endl;
320 G4Exception("G4VRadioactiveDecay::DeselectAVolume()", "HAD_RDM_300",
321 JustWarning, ed);
322 }
323 }
324 else
325 {
327 ed << aVolume << " is not a valid logical volume name. No action taken."
328 << G4endl;
329 G4Exception("G4VRadioactiveDecay::DeselectAVolume()", "HAD_RDM_300",
330 JustWarning, ed);
331 }
332}
333
334
336{
338 G4LogicalVolume* volume = nullptr;
339 ValidVolumes.clear();
340#ifdef G4VERBOSE
341 if (GetVerboseLevel()>1)
342 G4cout << " RDM Applies to all Volumes" << G4endl;
343#endif
344 for (std::size_t i = 0; i < theLogicalVolumes->size(); ++i){
345 volume = (*theLogicalVolumes)[i];
346 ValidVolumes.push_back(volume->GetName());
347#ifdef G4VERBOSE
348 if (GetVerboseLevel()>1)
349 G4cout << " RDM Applies to Volume " << volume->GetName() << G4endl;
350#endif
351 }
352 std::sort(ValidVolumes.begin(), ValidVolumes.end());
353 // sort needed in order to allow binary_search
354 isAllVolumesMode=true;
355}
356
357
359{
360 ValidVolumes.clear();
361 isAllVolumesMode=false;
362#ifdef G4VERBOSE
363 if (GetVerboseLevel() > 1) G4cout << "RDM removed from all volumes" << G4endl;
364#endif
365}
366
367
368// GetMeanLifeTime (required by the base class)
371{
372 G4double meanlife = DBL_MAX;
373 const G4ParticleDefinition* theParticleDef = theTrack.GetParticleDefinition();
374 if (!IsApplicable(*theParticleDef)) { return meanlife; }
375 G4double theLife = theParticleDef->GetPDGLifeTime();
376#ifdef G4VERBOSE
377 if (GetVerboseLevel() > 2) {
378 G4cout << "G4VRadioactiveDecay::GetMeanLifeTime() for "
379 << theParticleDef->GetParticleName() << G4endl;
380 G4cout << "KineticEnergy(GeV)=" << theTrack.GetKineticEnergy()/CLHEP::GeV
381 << " Mass(GeV)=" << theParticleDef->GetPDGMass()/CLHEP::GeV
382 << " LifeTime(ns)=" << theLife/CLHEP::ns << G4endl;
383 }
384#endif
385 if (theLife >= 0.0 && theLife <= fThresholdForVeryLongDecayTime) {
386 meanlife = theLife;
387 }
388
389 if (meanlife == DBL_MAX) {
390 const G4Ions* ion = dynamic_cast<const G4Ions*>(theParticleDef);
391 if (nullptr != ion && ion->GetExcitationEnergy() > 0.0) {
392 meanlife = 0.0;
393 }
394 }
395
396#ifdef G4VERBOSE
397 if (GetVerboseLevel() > 2)
398 G4cout << "G4VRadioactiveDecay::GetMeanLifeTime: "
399 << meanlife/CLHEP::s << " second " << G4endl;
400#endif
401
402 return meanlife;
403}
404
405
406////////////////////////////////////////////////////////////////////////////////
407// //
408// GetMeanFreePath for decay in flight //
409// //
410////////////////////////////////////////////////////////////////////////////////
411
414{
415 G4double res = DBL_MAX;
416 G4double lifeTime = GetMeanLifeTime(aTrack, fc);
417 if (lifeTime > 0.0 && lifeTime < DBL_MAX) {
418 auto dParticle = aTrack.GetDynamicParticle();
419 res = lifeTime*dParticle->GetTotalEnergy()*aTrack.GetVelocity()/dParticle->GetMass();
420 } else {
421 res = lifeTime;
422 }
423
424#ifdef G4VERBOSE
425 if (GetVerboseLevel() > 2) {
426 G4cout << "G4VRadioactiveDecay::GetMeanFreePath() for "
427 << aTrack.GetDefinition()->GetParticleName() << G4endl;
428 G4cout << " kinEnergy(GeV)=" << aTrack.GetKineticEnergy()/CLHEP::GeV
429 << " lifeTime(ns)=" << lifeTime
430 << " mean free path(cm)=" << res/CLHEP::cm << G4endl;
431 }
432#endif
433 return res;
434}
435
436////////////////////////////////////////////////////////////////////////////////
437// //
438// BuildPhysicsTable - initialization of atomic de-excitation //
439// //
440////////////////////////////////////////////////////////////////////////////////
441
443{
444 if (isInitialised) { return; }
445 isInitialised = true;
447 G4Threading::IsMasterThread() && "GenericIon" == p.GetParticleName()) {
448 StreamInfo(G4cout, "\n");
449 }
450 photonEvaporation->Initialise();
451 photonEvaporation->RDMForced(true);
452 photonEvaporation->SetICM(true);
453 decayIT->SetARM(applyARM);
454
457}
458
459////////////////////////////////////////////////////////////////////////////////
460// //
461// StreamInfo - stream out parameters //
462// //
463////////////////////////////////////////////////////////////////////////////////
464
465void
466G4VRadioactiveDecay::StreamInfo(std::ostream& os, const G4String& endline)
467{
472
473 G4long prec = os.precision(5);
474 os << "======================================================================"
475 << endline;
476 os << "====== Radioactive Decay Physics Parameters ======="
477 << endline;
478 os << "======================================================================"
479 << endline;
480 os << "min MeanLife (from G4NuclideTable) "
481 << G4BestUnit(minMeanLife, "Time") << endline;
482 os << "Max life time (from G4DeexPrecoParameters) "
483 << G4BestUnit(deex->GetMaxLifeTime(), "Time") << endline;
484 os << "Internal e- conversion flag "
485 << deex->GetInternalConversionFlag() << endline;
486 os << "Stored internal conversion coefficients "
487 << deex->StoreICLevelData() << endline;
488 os << "Enabled atomic relaxation mode "
489 << applyARM << endline;
490 os << "Enable correlated gamma emission "
491 << deex->CorrelatedGamma() << endline;
492 os << "Max 2J for sampling of angular correlations "
493 << deex->GetTwoJMAX() << endline;
494 os << "Atomic de-excitation enabled "
495 << emparam->Fluo() << endline;
496 os << "Auger electron emission enabled "
497 << emparam->Auger() << endline;
498 os << "Check EM cuts disabled for atomic de-excitation "
499 << emparam->DeexcitationIgnoreCut() << endline;
500 os << "Use Bearden atomic level energies "
501 << emparam->BeardenFluoDir() << endline;
502 os << "Use ANSTO fluorescence model "
503 << emparam->ANSTOFluoDir() << endline;
504 os << "Threshold for very long decay time at rest "
505 << G4BestUnit(fThresholdForVeryLongDecayTime, "Time") << endline;
506 os << "======================================================================"
507 << G4endl;
508 os.precision(prec);
509}
510
511
512////////////////////////////////////////////////////////////////////////////////
513// //
514// LoadDecayTable loads the decay scheme from the RadioactiveDecay database //
515// for the parent nucleus. //
516// //
517////////////////////////////////////////////////////////////////////////////////
518
520{
521 G4AutoLock lk(&radioactiveDecayMutex);
522 const G4String key = theIon->GetParticleName();
523 auto dtptr = master_dkmap->find(key);
524 if (dtptr != master_dkmap->end()) {
525 lk.unlock();
526 return dtptr->second;
527 }
528
529 // Generate input data file name using Z and A of the parent nucleus
530 // file containing radioactive decay data.
531 G4int A = theIon->GetAtomicMass();
532 G4int Z = theIon->GetAtomicNumber();
533
534 //G4cout << "LoadDecayTable for " << key << " Z=" << Z << " A=" << A << G4endl;
535
536 G4double levelEnergy = theIon->GetExcitationEnergy();
537 G4Ions::G4FloatLevelBase floatingLevel = theIon->GetFloatLevelBase();
538
539 //Check if data have been provided by the user
540 G4String file;
541 G4int ke = 1000*A + Z;
542 auto ptr = theUserRDataFiles->find(ke);
543 if (ptr != theUserRDataFiles->end()) {
544 file = ptr->second;
545 } else {
546 std::ostringstream os;
547 os << dirPath << "/z" << Z << ".a" << A << '\0';
548 file = os.str();
549 }
550
551 G4DecayTable* theDecayTable = new G4DecayTable();
552 G4bool found(false); // True if energy level matches one in table
553
554 std::ifstream DecaySchemeFile;
555 DecaySchemeFile.open(file);
556
557 if (DecaySchemeFile.good()) {
558 // Initialize variables used for reading in radioactive decay data
559 G4bool floatMatch(false);
560 const G4int nMode = G4RadioactiveDecayModeSize;
561 G4double modeTotalBR[nMode] = {0.0};
562 G4double modeSumBR[nMode];
563 for (G4int i = 0; i < nMode; ++i) {
564 modeSumBR[i] = 0.0;
565 }
566
567 char inputChars[120]={' '};
568 G4String inputLine;
569 G4String recordType("");
570 G4String floatingFlag("");
571 G4String daughterFloatFlag("");
572 G4Ions::G4FloatLevelBase daughterFloatLevel;
573 G4RadioactiveDecayMode theDecayMode;
574 G4double decayModeTotal(0.0);
575 G4double parentExcitation(0.0);
576 G4double a(0.0);
577 G4double b(0.0);
578 G4double c(0.0);
579 G4double dummy(0.0);
580 G4BetaDecayType betaType(allowed);
581
582 // Loop through each data file record until you identify the decay
583 // data relating to the nuclide of concern.
584
585 G4bool complete(false); // bool insures only one set of values read for any
586 // given parent energy level
587 G4int loop = 0;
588 /* Loop checking, 01.09.2015, D.Wright */
589 while (!complete && !DecaySchemeFile.getline(inputChars, 120).eof()) {
590 loop++;
591 if (loop > 100000) {
592 G4Exception("G4VRadioactiveDecay::LoadDecayTable()", "HAD_RDM_100",
593 JustWarning, "While loop count exceeded");
594 break;
595 }
596
597 inputLine = inputChars;
598 G4StrUtil::rstrip(inputLine);
599 if (inputChars[0] != '#' && inputLine.length() != 0) {
600 std::istringstream tmpStream(inputLine);
601
602 if (inputChars[0] == 'P') {
603 // Nucleus is a parent type. Check excitation level to see if it
604 // matches that of theParentNucleus
605 tmpStream >> recordType >> parentExcitation >> floatingFlag >> dummy;
606 // "dummy" takes the place of half-life
607 // Now read in from ENSDFSTATE in particle category
608
609 if (found) {
610 complete = true;
611 } else {
612 // Take first level which matches excitation energy regardless of floating level
613 found = (std::abs(parentExcitation*keV - levelEnergy) < levelTolerance);
614 if (floatingLevel != noFloat) {
615 // If floating level specificed, require match of both energy and floating level
616 floatMatch = (floatingLevel == G4Ions::FloatLevelBase(floatingFlag.back()) );
617 if (!floatMatch) found = false;
618 }
619 }
620
621 } else if (found) {
622 // The right part of the radioactive decay data file has been found. Search
623 // through it to determine the mode of decay of the subsequent records.
624
625 // Store for later the total decay probability for each decay mode
626 if (inputLine.length() < 72) {
627 tmpStream >> theDecayMode >> dummy >> decayModeTotal;
628
629 switch (theDecayMode) {
630 case IT:
631 {
632 G4ITDecay* anITChannel = new G4ITDecay(theIon, decayModeTotal, 0.0, 0.0);
633 theDecayTable->Insert(anITChannel);
634 }
635 break;
636 case BetaMinus:
637 modeTotalBR[BetaMinus] = decayModeTotal; break;
638 case BetaPlus:
639 modeTotalBR[BetaPlus] = decayModeTotal; break;
640 case KshellEC:
641 modeTotalBR[KshellEC] = decayModeTotal; break;
642 case LshellEC:
643 modeTotalBR[LshellEC] = decayModeTotal; break;
644 case MshellEC:
645 modeTotalBR[MshellEC] = decayModeTotal; break;
646 case NshellEC:
647 modeTotalBR[NshellEC] = decayModeTotal; break;
648 case Alpha:
649 modeTotalBR[Alpha] = decayModeTotal; break;
650 case Proton:
651 modeTotalBR[Proton] = decayModeTotal; break;
652 case Neutron:
653 modeTotalBR[Neutron] = decayModeTotal; break;
654 case SpFission:
655 modeTotalBR[SpFission] = decayModeTotal; break;
656 case BDProton:
657 /* Not yet implemented */ break;
658 case BDNeutron:
659 /* Not yet implemented */ break;
660 case Beta2Minus:
661 /* Not yet implemented */ break;
662 case Beta2Plus:
663 /* Not yet implemented */ break;
664 case Proton2:
665 /* Not yet implemented */ break;
666 case Neutron2:
667 /* Not yet implemented */ break;
668 case Triton:
669 modeTotalBR[Triton] = decayModeTotal; break;
670 case RDM_ERROR:
671
672 default:
673 G4Exception("G4VRadioactiveDecay::LoadDecayTable()", "HAD_RDM_000",
674 FatalException, "Selected decay mode does not exist");
675 } // switch
676
677 } else {
678 if (inputLine.length() < 84) {
679 tmpStream >> theDecayMode >> a >> daughterFloatFlag >> b >> c;
680 betaType = allowed;
681 } else {
682 tmpStream >> theDecayMode >> a >> daughterFloatFlag >> b >> c >> betaType;
683 }
684
685 // Allowed transitions are the default. Forbidden transitions are
686 // indicated in the last column.
687 a /= 1000.;
688 c /= 1000.;
689 b /= 100.;
690 daughterFloatLevel = G4Ions::FloatLevelBase(daughterFloatFlag.back());
691
692 switch (theDecayMode) {
693 case BetaMinus:
694 {
695 G4BetaMinusDecay* aBetaMinusChannel =
696 new G4BetaMinusDecay(theIon, b, c*MeV, a*MeV,
697 daughterFloatLevel, betaType);
698 //aBetaMinusChannel->DumpNuclearInfo();
699 theDecayTable->Insert(aBetaMinusChannel);
700 modeSumBR[BetaMinus] += b;
701 }
702 break;
703
704 case BetaPlus:
705 {
706 G4BetaPlusDecay* aBetaPlusChannel =
707 new G4BetaPlusDecay(theIon, b, c*MeV, a*MeV,
708 daughterFloatLevel, betaType);
709 //aBetaPlusChannel->DumpNuclearInfo();
710 theDecayTable->Insert(aBetaPlusChannel);
711 modeSumBR[BetaPlus] += b;
712 }
713 break;
714
715 case KshellEC: // K-shell electron capture
716 {
717 G4ECDecay* aKECChannel =
718 new G4ECDecay(theIon, b, c*MeV, a*MeV,
719 daughterFloatLevel, KshellEC);
720 //aKECChannel->DumpNuclearInfo();
721 aKECChannel->SetARM(applyARM);
722 theDecayTable->Insert(aKECChannel);
723 modeSumBR[KshellEC] += b;
724 }
725 break;
726
727 case LshellEC: // L-shell electron capture
728 {
729 G4ECDecay* aLECChannel =
730 new G4ECDecay(theIon, b, c*MeV, a*MeV,
731 daughterFloatLevel, LshellEC);
732// aLECChannel->DumpNuclearInfo();
733 aLECChannel->SetARM(applyARM);
734 theDecayTable->Insert(aLECChannel);
735 modeSumBR[LshellEC] += b;
736 }
737 break;
738
739 case MshellEC: // M-shell electron capture
740 {
741 G4ECDecay* aMECChannel =
742 new G4ECDecay(theIon, b, c*MeV, a*MeV,
743 daughterFloatLevel, MshellEC);
744// aMECChannel->DumpNuclearInfo();
745 aMECChannel->SetARM(applyARM);
746 theDecayTable->Insert(aMECChannel);
747 modeSumBR[MshellEC] += b;
748 }
749 break;
750
751 case NshellEC: // N-shell electron capture
752 {
753 G4ECDecay* aNECChannel =
754 new G4ECDecay(theIon, b, c*MeV, a*MeV,
755 daughterFloatLevel, NshellEC);
756// aNECChannel->DumpNuclearInfo();
757 aNECChannel->SetARM(applyARM);
758 theDecayTable->Insert(aNECChannel);
759 modeSumBR[NshellEC] += b;
760 }
761 break;
762
763 case Alpha:
764 {
765 G4AlphaDecay* anAlphaChannel =
766 new G4AlphaDecay(theIon, b, c*MeV, a*MeV,
767 daughterFloatLevel);
768// anAlphaChannel->DumpNuclearInfo();
769 theDecayTable->Insert(anAlphaChannel);
770 modeSumBR[Alpha] += b;
771 }
772 break;
773
774 case Proton:
775 {
776 G4ProtonDecay* aProtonChannel =
777 new G4ProtonDecay(theIon, b, c*MeV, a*MeV,
778 daughterFloatLevel);
779// aProtonChannel->DumpNuclearInfo();
780 theDecayTable->Insert(aProtonChannel);
781 modeSumBR[Proton] += b;
782 }
783 break;
784
785 case Neutron:
786 {
787 G4NeutronDecay* aNeutronChannel =
788 new G4NeutronDecay(theIon, b, c*MeV, a*MeV,
789 daughterFloatLevel);
790// aNeutronChannel->DumpNuclearInfo();
791 theDecayTable->Insert(aNeutronChannel);
792 modeSumBR[Neutron] += b;
793 }
794 break;
795
796 case SpFission:
797 {
798 G4SFDecay* aSpontFissChannel =
799 new G4SFDecay(theIon, b, c*MeV, a*MeV, daughterFloatLevel);
800 theDecayTable->Insert(aSpontFissChannel);
801 modeSumBR[SpFission] += b;
802 }
803 break;
804
805 case BDProton:
806 // Not yet implemented
807 // G4cout << " beta-delayed proton decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
808 break;
809
810 case BDNeutron:
811 // Not yet implemented
812 // G4cout << " beta-delayed neutron decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
813 break;
814
815 case Beta2Minus:
816 // Not yet implemented
817 // G4cout << " Double beta- decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
818 break;
819
820 case Beta2Plus:
821 // Not yet implemented
822 // G4cout << " Double beta+ decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
823 break;
824
825 case Proton2:
826 // Not yet implemented
827 // G4cout << " Double proton decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
828 break;
829
830 case Neutron2:
831 // Not yet implemented
832 // G4cout << " Double beta- decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
833 break;
834
835 case Triton:
836 {
837 G4TritonDecay* aTritonChannel =
838 new G4TritonDecay(theIon, b, c*MeV, a*MeV, daughterFloatLevel);
839 theDecayTable->Insert(aTritonChannel);
840 modeSumBR[Triton] += b;
841 }
842 break;
843
844 case RDM_ERROR:
845
846 default:
847 G4Exception("G4VRadioactiveDecay::LoadDecayTable()", "HAD_RDM_000",
848 FatalException, "Selected decay mode does not exist");
849 } // switch
850 } // line < 72
851 } // if char == P
852 } // if char != #
853 } // While
854
855 // Go through the decay table and make sure that the branching ratios are
856 // correctly normalised.
857
858 G4VDecayChannel* theChannel = 0;
859 G4NuclearDecay* theNuclearDecayChannel = 0;
860 G4String mode = "";
861
862 G4double theBR = 0.0;
863 for (G4int i = 0; i < theDecayTable->entries(); ++i) {
864 theChannel = theDecayTable->GetDecayChannel(i);
865 theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
866 theDecayMode = theNuclearDecayChannel->GetDecayMode();
867
868 if (theDecayMode != IT) {
869 theBR = theChannel->GetBR();
870 theChannel->SetBR(theBR*modeTotalBR[theDecayMode]/modeSumBR[theDecayMode]);
871 }
872 }
873 } // decay file exists
874
875 DecaySchemeFile.close();
876
877 if (!found && levelEnergy > 0) {
878 // Case where IT cascade for excited isotopes has no entries in RDM database
879 // Decay mode is isomeric transition.
880 G4ITDecay* anITChannel = new G4ITDecay(theIon, 1.0, 0.0, 0.0);
881 theDecayTable->Insert(anITChannel);
882 }
883
884 if (GetVerboseLevel() > 1) {
885 theDecayTable->DumpInfo();
886 }
887
888 // store in master library
889 (*master_dkmap)[theIon->GetParticleName()] = theDecayTable;
890 lk.unlock();
891 return theDecayTable;
892}
893
895 const G4String& filename)
896{
897 if (Z < 1 || A < 2) G4cout << "Z and A not valid!" << G4endl;
898
899 std::ifstream DecaySchemeFile(filename);
900 if (DecaySchemeFile) {
901 G4int ID_ion = A*1000 + Z;
902 (*theUserRDataFiles)[ID_ion] = filename;
903 } else {
905 ed << filename << " does not exist! " << G4endl;
906 G4Exception("G4VRadioactiveDecay::AddUserDecayDataFile()", "HAD_RDM_001",
907 FatalException, ed);
908 }
909}
910
911////////////////////////////////////////////////////////////////////////////////
912// //
913// DecayIt //
914// //
915////////////////////////////////////////////////////////////////////////////////
916
919{
920 // Initialize G4ParticleChange object, get particle details and decay table
921 fParticleChangeForRadDecay.Initialize(theTrack);
922 fParticleChangeForRadDecay.ProposeWeight(theTrack.GetWeight());
923 const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
924 const G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
925
926 // First check whether RDM applies to the current logical volume
927 if (!isAllVolumesMode) {
928 if (!std::binary_search(ValidVolumes.begin(), ValidVolumes.end(),
929 theTrack.GetVolume()->GetLogicalVolume()->GetName())) {
930#ifdef G4VERBOSE
931 if (GetVerboseLevel()>1) {
932 G4cout <<"G4VRadioactiveDecay::DecayIt : "
933 << theTrack.GetVolume()->GetLogicalVolume()->GetName()
934 << " is not selected for the RDM"<< G4endl;
935 G4cout << " There are " << ValidVolumes.size() << " volumes" << G4endl;
936 G4cout << " The Valid volumes are: ";
937 for (auto const & vol : ValidVolumes) { G4cout << vol << " " << G4endl; }
938 G4cout << G4endl;
939 }
940#endif
941 fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
942
943 // Kill the parent particle.
944 fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill) ;
945 fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
948 }
949 }
950
951 // Now check if particle is valid for RDM
952 G4DecayTable* theDecayTable = GetDecayTable(theParticleDef);
953 if ( theDecayTable == nullptr || theDecayTable->entries() == 0) {
954 // Particle is not an ion or is outside the nucleuslimits for decay
955#ifdef G4VERBOSE
956 if (GetVerboseLevel() > 1) {
957 G4cout << "G4VRadioactiveDecay::DecayIt : "
958 << theParticleDef->GetParticleName()
959 << " is outside (Z,A) limits set for the decay or has no decays."
960 << G4endl;
961 }
962#endif
963 fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
964
965 // Kill the parent particle
966 fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill) ;
967 fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
970 }
971 //G4cout << "DecayIt for " << theParticleDef->GetParticleName()
972 // << " isAllVolumesMode:" << isAllVolumesMode
973 // << " decayTable=" << theDecayTable << G4endl;
974
975 // Data found. Decay nucleus without variance reduction.
976 DecayAnalog(theTrack, theDecayTable);
978}
979
981 G4DecayTable* decayTable)
982{
983 const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
984 const G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
985 //G4cout << "DecayIt for " << theParticleDef->GetParticleName() << G4endl;
986 G4DecayProducts* products = DoDecay(*theParticleDef, decayTable);
987
988 // Check if the product is the same as input and kill the track if
989 // necessary to prevent infinite loop (11/05/10, F.Lei)
990 if (nullptr == products || products->entries() == 1) {
991 fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
992 fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill);
993 fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
995 delete products;
996 return;
997 }
998
999 G4double energyDeposit = 0.0;
1000 G4double finalGlobalTime = theTrack.GetGlobalTime();
1001 G4double finalLocalTime = theTrack.GetLocalTime();
1002
1003 // Get parent particle information and boost the decay products to the
1004 // laboratory frame
1005
1006 // ParentEnergy used for the boost should be the total energy of the nucleus
1007 // of the parent ion without the energy of the shell electrons
1008 // (correction for bug 1359 by L. Desorgher)
1009 G4double ParentEnergy = theParticle->GetKineticEnergy()
1010 + theParticle->GetParticleDefinition()->GetPDGMass();
1011 G4ThreeVector ParentDirection(theParticle->GetMomentumDirection());
1012
1013 if (theTrack.GetTrackStatus() == fStopButAlive) {
1014 // this condition seems to be always True, further investigation is needed (L.Desorgher)
1015
1016 // The particle is decayed at rest
1017 // Since the time is for the particle at rest, need to add additional time
1018 // lapsed between particle coming to rest and the actual decay. This time
1019 // is sampled with the mean-life of the particle. Need to protect the case
1020 // PDGTime < 0. (F.Lei 11/05/10)
1021 G4double temptime = -std::log(G4UniformRand() ) *
1022 theParticleDef->GetPDGLifeTime();
1023 if (temptime < 0.) temptime = 0.;
1024 finalGlobalTime += temptime;
1025 finalLocalTime += temptime;
1026 energyDeposit += theParticle->GetKineticEnergy();
1027
1028 // Kill the parent particle, and ignore its decay, if it decays later than the
1029 // threshold fThresholdForVeryLongDecayTime (whose default value corresponds
1030 // to more than twice the age of the universe).
1031 // This kind of cut has been introduced (in April 2021) in order to avoid to
1032 // account energy depositions happening after many billions of years in
1033 // ordinary materials used in calorimetry, in particular Tungsten and Lead
1034 // (via their natural unstable, but very long lived, isotopes, such as
1035 // W183, W180 and Pb204).
1036 // Note that the cut is not on the average, mean lifetime, but on the actual
1037 // sampled global decay time.
1038 if ( finalGlobalTime > fThresholdForVeryLongDecayTime ) {
1039 fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
1040 fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill) ;
1041 fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
1043 delete products;
1044 return;
1045 }
1046 }
1047 products->Boost(ParentEnergy, ParentDirection);
1048
1049 // Add products in theParticleChangeForRadDecay.
1050 G4int numberOfSecondaries = products->entries();
1051 fParticleChangeForRadDecay.SetNumberOfSecondaries(numberOfSecondaries);
1052
1053 if (GetVerboseLevel() > 1) {
1054 G4cout << "G4VRadioactiveDecay::DecayAnalog: Decay vertex :";
1055 G4cout << " Time: " << finalGlobalTime/ns << "[ns]";
1056 G4cout << " X:" << (theTrack.GetPosition()).x() /cm << "[cm]";
1057 G4cout << " Y:" << (theTrack.GetPosition()).y() /cm << "[cm]";
1058 G4cout << " Z:" << (theTrack.GetPosition()).z() /cm << "[cm]";
1059 G4cout << G4endl;
1060 G4cout << "G4Decay::DecayIt : decay products in Lab. Frame" << G4endl;
1061 products->DumpInfo();
1062 products->IsChecked();
1063 }
1064
1065 const G4int modelID_forIT = G4PhysicsModelCatalog::GetModelID( "model_RDM_IT" );
1066 G4int modelID = modelID_forIT + 10*theRadDecayMode;
1067 const G4int modelID_forAtomicRelaxation =
1068 G4PhysicsModelCatalog::GetModelID( "model_RDM_AtomicRelaxation" );
1069 for ( G4int index = 0; index < numberOfSecondaries; ++index ) {
1070 G4Track* secondary = new G4Track( products->PopProducts(), finalGlobalTime,
1071 theTrack.GetPosition() );
1072 secondary->SetWeight( theTrack.GetWeight() );
1073 secondary->SetCreatorModelID( modelID );
1074 // Change for atomics relaxation
1075 if ( theRadDecayMode == IT && index > 0 ) {
1076 if ( index == numberOfSecondaries-1 ) {
1077 secondary->SetCreatorModelID( modelID_forIT );
1078 } else {
1079 secondary->SetCreatorModelID( modelID_forAtomicRelaxation) ;
1080 }
1081 } else if ( theRadDecayMode >= KshellEC && theRadDecayMode <= NshellEC &&
1082 index < numberOfSecondaries-1 ) {
1083 secondary->SetCreatorModelID( modelID_forAtomicRelaxation );
1084 }
1085 secondary->SetGoodForTrackingFlag();
1086 secondary->SetTouchableHandle( theTrack.GetTouchableHandle() );
1087 fParticleChangeForRadDecay.AddSecondary( secondary );
1088 }
1089
1090 delete products;
1091
1092 // Kill the parent particle
1093 fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill) ;
1094 fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(energyDeposit);
1095 fParticleChangeForRadDecay.ProposeLocalTime(finalLocalTime);
1096
1097 // Reset NumberOfInteractionLengthLeft.
1099}
1100
1101
1104 G4DecayTable* theDecayTable)
1105{
1106 G4DecayProducts* products = nullptr;
1107
1108 // Choose a decay channel.
1109 // G4DecayTable::SelectADecayChannel checks to see if sum of daughter masses
1110 // exceeds parent mass. Pass it the parent mass + maximum Q value to account
1111 // for difference in mass defect.
1112 G4double parentPlusQ = theParticleDef.GetPDGMass() + 30.*MeV;
1113 G4VDecayChannel* theDecayChannel = theDecayTable->SelectADecayChannel(parentPlusQ);
1114
1115 if (theDecayChannel == nullptr) {
1116 // Decay channel not found.
1118 ed << " Cannot determine decay channel for " << theParticleDef.GetParticleName() << G4endl;
1119 G4Exception("G4VRadioactiveDecay::DoDecay", "HAD_RDM_013",
1120 FatalException, ed);
1121 } else {
1122 // A decay channel has been identified, so execute the DecayIt.
1123#ifdef G4VERBOSE
1124 if (GetVerboseLevel() > 1) {
1125 G4cout << "G4VRadioactiveDecay::DoIt : selected decay channel addr: "
1126 << theDecayChannel << G4endl;
1127 }
1128#endif
1129 theRadDecayMode = static_cast<G4NuclearDecay*>(theDecayChannel)->GetDecayMode();
1130
1131 // for IT decay use local G4ITDecay class
1132 if (theRadDecayMode == IT) {
1133 decayIT->SetupDecay(&theParticleDef);
1134 products = decayIT->DecayIt(0.0);
1135 } else {
1136 // for others decayes use shared class
1137 products = theDecayChannel->DecayIt(theParticleDef.GetPDGMass());
1138 }
1139
1140 // Apply directional bias if requested by user
1141 CollimateDecay(products);
1142 }
1143
1144 return products;
1145}
1146
1147
1148// Apply directional bias for "visible" daughters (e+-, gamma, n, p, alpha)
1150
1151 if (origin == forceDecayDirection) return; // No collimation requested
1152 if (180.*deg == forceDecayHalfAngle) return;
1153 if (0 == products || 0 == products->entries()) return;
1154
1155#ifdef G4VERBOSE
1156 if (GetVerboseLevel() > 1) G4cout << "Begin of CollimateDecay..." << G4endl;
1157#endif
1158
1159 // Particles suitable for directional biasing (for if-blocks below)
1160 static const G4ParticleDefinition* electron = G4Electron::Definition();
1161 static const G4ParticleDefinition* positron = G4Positron::Definition();
1162 static const G4ParticleDefinition* neutron = G4Neutron::Definition();
1163 static const G4ParticleDefinition* gamma = G4Gamma::Definition();
1164 static const G4ParticleDefinition* alpha = G4Alpha::Definition();
1165 static const G4ParticleDefinition* triton = G4Triton::Definition();
1166 static const G4ParticleDefinition* proton = G4Proton::Definition();
1167
1168 G4ThreeVector newDirection; // Re-use to avoid memory churn
1169 for (G4int i=0; i<products->entries(); ++i) {
1170 G4DynamicParticle* daughter = (*products)[i];
1171 const G4ParticleDefinition* daughterType =
1172 daughter->GetParticleDefinition();
1173 if (daughterType == electron || daughterType == positron ||
1174 daughterType == neutron || daughterType == gamma ||
1175 daughterType == alpha || daughterType == triton || daughterType == proton) {
1176 CollimateDecayProduct(daughter);
1177 }
1178 }
1179}
1180
1182#ifdef G4VERBOSE
1183 if (GetVerboseLevel() > 1) {
1184 G4cout << "CollimateDecayProduct for daughter "
1185 << daughter->GetParticleDefinition()->GetParticleName() << G4endl;
1186 }
1187#endif
1188
1190 if (origin != collimate) daughter->SetMomentumDirection(collimate);
1191}
1192
1193
1194// Choose random direction within collimation cone
1195
1197 if (origin == forceDecayDirection) return origin; // Don't do collimation
1198 if (forceDecayHalfAngle == 180.*deg) return origin;
1199
1200 G4ThreeVector dir = forceDecayDirection;
1201
1202 // Return direction offset by random throw
1203 if (forceDecayHalfAngle > 0.) {
1204 // Generate uniform direction around central axis
1205 G4double phi = 2.*pi*G4UniformRand();
1206 G4double cosMin = std::cos(forceDecayHalfAngle);
1207 G4double cosTheta = (1.-cosMin)*G4UniformRand() + cosMin; // [cosMin,1.)
1208
1209 dir.setPhi(dir.phi()+phi);
1210 dir.setTheta(dir.theta()+std::acos(cosTheta));
1211 }
1212
1213#ifdef G4VERBOSE
1214 if (GetVerboseLevel()>1)
1215 G4cout << " ChooseCollimationDirection returns " << dir << G4endl;
1216#endif
1217
1218 return dir;
1219}
1220
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4BetaDecayType
@ allowed
const char * G4FindDataDir(const char *)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ForceCondition
@ fRadioactiveDecay
#define noFloat
Definition G4Ions.hh:119
@ fDecay
@ G4RadioactiveDecayModeSize
std::map< G4String, G4DecayTable * > DecayTableMap
#define G4BestUnit(a, b)
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
@ fStopButAlive
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
std::map< G4String, G4DecayTable * > DecayTableMap
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
double phi() const
double theta() const
void setTheta(double)
void setPhi(double)
static G4Alpha * Definition()
Definition G4Alpha.cc:43
void DumpInfo() const
G4int entries() const
G4DynamicParticle * PopProducts()
G4bool IsChecked() const
void Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
G4VDecayChannel * GetDecayChannel(G4int index) const
void Insert(G4VDecayChannel *aChannel)
G4VDecayChannel * SelectADecayChannel(G4double parentMass=-1.)
void DumpInfo() const
G4int entries() const
G4bool GetInternalConversionFlag() const
void SetMomentumDirection(const G4ThreeVector &aDirection)
const G4ThreeVector & GetMomentumDirection() const
const G4ParticleDefinition * GetParticleDefinition() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
void SetARM(G4bool onoff)
Definition G4ECDecay.hh:56
static G4Electron * Definition()
Definition G4Electron.cc:45
static G4EmParameters * Instance()
G4bool Fluo() const
G4bool DeexcitationIgnoreCut() const
G4bool Auger() const
G4bool BeardenFluoDir()
static G4Gamma * Definition()
Definition G4Gamma.cc:43
static G4HadronicParameters * Instance()
G4double GetTimeThresholdForRadioactiveDecay() const
void RegisterExtraProcess(G4VProcess *)
void RegisterParticleForExtraProcess(G4VProcess *, const G4ParticleDefinition *)
static G4HadronicProcessStore * Instance()
void PrintInfo(const G4ParticleDefinition *)
G4double GetExcitationEnergy() const
Definition G4Ions.hh:149
G4Ions::G4FloatLevelBase GetFloatLevelBase() const
Definition G4Ions.hh:159
static G4Ions::G4FloatLevelBase FloatLevelBase(char flbChar)
Definition G4Ions.cc:107
G4FloatLevelBase
Definition G4Ions.hh:80
G4LogicalVolume * GetVolume(const G4String &name, G4bool verbose=true, G4bool reverseSearch=false) const
static G4LogicalVolumeStore * GetInstance()
const G4String & GetName() const
static G4Neutron * Definition()
Definition G4Neutron.cc:50
G4RadioactiveDecayMode GetDecayMode() const
G4DeexPrecoParameters * GetParameters()
static G4NuclearLevelData * GetInstance()
G4double GetMeanLifeThreshold()
static G4NuclideTable * GetInstance()
G4int GetAtomicNumber() const
G4int GetAtomicMass() const
G4double GetPDGLifeTime() const
const G4String & GetParticleName() const
static G4int GetModelID(const G4int modelIndex)
static G4Positron * Definition()
Definition G4Positron.cc:45
static G4Proton * Definition()
Definition G4Proton.cc:45
G4TrackStatus GetTrackStatus() const
G4double GetVelocity() const
const G4ParticleDefinition * GetParticleDefinition() const
G4VPhysicalVolume * GetVolume() const
G4double GetWeight() const
void SetWeight(G4double aValue)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4double GetLocalTime() const
G4ParticleDefinition * GetDefinition() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
G4double GetKineticEnergy() const
void SetCreatorModelID(const G4int id)
void SetGoodForTrackingFlag(G4bool value=true)
static G4Triton * Definition()
Definition G4Triton.cc:45
G4double GetBR() const
void SetBR(G4double value)
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
G4LogicalVolume * GetLogicalVolume() const
G4int GetVerboseLevel() const
void ClearNumberOfInteractionLengthLeft()
void SetProcessSubType(G4int)
G4VParticleChange * pParticleChange
virtual G4VParticleChange * DecayIt(const G4Track &theTrack, const G4Step &theStep)
G4ParticleChangeForRadDecay fParticleChangeForRadDecay
G4VRadioactiveDecay(const G4String &processName="RadioactiveDecay", const G4double timeThreshold=-1.0)
void DecayAnalog(const G4Track &theTrack, G4DecayTable *)
void AddUserDecayDataFile(G4int Z, G4int A, const G4String &filename)
G4PhotonEvaporation * photonEvaporation
void ProcessDescription(std::ostream &outFile) const override
G4DecayProducts * DoDecay(const G4ParticleDefinition &, G4DecayTable *)
void BuildPhysicsTable(const G4ParticleDefinition &) override
std::vector< G4String > ValidVolumes
G4VParticleChange * AtRestDoIt(const G4Track &theTrack, const G4Step &theStep) override
void SelectAVolume(const G4String &aVolume)
G4double GetMeanFreePath(const G4Track &theTrack, G4double previousStepSize, G4ForceCondition *condition) override
G4RadioactiveDecayMessenger * theRadioactiveDecayMessenger
void StreamInfo(std::ostream &os, const G4String &endline)
void CollimateDecay(G4DecayProducts *products)
G4DecayTable * LoadDecayTable(const G4Ions *)
G4double GetMeanLifeTime(const G4Track &theTrack, G4ForceCondition *condition) override
G4bool IsApplicable(const G4ParticleDefinition &) override
G4ThreeVector ChooseCollimationDirection() const
static DecayTableMap * master_dkmap
static const G4double levelTolerance
void DeselectAVolume(const G4String &aVolume)
G4DecayTable * GetDecayTable(const G4ParticleDefinition *)
G4VParticleChange * PostStepDoIt(const G4Track &theTrack, const G4Step &theStep) override
void CollimateDecayProduct(G4DynamicParticle *product)
G4VRestDiscreteProcess(const G4String &, G4ProcessType aType=fNotDefined)
G4bool IsMasterThread()
#define DBL_MAX
Definition templates.hh:62
#define ns(x)
Definition xmltok.c:1649