98 G4cout <<
"G4Radioactivation constructor: processName = " << processName
119 theRadioactivityTables.push_back(rTable);
123 halflifethreshold = 1000.*nanosecond;
129 outFile <<
"The G4Radioactivation process performs radioactive decay of\n"
130 <<
"nuclides (G4GenericIon) in biased mode which includes nucleus\n"
131 <<
"duplication, branching ratio biasing, source time convolution\n"
132 <<
"and detector time convolution. It is designed for use in\n"
133 <<
"activation physics.\n"
134 <<
"The required half-lives and decay schemes are retrieved from\n"
135 <<
"the RadioactiveDecay database which was derived from ENSDF.\n";
147 DecayTableMap::iterator table_ptr =
dkmap->find(key);
150 if (table_ptr ==
dkmap->end() ) {
152 if(theDecayTable) (*dkmap)[key] = theDecayTable;
154 theDecayTable = table_ptr->second;
156 return theDecayTable;
165 for (std::size_t i = 0; i < theParentChainTable.size(); ++i) {
166 if (theParentChainTable[i].GetIonName() == aParticleName)
return true;
178 for (std::size_t i = 0; i < theParentChainTable.size(); ++i) {
179 if (theParentChainTable[i].GetIonName() == aParticleName) {
180 theDecayRateVector = theParentChainTable[i].GetItsRates();
185 G4cout <<
"The DecayRate Table for " << aParticleName <<
" is selected."
202 if ( t > SBin[NSourceBin]) {
208 while (t > SBin[nbin]) {
211 G4Exception(
"G4Radioactivation::ConvolveSourceTimeProfile()",
212 "HAD_RDM_100",
JustWarning,
"While loop count exceeded");
224 for (
G4int i = 0; i < nbin; i++) {
225 earg = (SBin[i+1] - SBin[i])/tau;
227 convolvedTime += SProfile[i] * std::exp((SBin[i] - t)/tau) *
230 convolvedTime += SProfile[i] *
231 (std::exp(-(t-SBin[i+1])/tau)-std::exp(-(t-SBin[i])/tau));
235 convolvedTime -= SProfile[nbin] * std::expm1((SBin[nbin] - t)/tau);
238 if (convolvedTime < 0.) {
239 G4cout <<
" Convolved time =: " << convolvedTime <<
" reset to zero! " <<
G4endl;
246 G4cout <<
" Convolved time: " << convolvedTime <<
G4endl;
248 return convolvedTime;
267 while (DProfile[i] < rand) {
273 G4Exception(
"G4Radioactivation::GetDecayTime()",
"HAD_RDM_100",
280 decaytime = DBin[i] + rand*(DBin[i+1]-DBin[i]);
283 G4cout <<
" Decay time: " <<decaytime/s <<
"[s]" <<
G4endl;
294 while (aDecayTime > DBin[i] ) {
298 G4Exception(
"G4Radioactivation::GetDecayTimeBin()",
"HAD_RDM_100",
327 G4int theG, std::vector<G4double> theCoefficients,
328 std::vector<G4double> theTaos)
332 ratesToDaughter.
SetZ(theZ);
333 ratesToDaughter.
SetA(theA);
334 ratesToDaughter.
SetE(theE);
337 ratesToDaughter.
SetTaos(theTaos);
351 theDecayRateVector.clear();
353 G4int nGeneration = 0;
355 std::vector<G4double> taos;
358 std::vector<G4double> Acoeffs;
361 Acoeffs.push_back(-1.);
363 G4int A = ((
const G4Ions*)(&theParentNucleus))->GetAtomicMass();
364 G4int Z = ((
const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
365 G4double E = ((
const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
367 if (tao < 0.) tao = 1e-100;
376 theDecayRateVector.push_back(ratesToDaughter);
402 std::vector<G4double> TP;
403 std::vector<G4double> RP;
407 G4int nearestLevelIndex = 0;
425 G4Exception(
"G4Radioactivation::CalculateChainsFromParent()",
"HAD_RDM_100",
430 for (j = nS; j < nT; j++) {
432 ZP = theDecayRateVector[j].GetZ();
433 AP = theDecayRateVector[j].GetA();
434 EP = theDecayRateVector[j].GetE();
435 RP = theDecayRateVector[j].GetDecayRateC();
436 TP = theDecayRateVector[j].GetTaos();
438 G4cout <<
"G4RadioactiveDecay::CalculateChainsFromParent: daughters of ("
439 << ZP <<
", " << AP <<
", " << EP
440 <<
") are being calculated, generation = " << nGeneration
447 aParentNucleus = theIonTable->
GetIon(ZP,AP,EP);
460 for (
G4int k = 0; k < nMode; k++) brs[k] = 0.0;
463 for (
G4int i = 0; i < parentDecayTable->
entries(); i++) {
465 theNuclearDecayChannel =
static_cast<G4NuclearDecay*
>(theChannel);
469 AD = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
470 ZD = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
479 if (std::abs(daughterExcitation - nearestEnergy) <
levelTolerance) {
483 if (levelManager->
LifeTime(nearestLevelIndex)*
ns >= halflifethreshold){
485 summedDecayTable->
Insert(theChannel);
487 brs[theDecayMode] += theChannel->
GetBR();
490 brs[theDecayMode] += theChannel->
GetBR();
493 brs[theDecayMode] += theChannel->
GetBR();
500 for (
G4int i = 0; i < nMode; i++) {
505 theITChannel =
new G4ITDecay(aParentNucleus, brs[
IT], 0.0, 0.0,
508 summedDecayTable->
Insert(theITChannel);
516 summedDecayTable->
Insert(theBetaMinusChannel);
524 summedDecayTable->
Insert(theBetaPlusChannel);
531 summedDecayTable->
Insert(theAlphaChannel);
538 summedDecayTable->
Insert(theProtonChannel);
545 summedDecayTable->
Insert(theNeutronChannel);
552 summedDecayTable->
Insert(theFissionChannel);
583 summedDecayTable->
Insert(theTritonChannel);
594 for (
G4int i = 0; i < summedDecayTable->
entries(); i++){
596 theNuclearDecayChannel =
static_cast<G4NuclearDecay*
>(theChannel);
597 theBR = theChannel->
GetBR();
602 if (theNuclearDecayChannel->
GetDecayMode() ==
IT && nGeneration == 1) {
604 A = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
605 Z = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
606 theDaughterNucleus=theIonTable->
GetIon(
Z,
A,0.);
609 aParentNucleus != theDaughterNucleus) {
612 if (parentDecayTable->
entries() ) {
613 A = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
614 Z = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
615 E = ((
const G4Ions*)(theDaughterNucleus))->GetExcitationEnergy();
618 if (TaoPlus <= 0.) TaoPlus = 1e-100;
628 taos.push_back(TaoPlus);
635 ta2 = (
long double)TaoPlus;
636 for (k = 0; k < RP.size(); k++){
637 ta1 = (
long double)TP[k];
641 theRate = ta1/(ta1-ta2);
643 theRate = theRate * theBR * RP[k];
644 Acoeffs.push_back(theRate);
651 long double aRate, aRate1;
653 for (k = 0; k < RP.size(); k++){
654 ta1 = (
long double)TP[k];
658 aRate = ta2/(ta1-ta2);
660 aRate = aRate * (
long double)(theBR * RP[k]);
664 Acoeffs.push_back(theRate);
666 theDecayRateVector.push_back(ratesToDaughter);
672 delete summedDecayTable;
677 if (nS == nT) stable =
true;
692 theParentChainTable.push_back(chainsFromParent);
704 std::ifstream infile ( filename, std::ios::in );
707 ed <<
" Could not open file " << filename <<
G4endl;
708 G4Exception(
"G4Radioactivation::SetSourceTimeProfile()",
"HAD_RDM_001",
716 while (infile >> bin >> flux) {
719 G4Exception(
"G4Radioactivation::SetSourceTimeProfile()",
"HAD_RDM_100",
725 if (NSourceBin > 99) {
726 G4Exception(
"G4Radioactivation::SetSourceTimeProfile()",
"HAD_RDM_002",
730 SBin[NSourceBin] = bin * s;
731 SProfile[NSourceBin] = flux;
740 G4cout <<
" Source Timeprofile Nbin = " << NSourceBin <<
G4endl;
753 std::ifstream infile(filename, std::ios::in);
754 if (!infile)
G4Exception(
"G4Radioactivation::SetDecayBias()",
"HAD_RDM_001",
761 theRadioactivityTables.clear();
766 while (infile >> bin >> flux ) {
770 G4Exception(
"G4Radioactivation::SetDecayBias()",
"HAD_RDM_100",
775 if (NDecayBin > 99) {
776 G4Exception(
"G4Radioactivation::SetDecayBias()",
"HAD_RDM_002",
779 DBin[NDecayBin] = bin * s;
780 DProfile[NDecayBin] = flux;
782 decayWindows[NDecayBin] = dWindows;
785 theRadioactivityTables.push_back(rTable);
789 for ( i = 1; i<= NDecayBin; i++) DProfile[i] += DProfile[i-1];
790 for ( i = 0; i<= NDecayBin; i++) DProfile[i] /= DProfile[NDecayBin];
799 G4cout <<
" Decay Bias Profile Nbin = " << NDecayBin <<
G4endl;
824 G4cout <<
"G4RadioactiveDecay::DecayIt : "
826 <<
" is not selected for the RDM"<<
G4endl;
848 G4cout <<
"G4RadioactiveDecay::DecayIt : "
850 <<
" is not an ion or is outside (Z,A) limits set for the decay. "
851 <<
" Set particle change accordingly. "
866 if (theDecayTable == 0 || theDecayTable->
entries() == 0) {
871 G4cout <<
"G4RadioactiveDecay::DecayIt : "
872 <<
"decay table not defined for "
874 <<
". Set particle change accordingly. "
912 std::vector<G4double> PT;
913 std::vector<G4double> PR;
915 long double decayRate;
918 G4int numberOfSecondaries;
919 G4int totalNumberOfSecondaries = 0;
923 std::vector<G4DynamicParticle*> secondaryparticles;
924 std::vector<G4double> pw;
925 std::vector<G4double> ptime;
930 for (
G4int n = 0; n < NSplit; n++) {
939 weight1 = 1./DProfile[nbin-1]
940 *(DBin[nbin]-DBin[nbin-1])/NSplit;
941 }
else if (nbin > 1) {
943 weight1 = 1./(DProfile[nbin]-DProfile[nbin-2])
944 *(DBin[nbin]-DBin[nbin-1])/NSplit;
952 for (i = 0; i < theDecayRateVector.size(); i++) {
953 PZ = theDecayRateVector[i].GetZ();
954 PA = theDecayRateVector[i].GetA();
955 PE = theDecayRateVector[i].GetE();
956 PT = theDecayRateVector[i].GetTaos();
957 PR = theDecayRateVector[i].GetDecayRateC();
1005 for (
G4int j = 0; j <
G4int(PT.size() ); j++) {
1007 decayRate -= PR[j] * (
long double)taotime;
1019 if (decayRate < 0.0) decayRate = 0.0;
1028 theRadioactivityTables[decayWindows[nbin-1]]
1029 ->AddIsotope(PZ,PA,PE,weight1*decayRate,theTrack.
GetWeight());
1038 parentNucleus = theIonTable->
GetIon(PZ,PA,PE);
1050 if (theDecayChannel == 0) {
1054 G4cout <<
" G4RadioactiveDecay::DoIt : cannot determine decay channel ";
1055 G4cout <<
" for this nucleus; decay as if no biasing active. ";
1060 tempprods =
DoDecay(*parentNucleus);
1065 tempprods = theDecayChannel->
DecayIt(tempmass);
1066 weight *= (theDecayChannel->
GetBR())*(decayTable->
entries());
1069 tempprods =
DoDecay(*parentNucleus);
1073 numberOfSecondaries = tempprods->
entries();
1074 currentTime = finalGlobalTime + theDecayTime;
1075 for (index = 0; index < numberOfSecondaries; ++index) {
1078 pw.push_back(weight);
1079 ptime.push_back(currentTime);
1080 secondaryparticles.push_back(asecondaryparticle);
1084 ->GetExcitationEnergy() > 0. && weight > 0.) {
1087 ptime,secondaryparticles);
1097 totalNumberOfSecondaries = (
G4int)pw.size();
1099 for (index=0; index < totalNumberOfSecondaries; ++index) {
1101 ptime[index], currentPosition);
1125 std::vector<double>& weights_v,
1126 std::vector<double>& times_v,
1127 std::vector<G4DynamicParticle*>& secondaries_v)
1129 G4double elevel=((
const G4Ions*)(apartDef))->GetExcitationEnergy();
1133 while (life_time < halflifethreshold && elevel > 0.) {
1140 for (
G4int ind = 0; ind < nb_pevapSecondaries; ind++) {
1145 elevel = ((
const G4Ions*)(secDef))->GetExcitationEnergy();
1149 weights_v.push_back(weight);
1150 times_v.push_back(currentTime);
1151 secondaries_v.push_back(a_pevap_secondary);
1154 weights_v.push_back(weight);
1155 times_v.push_back(currentTime);
1156 secondaries_v.push_back(a_pevap_secondary);
1161 delete pevap_products;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ G4RadioactiveDecayModeSize
G4GLOB_DLL std::ostream G4cout
G4DynamicParticle * PopProducts()
G4VDecayChannel * GetDecayChannel(G4int index) const
void Insert(G4VDecayChannel *aChannel)
G4ParticleDefinition * GetDefinition() const
virtual G4DecayProducts * DecayIt(G4double)
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
std::size_t NearestLevelIndex(const G4double energy, const std::size_t index=0) const
std::size_t NumberOfTransitions() const
G4double LifeTime(const std::size_t i) const
G4double NearestLevelEnergy(const G4double energy, const std::size_t index=0) const
const G4String & GetName() const
G4double GetDaughterExcitation()
G4ParticleDefinition * GetDaughterNucleus()
G4RadioactiveDecayMode GetDecayMode()
const G4LevelManager * GetLevelManager(G4int Z, G4int A)
static G4NuclearLevelData * GetInstance()
void Initialize(const G4Track &) final
void ProposeLocalTime(G4double t)
G4bool GetPDGStable() const
G4double GetPDGMass() const
G4int GetBaryonNumber() const
G4double GetPDGLifeTime() const
const G4String & GetParticleName() const
G4IonTable * GetIonTable() const
static G4ParticleTable * GetParticleTable()
G4int GetDecayTimeBin(const G4double aDecayTime)
void AddDeexcitationSpectrumForBiasMode(G4ParticleDefinition *apartDef, G4double weight, G4double currenTime, std::vector< double > &weights_v, std::vector< double > ×_v, std::vector< G4DynamicParticle * > &secondaries_v)
void SetDecayBias(G4String filename)
G4bool IsRateTableReady(const G4ParticleDefinition &)
virtual void ProcessDescription(std::ostream &outFile) const
G4Radioactivation(const G4String &processName="Radioactivation")
G4VParticleChange * DecayIt(const G4Track &theTrack, const G4Step &theStep)
G4double ConvolveSourceTimeProfile(const G4double, const G4double)
void CalculateChainsFromParent(const G4ParticleDefinition &)
void SetDecayRate(G4int, G4int, G4double, G4int, std::vector< G4double >, std::vector< G4double >)
G4DecayTable * GetDecayTable1(const G4ParticleDefinition *)
void SetSourceTimeProfile(G4String filename)
void GetChainsFromParent(const G4ParticleDefinition &)
G4double GetMeanLifeTime(const G4Track &theTrack, G4ForceCondition *condition)
G4RadioactivationMessenger * theRadioactivationMessenger
void SetIonName(G4String name)
void SetItsRates(G4RadioactiveDecayRates arate)
void SetE(G4double value)
void SetTaos(std::vector< G4double > value)
void SetDecayRateC(std::vector< G4double > value)
void SetGeneration(G4int value)
void DecayAnalog(const G4Track &theTrack)
std::vector< G4String > ValidVolumes
G4DecayTable * LoadDecayTable(const G4ParticleDefinition &theParentNucleus)
G4double GetMeanLifeTime(const G4Track &theTrack, G4ForceCondition *condition)
G4DecayProducts * DoDecay(const G4ParticleDefinition &theParticleDef)
static const G4double levelTolerance
G4ParticleChangeForRadDecay fParticleChangeForRadDecay
G4int GetVerboseLevel() const
G4bool IsApplicable(const G4ParticleDefinition &)
G4PhotonEvaporation * photonEvaporation
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
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
void SetGoodForTrackingFlag(G4bool value=true)
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
void ProposeTrackStatus(G4TrackStatus status)
void ProposeWeight(G4double finalWeight)
void AddSecondary(G4Track *aSecondary)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4LogicalVolume * GetLogicalVolume() const
void ClearNumberOfInteractionLengthLeft()