Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
#include "G4BetaPlusDecay.hh"
|
||||
#include "G4ECDecay.hh"
|
||||
#include "G4AlphaDecay.hh"
|
||||
#include "G4TritonDecay.hh"
|
||||
#include "G4ProtonDecay.hh"
|
||||
#include "G4NeutronDecay.hh"
|
||||
#include "G4SFDecay.hh"
|
||||
@@ -71,6 +72,7 @@
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4Triton.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
#include "G4HadronicProcessType.hh"
|
||||
@@ -98,7 +100,7 @@ G4Radioactivation::G4Radioactivation(const G4String& processName)
|
||||
}
|
||||
#endif
|
||||
|
||||
SetProcessSubType(fRadioactiveDecay);
|
||||
// DHW SetProcessSubType(fRadioactiveDecay);
|
||||
theRadioactivationMessenger = new G4RadioactivationMessenger(this);
|
||||
|
||||
// Apply default values.
|
||||
@@ -118,7 +120,7 @@ G4Radioactivation::G4Radioactivation(const G4String& processName)
|
||||
NSplit = 1;
|
||||
AnalogueMC = true;
|
||||
BRBias = true;
|
||||
halflifethreshold = nanosecond;
|
||||
halflifethreshold = 1000.*nanosecond;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +141,20 @@ G4Radioactivation::~G4Radioactivation()
|
||||
delete theRadioactivationMessenger;
|
||||
}
|
||||
|
||||
G4DecayTable* G4Radioactivation::GetDecayTable1(const G4ParticleDefinition* aNucleus)
|
||||
{
|
||||
G4String key = aNucleus->GetParticleName();
|
||||
DecayTableMap::iterator table_ptr = dkmap->find(key);
|
||||
|
||||
G4DecayTable* theDecayTable = 0;
|
||||
if (table_ptr == dkmap->end() ) { // If table not there,
|
||||
theDecayTable = LoadDecayTable(*aNucleus); // load from file and
|
||||
if(theDecayTable) (*dkmap)[key] = theDecayTable; // store in library
|
||||
} else {
|
||||
theDecayTable = table_ptr->second;
|
||||
}
|
||||
return theDecayTable;
|
||||
}
|
||||
|
||||
G4bool
|
||||
G4Radioactivation::IsRateTableReady(const G4ParticleDefinition& aParticle)
|
||||
@@ -288,6 +304,23 @@ G4int G4Radioactivation::GetDecayTimeBin(const G4double aDecayTime)
|
||||
return i;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// GetMeanLifeTime (required by the base class) //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4Radioactivation::GetMeanLifeTime(const G4Track& theTrack,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
// For variance reduction time is set to 0 so as to force the particle
|
||||
// to decay immediately.
|
||||
// In analogue mode it returns the particle's mean-life.
|
||||
G4double meanlife = 0.;
|
||||
if (AnalogueMC) meanlife = G4RadioactiveDecayBase::GetMeanLifeTime(theTrack, 0);
|
||||
return meanlife;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
G4Radioactivation::SetDecayRate(G4int theZ, G4int theA, G4double theE,
|
||||
@@ -345,7 +378,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
|
||||
// Now start treating the secondary generations.
|
||||
G4bool stable = false;
|
||||
G4int i;
|
||||
// G4int i;
|
||||
G4int j;
|
||||
G4VDecayChannel* theChannel = 0;
|
||||
G4NuclearDecay* theNuclearDecayChannel = 0;
|
||||
@@ -355,6 +388,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
G4BetaPlusDecay* theBetaPlusChannel = 0;
|
||||
G4AlphaDecay* theAlphaChannel = 0;
|
||||
G4ProtonDecay* theProtonChannel = 0;
|
||||
G4TritonDecay* theTritonChannel = 0;
|
||||
G4NeutronDecay* theNeutronChannel = 0;
|
||||
G4SFDecay* theFissionChannel = 0;
|
||||
|
||||
@@ -378,7 +412,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
G4double TaoPlus;
|
||||
G4int nS = 0; // Running index of first decay in a given generation
|
||||
G4int nT = nEntry; // Total number of decays accumulated over entire history
|
||||
const G4int nMode = 11;
|
||||
const G4int nMode = 12;
|
||||
G4double brs[nMode];
|
||||
//
|
||||
theIonTable =
|
||||
@@ -411,7 +445,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
// G4cout << G4endl;
|
||||
|
||||
aParentNucleus = theIonTable->GetIon(ZP,AP,EP);
|
||||
parentDecayTable = GetDecayTable(aParentNucleus);
|
||||
parentDecayTable = GetDecayTable1(aParentNucleus);
|
||||
|
||||
G4DecayTable* summedDecayTable = new G4DecayTable();
|
||||
// This instance of G4DecayTable is for accumulating BRs and decay
|
||||
@@ -426,18 +460,20 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
for (G4int k = 0; k < nMode; k++) brs[k] = 0.0;
|
||||
|
||||
// Go through the decay table and sum all channels having the same decay mode
|
||||
for (i = 0; i < parentDecayTable->entries(); i++) {
|
||||
for (G4int i = 0; i < parentDecayTable->entries(); i++) {
|
||||
theChannel = parentDecayTable->GetDecayChannel(i);
|
||||
theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
|
||||
theDecayMode = theNuclearDecayChannel->GetDecayMode();
|
||||
daughterExcitation = theNuclearDecayChannel->GetDaughterExcitation();
|
||||
theDaughterNucleus = theNuclearDecayChannel->GetDaughterNucleus() ;
|
||||
|
||||
AD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
|
||||
ZD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
|
||||
const G4LevelManager* levelManager =
|
||||
G4NuclearLevelData::GetInstance()->GetLevelManager(ZD,AD);
|
||||
|
||||
// Check each nuclide to see if it is metastable (lifetime > 1 usec)
|
||||
// If so, add it to the decay chain by inserting its decay channel in
|
||||
// summedDecayTable. If not, just add its BR to sum for that decay mode.
|
||||
if (levelManager->NumberOfTransitions() ) {
|
||||
nearestEnergy = levelManager->NearestLevelEnergy(daughterExcitation);
|
||||
if (std::abs(daughterExcitation - nearestEnergy) < levelTolerance) {
|
||||
@@ -445,7 +481,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
// by default, user can set it via the UI command
|
||||
nearestLevelIndex = levelManager->NearestLevelIndex(daughterExcitation);
|
||||
if (levelManager->LifeTime(nearestLevelIndex)*ns >= halflifethreshold){
|
||||
// save the metastable nucleus
|
||||
// save the metastable decay channel
|
||||
summedDecayTable->Insert(theChannel);
|
||||
} else {
|
||||
brs[theDecayMode] += theChannel->GetBR();
|
||||
@@ -456,11 +492,12 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
} else {
|
||||
brs[theDecayMode] += theChannel->GetBR();
|
||||
}
|
||||
|
||||
} // Combine decay channels (loop i)
|
||||
|
||||
|
||||
brs[2] = brs[2]+brs[3]+brs[4]+brs[5]+brs[6]; // Combine beta+ and EC
|
||||
brs[3] = brs[4] = brs[5] = brs[6] = 0.0;
|
||||
for (i = 0; i < nMode; i++) { // loop over decay modes
|
||||
for (G4int i = 0; i < nMode; i++) { // loop over decay modes
|
||||
if (brs[i] > 0.) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
@@ -481,7 +518,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
|
||||
case 2:
|
||||
// Decay mode is beta+ + EC.
|
||||
theBetaPlusChannel = new G4BetaPlusDecay(aParentNucleus, brs[2], // DHW: April 2015
|
||||
theBetaPlusChannel = new G4BetaPlusDecay(aParentNucleus, brs[2],
|
||||
0.*MeV, 0.*MeV,
|
||||
noFloat, allowed);
|
||||
summedDecayTable->Insert(theBetaPlusChannel);
|
||||
@@ -514,15 +551,22 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
0.*MeV, noFloat);
|
||||
summedDecayTable->Insert(theFissionChannel);
|
||||
break;
|
||||
case 11:
|
||||
// Decay mode is Triton.
|
||||
theTritonChannel = new G4TritonDecay(aParentNucleus, brs[9], 0.*MeV,
|
||||
0.*MeV, noFloat);
|
||||
summedDecayTable->Insert(theTritonChannel);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loop over all branches in summedDecayTable
|
||||
//
|
||||
for (i = 0; i < summedDecayTable->entries(); i++){
|
||||
for (G4int i = 0; i < summedDecayTable->entries(); i++){
|
||||
theChannel = summedDecayTable->GetDecayChannel(i);
|
||||
theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
|
||||
theBR = theChannel->GetBR();
|
||||
@@ -536,11 +580,10 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
Z = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
|
||||
theDaughterNucleus=theIonTable->GetIon(Z,A,0.);
|
||||
}
|
||||
if (IsApplicable(*theDaughterNucleus) && theBR &&
|
||||
if (IsApplicable(*theDaughterNucleus) && theBR > 0.0 &&
|
||||
aParentNucleus != theDaughterNucleus) {
|
||||
// need to make sure daughter has decay table
|
||||
parentDecayTable = GetDecayTable(theDaughterNucleus);
|
||||
|
||||
parentDecayTable = GetDecayTable1(theDaughterNucleus);
|
||||
if (parentDecayTable->entries() ) {
|
||||
A = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
|
||||
Z = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
|
||||
@@ -776,13 +819,13 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
if (!(IsApplicable(*theParticleDef) ) ) {
|
||||
// Particle is not an ion or is outside the nucleuslimits for decay
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cerr << "G4RadioactiveDecay::DecayIt : "
|
||||
<< theParticleDef->GetParticleName()
|
||||
<< " is not a valid nucleus for the RDM"<< G4endl;
|
||||
if (GetVerboseLevel() > 0) {
|
||||
G4cout << "G4RadioactiveDecay::DecayIt : "
|
||||
<< theParticleDef->GetParticleName()
|
||||
<< " is not an ion or is outside (Z,A) limits set for the decay. "
|
||||
<< " Set particle change accordingly. "
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
|
||||
|
||||
// Kill the parent particle
|
||||
@@ -791,17 +834,20 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return &fParticleChangeForRadDecay;
|
||||
}
|
||||
G4DecayTable* theDecayTable = GetDecayTable(theParticleDef);
|
||||
|
||||
G4DecayTable* theDecayTable = GetDecayTable1(theParticleDef);
|
||||
|
||||
if (theDecayTable == 0 || theDecayTable->entries() == 0) {
|
||||
// No data in the decay table. Set particle change parameters
|
||||
// to indicate this.
|
||||
#ifdef G4VERBOSE
|
||||
|
||||
if (GetVerboseLevel() > 0) {
|
||||
G4cerr <<"G4RadioactiveDecay::DecayIt : decay table not defined for ";
|
||||
G4cerr <<theParticleDef->GetParticleName() <<G4endl;
|
||||
G4cout << "G4RadioactiveDecay::DecayIt : "
|
||||
<< "decay table not defined for "
|
||||
<< theParticleDef->GetParticleName()
|
||||
<< ". Set particle change accordingly. "
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
|
||||
|
||||
// Kill the parent particle.
|
||||
@@ -812,20 +858,28 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
|
||||
} else {
|
||||
// Data found. Try to decay nucleus
|
||||
if (AnalogueMC) {
|
||||
G4RadioactiveDecayBase::DecayAnalog(theTrack);
|
||||
|
||||
} else {
|
||||
// Proceed with decay using variance reduction
|
||||
G4double energyDeposit = 0.0;
|
||||
G4double finalGlobalTime = theTrack.GetGlobalTime();
|
||||
G4double finalLocalTime = theTrack.GetLocalTime();
|
||||
G4double finalLocalTime = theTrack.GetLocalTime();
|
||||
G4int index;
|
||||
G4ThreeVector currentPosition;
|
||||
currentPosition = theTrack.GetPosition();
|
||||
|
||||
G4IonTable* theIonTable;
|
||||
G4ParticleDefinition* parentNucleus;
|
||||
|
||||
// Get decay chains for the given nuclide
|
||||
if (!IsRateTableReady(*theParticleDef)) CalculateChainsFromParent(*theParticleDef);
|
||||
GetChainsFromParent(*theParticleDef);
|
||||
|
||||
// Declare some of the variables required in the implementation
|
||||
G4ParticleDefinition* parentNucleus;
|
||||
G4IonTable* theIonTable;
|
||||
// G4ParticleDefinition* parentNucleus;
|
||||
// G4IonTable* theIonTable;
|
||||
G4int PZ;
|
||||
G4int PA;
|
||||
G4double PE;
|
||||
@@ -836,7 +890,7 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
long double decayRate;
|
||||
|
||||
size_t i;
|
||||
size_t j;
|
||||
// size_t j;
|
||||
G4int numberOfSecondaries;
|
||||
G4int totalNumberOfSecondaries = 0;
|
||||
G4double currentTime = 0.;
|
||||
@@ -851,7 +905,7 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
// Now apply the nucleus splitting
|
||||
for (G4int n = 0; n < NSplit; n++) {
|
||||
// Get the decay time following the decay probability function
|
||||
// suppllied by user
|
||||
// supplied by user
|
||||
G4double theDecayTime = GetDecayTime();
|
||||
G4int nbin = GetDecayTimeBin(theDecayTime);
|
||||
|
||||
@@ -866,7 +920,6 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
*(DBin[nbin]-DBin[nbin-1])/NSplit;
|
||||
// weight1 = (probability of choosing one of the bins)*(time width of bin)/NSplit
|
||||
}
|
||||
|
||||
// it should be calculated in seconds
|
||||
weight1 /= s ;
|
||||
|
||||
@@ -925,7 +978,7 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
// For each nuclide, calculate all the decay chains which can reach
|
||||
// the parent nuclide
|
||||
decayRate = 0.L;
|
||||
for (j = 0; j < PT.size(); j++) {
|
||||
for (G4int j = 0; j < G4int(PT.size() ); j++) {
|
||||
// G4cout << " RDM::DecayIt: tau input to Convolve: " << PT[j] << G4endl;
|
||||
taotime = ConvolveSourceTimeProfile(theDecayTime,PT[j]);
|
||||
// taotime = GetTaoTime(theDecayTime,PT[j]);
|
||||
@@ -942,29 +995,31 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
// (order 10**-30) that negative values are likely due to cancellation
|
||||
// errors. Set them to zero.
|
||||
if (decayRate < 0.0) decayRate = 0.0;
|
||||
/*
|
||||
if (decayRate < 0.0) {
|
||||
if (-decayRate > 1.0e-30) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative decay probability (magnitude > 1e-30) \n"
|
||||
<< " in variance reduction branch " << G4endl;
|
||||
G4Exception("G4RadioactiveDecay::DecayIt()",
|
||||
"HAD_RDM_200", JustWarning, ed);
|
||||
} else {
|
||||
// Decay probability is small enough that negative value is likely
|
||||
// due to cancellation errors. Set it to zero.
|
||||
decayRate = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (decayRate < 0.0) G4cout << " NEGATIVE decay rate = " << decayRate << G4endl;
|
||||
*/
|
||||
// // Test code
|
||||
// if (decayRate < 0.0) {
|
||||
// if (-decayRate > 1.0e-30) {
|
||||
// G4ExceptionDescription ed;
|
||||
// ed << " Negative decay probability (magnitude > 1e-30) \n"
|
||||
// << " in variance reduction branch " << G4endl;
|
||||
// G4Exception("G4RadioactiveDecay::DecayIt()",
|
||||
// "HAD_RDM_200", JustWarning, ed);
|
||||
// } else {
|
||||
// // Decay probability is small enough that negative value is likely
|
||||
// // due to cancellation errors. Set it to zero.
|
||||
// decayRate = 0.0;
|
||||
// }
|
||||
// }
|
||||
// G4cout << " VR in i loop after decayRate < 0 " << G4endl;
|
||||
// if (decayRate < 0.0) G4cout << " NEGATIVE decay rate = " << decayRate << G4endl;
|
||||
|
||||
// G4cout <<theDecayTime/s <<"\t"<<nbin<<G4endl;
|
||||
// G4cout << theTrack.GetWeight() <<"\t"<<weight1<<"\t"<<decayRate<< G4endl;
|
||||
|
||||
// Add isotope to the radioactivity tables
|
||||
// One table for each observation time window specifed in
|
||||
// SetDecayBias(G4String filename)
|
||||
|
||||
theRadioactivityTables[decayWindows[nbin-1]]
|
||||
->AddIsotope(PZ,PA,PE,weight1*decayRate,theTrack.GetWeight());
|
||||
|
||||
@@ -981,22 +1036,22 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
// Its contents to be transfered to the products at the end of the loop
|
||||
G4DecayProducts* tempprods = 0;
|
||||
|
||||
// Decide whether to apply branching ratio bias or not
|
||||
// Decide whether to apply branching ratio bias or not
|
||||
if (BRBias) {
|
||||
G4DecayTable* decayTable = GetDecayTable(parentNucleus);
|
||||
|
||||
G4DecayTable* decayTable = GetDecayTable1(parentNucleus);
|
||||
ndecaych = G4int(decayTable->entries()*G4UniformRand());
|
||||
G4VDecayChannel* theDecayChannel = decayTable->GetDecayChannel(ndecaych);
|
||||
|
||||
if (theDecayChannel == 0) {
|
||||
// Decay channel not found.
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cerr << " G4RadioactiveDecay::DoIt : cannot determine decay channel ";
|
||||
G4cerr << " for this nucleus; decay as if no biasing active ";
|
||||
G4cerr << G4endl;
|
||||
|
||||
if (GetVerboseLevel() > 0) {
|
||||
G4cout << " G4RadioactiveDecay::DoIt : cannot determine decay channel ";
|
||||
G4cout << " for this nucleus; decay as if no biasing active. ";
|
||||
G4cout << G4endl;
|
||||
decayTable ->DumpInfo();
|
||||
}
|
||||
#endif
|
||||
|
||||
tempprods = DoDecay(*parentNucleus); // DHW 6 Dec 2010 - do decay as if no biasing
|
||||
// to avoid deref of temppprods = 0
|
||||
} else {
|
||||
@@ -1025,8 +1080,8 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
AddDeexcitationSpectrumForBiasMode(apartDef,weight,currentTime,pw,ptime,secondaryparticles);
|
||||
}
|
||||
}
|
||||
delete tempprods;
|
||||
|
||||
delete tempprods;
|
||||
} // end of i loop
|
||||
} // end of n loop
|
||||
|
||||
@@ -1049,9 +1104,10 @@ G4Radioactivation::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
fParticleChangeForRadDecay.ProposeLocalTime(finalLocalTime);
|
||||
// Reset NumberOfInteractionLengthLeft.
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
} // end VR decay
|
||||
|
||||
return &fParticleChangeForRadDecay;
|
||||
}
|
||||
} // end of data found branch
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
#include "G4BetaPlusDecay.hh"
|
||||
#include "G4ECDecay.hh"
|
||||
#include "G4AlphaDecay.hh"
|
||||
#include "G4TritonDecay.hh"
|
||||
#include "G4ProtonDecay.hh"
|
||||
#include "G4NeutronDecay.hh"
|
||||
#include "G4SFDecay.hh"
|
||||
@@ -134,6 +135,7 @@
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4Triton.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
#include "G4HadronicProcessType.hh"
|
||||
@@ -187,7 +189,7 @@ G4RadioactiveDecay::G4RadioactiveDecay(const G4String& processName)
|
||||
photonEvaporation->SetICM(true);
|
||||
|
||||
// Check data directory
|
||||
char* path_var = getenv("G4RADIOACTIVEDATA");
|
||||
char* path_var = std::getenv("G4RADIOACTIVEDATA");
|
||||
if (!path_var) {
|
||||
G4Exception("G4RadioactiveDecay()","HAD_RDM_200",FatalException,
|
||||
"Environment variable G4RADIOACTIVEDATA is not set");
|
||||
@@ -827,7 +829,7 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
|
||||
if (DecaySchemeFile.good()) {
|
||||
// Initialize variables used for reading in radioactive decay data
|
||||
G4bool floatMatch(false);
|
||||
const G4int nMode = 11;
|
||||
const G4int nMode = 12;
|
||||
G4double modeTotalBR[nMode] = {0.0};
|
||||
G4double modeSumBR[nMode];
|
||||
for (G4int i = 0; i < nMode; i++) {
|
||||
@@ -937,6 +939,8 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
|
||||
break;
|
||||
case SpFission:
|
||||
modeTotalBR[10] = decayModeTotal; break;
|
||||
case Triton:
|
||||
modeTotalBR[11] = decayModeTotal; break;
|
||||
case RDM_ERROR:
|
||||
|
||||
default:
|
||||
@@ -1106,6 +1110,17 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
|
||||
modeSumBR[10] += b;
|
||||
}
|
||||
break;
|
||||
case Triton:
|
||||
{
|
||||
G4TritonDecay* aTritonChannel =
|
||||
new G4TritonDecay(&theParentNucleus, b, c*MeV, a*MeV,
|
||||
daughterFloatLevel);
|
||||
// anTritonChannel->DumpNuclearInfo();
|
||||
aTritonChannel->SetHLThreshold(halflifethreshold);
|
||||
theDecayTable->Insert(aTritonChannel);
|
||||
modeSumBR[11] += b;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDM_ERROR:
|
||||
|
||||
@@ -1241,6 +1256,7 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
G4BetaPlusDecay* theBetaPlusChannel = 0;
|
||||
G4AlphaDecay* theAlphaChannel = 0;
|
||||
G4ProtonDecay* theProtonChannel = 0;
|
||||
G4TritonDecay* theTritonChannel = 0;
|
||||
G4NeutronDecay* theNeutronChannel = 0;
|
||||
G4SFDecay* theFissionChannel = 0;
|
||||
|
||||
@@ -1264,8 +1280,9 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
G4double TaoPlus;
|
||||
G4int nS = 0; // Running index of first decay in a given generation
|
||||
G4int nT = nEntry; // Total number of decays accumulated over entire history
|
||||
const G4int nMode = 11;
|
||||
const G4int nMode = 12;
|
||||
G4double brs[nMode];
|
||||
|
||||
//
|
||||
theIonTable =
|
||||
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
|
||||
@@ -1401,7 +1418,13 @@ CalculateChainsFromParent(const G4ParticleDefinition& theParentNucleus)
|
||||
0.*MeV, noFloat);
|
||||
summedDecayTable->Insert(theFissionChannel);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
// Decay mode is triton.
|
||||
theTritonChannel = new G4TritonDecay(aParentNucleus, brs[11], 0.*MeV,
|
||||
0.*MeV, noFloat);
|
||||
summedDecayTable->Insert(theTritonChannel);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1772,6 +1795,17 @@ G4RadioactiveDecay::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
for (index=0; index < numberOfSecondaries; index++) {
|
||||
G4Track* secondary = new G4Track(products->PopProducts(),
|
||||
finalGlobalTime, currentPosition);
|
||||
|
||||
secondary->SetCreatorModelIndex(theRadDecayMode);
|
||||
//Change for atomics relaxation
|
||||
if (theRadDecayMode == IT && index>0){
|
||||
if (index == numberOfSecondaries-1) secondary->SetCreatorModelIndex(IT);
|
||||
else secondary->SetCreatorModelIndex(30);
|
||||
}
|
||||
else if (theRadDecayMode >= KshellEC && theRadDecayMode <= NshellEC
|
||||
&& index <numberOfSecondaries-1){
|
||||
secondary->SetCreatorModelIndex(30);
|
||||
}
|
||||
secondary->SetGoodForTrackingFlag();
|
||||
secondary->SetTouchableHandle(theTrack.GetTouchableHandle());
|
||||
fParticleChangeForRadDecay.AddSecondary(secondary);
|
||||
@@ -2041,7 +2075,7 @@ G4RadioactiveDecay::DoDecay(const G4ParticleDefinition& theParticleDef)
|
||||
// for difference in mass defect.
|
||||
G4double parentPlusQ = theParticleDef.GetPDGMass() + 30.*MeV;
|
||||
G4VDecayChannel* theDecayChannel = theDecayTable->SelectADecayChannel(parentPlusQ);
|
||||
|
||||
theRadDecayMode = (static_cast<G4NuclearDecay*>(theDecayChannel))->GetDecayMode();
|
||||
if (theDecayChannel == 0) {
|
||||
// Decay channel not found.
|
||||
G4ExceptionDescription ed;
|
||||
@@ -2083,6 +2117,7 @@ void G4RadioactiveDecay::CollimateDecay(G4DecayProducts* products) {
|
||||
static const G4ParticleDefinition* neutron = G4Neutron::Definition();
|
||||
static const G4ParticleDefinition* gamma = G4Gamma::Definition();
|
||||
static const G4ParticleDefinition* alpha = G4Alpha::Definition();
|
||||
static const G4ParticleDefinition* triton = G4Triton::Definition();
|
||||
static const G4ParticleDefinition* proton = G4Proton::Definition();
|
||||
|
||||
G4ThreeVector newDirection; // Re-use to avoid memory churn
|
||||
@@ -2092,7 +2127,7 @@ void G4RadioactiveDecay::CollimateDecay(G4DecayProducts* products) {
|
||||
daughter->GetParticleDefinition();
|
||||
if (daughterType == electron || daughterType == positron ||
|
||||
daughterType == neutron || daughterType == gamma ||
|
||||
daughterType == alpha || daughterType == proton) CollimateDecayProduct(daughter);
|
||||
daughterType == alpha || daughterType == triton || daughterType == proton) CollimateDecayProduct(daughter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "G4BetaPlusDecay.hh"
|
||||
#include "G4ECDecay.hh"
|
||||
#include "G4AlphaDecay.hh"
|
||||
#include "G4TritonDecay.hh"
|
||||
#include "G4ProtonDecay.hh"
|
||||
#include "G4NeutronDecay.hh"
|
||||
#include "G4SFDecay.hh"
|
||||
@@ -71,6 +72,7 @@
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4Triton.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
#include "G4HadronicProcessType.hh"
|
||||
@@ -125,11 +127,11 @@ G4RadioactiveDecayBase::G4RadioactiveDecayBase(const G4String& processName)
|
||||
photonEvaporation->RDMForced(true);
|
||||
photonEvaporation->SetICM(true);
|
||||
|
||||
G4DeexPrecoParameters* deex = G4NuclearLevelData::GetInstance()->GetParameters();
|
||||
deex->SetCorrelatedGamma(true);
|
||||
// DHW G4DeexPrecoParameters* deex = G4NuclearLevelData::GetInstance()->GetParameters();
|
||||
// DHW deex->SetCorrelatedGamma(true);
|
||||
|
||||
// Check data directory
|
||||
char* path_var = getenv("G4RADIOACTIVEDATA");
|
||||
char* path_var = std::getenv("G4RADIOACTIVEDATA");
|
||||
if (!path_var) {
|
||||
G4Exception("G4RadioactiveDecay()","HAD_RDM_200",FatalException,
|
||||
"Environment variable G4RADIOACTIVEDATA is not set");
|
||||
@@ -233,7 +235,6 @@ G4DecayTable* G4RadioactiveDecayBase::GetDecayTable(const G4ParticleDefinition*
|
||||
} else {
|
||||
theDecayTable = table_ptr->second;
|
||||
}
|
||||
|
||||
return theDecayTable;
|
||||
}
|
||||
|
||||
@@ -244,18 +245,19 @@ void G4RadioactiveDecayBase::SelectAVolume(const G4String aVolume)
|
||||
G4LogicalVolume* volume;
|
||||
theLogicalVolumes = G4LogicalVolumeStore::GetInstance();
|
||||
for (size_t i = 0; i < theLogicalVolumes->size(); i++) {
|
||||
volume=(*theLogicalVolumes)[i];
|
||||
volume = (*theLogicalVolumes)[i];
|
||||
if (volume->GetName() == aVolume) {
|
||||
ValidVolumes.push_back(aVolume);
|
||||
std::sort(ValidVolumes.begin(), ValidVolumes.end());
|
||||
// sort need for performing binary_search
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0)
|
||||
G4cout << " RDM Applies to : " << aVolume << G4endl;
|
||||
#endif
|
||||
} else if(i == theLogicalVolumes->size()) {
|
||||
G4cerr << "SelectAVolume: "<< aVolume
|
||||
<< " is not a valid logical volume name" << G4endl;
|
||||
|
||||
if (GetVerboseLevel() > 0)
|
||||
G4cout << " Radioactive decay applied to " << aVolume << G4endl;
|
||||
|
||||
} else if (i == theLogicalVolumes->size() ) {
|
||||
G4cout << " G4RadioactiveDecay::SelectAVolume: " << aVolume
|
||||
<< " is not a valid logical volume name."
|
||||
<< " Decay not activated for it." << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,27 +268,26 @@ void G4RadioactiveDecayBase::DeselectAVolume(const G4String aVolume)
|
||||
G4LogicalVolumeStore* theLogicalVolumes;
|
||||
G4LogicalVolume* volume;
|
||||
theLogicalVolumes = G4LogicalVolumeStore::GetInstance();
|
||||
for (size_t i = 0; i < theLogicalVolumes->size(); i++){
|
||||
volume=(*theLogicalVolumes)[i];
|
||||
for (size_t i = 0; i < theLogicalVolumes->size(); i++) {
|
||||
volume = (*theLogicalVolumes)[i];
|
||||
if (volume->GetName() == aVolume) {
|
||||
std::vector<G4String>::iterator location;
|
||||
location = std::find(ValidVolumes.begin(),ValidVolumes.end(),aVolume);
|
||||
if (location != ValidVolumes.end()) {
|
||||
if (location != ValidVolumes.end() ) {
|
||||
ValidVolumes.erase(location);
|
||||
std::sort(ValidVolumes.begin(), ValidVolumes.end());
|
||||
isAllVolumesMode =false;
|
||||
isAllVolumesMode = false;
|
||||
if (GetVerboseLevel() > 0)
|
||||
G4cout << " G4RadioactiveDecay::DeselectAVolume: " << aVolume
|
||||
<< " is removed from list " << G4endl;
|
||||
} else {
|
||||
G4cerr << " DeselectVolume:" << aVolume << " is not in the list "
|
||||
<< G4endl;
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel() > 0)
|
||||
G4cout << " DeselectVolume: " << aVolume << " is removed from list "
|
||||
<< G4endl;
|
||||
#endif
|
||||
G4cout << " G4RadioactiveDecay::DeselectAVolume: " << aVolume
|
||||
<< " is not in the list. No action taken. " << G4endl;
|
||||
}
|
||||
} else if (i == theLogicalVolumes->size()) {
|
||||
G4cerr << " DeselectVolume:" << aVolume
|
||||
<< "is not a valid logical volume name" << G4endl;
|
||||
G4cout << " G4RadioactiveDecay::DeselectVolume:" << aVolume
|
||||
<< " is not a valid logical volume name. No action taken."
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,12 +334,8 @@ void G4RadioactiveDecayBase::DeselectAllVolumes()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4RadioactiveDecayBase::GetMeanLifeTime(const G4Track& theTrack,
|
||||
G4ForceCondition*)
|
||||
G4ForceCondition*)
|
||||
{
|
||||
// For variance reduction the time is set to 0 so as to force the particle
|
||||
// to decay immediately.
|
||||
// In analogueMC mode it returns the particle's mean-life.
|
||||
|
||||
G4double meanlife = 0.;
|
||||
const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
|
||||
const G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
|
||||
@@ -363,7 +360,7 @@ G4double G4RadioactiveDecayBase::GetMeanLifeTime(const G4Track& theTrack,
|
||||
G4cout << " mean life time: " << meanlife/s << " s " << G4endl;
|
||||
#endif
|
||||
|
||||
return meanlife;
|
||||
return meanlife;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -543,7 +540,7 @@ G4RadioactiveDecayBase::LoadDecayTable(const G4ParticleDefinition& theParentNucl
|
||||
if (DecaySchemeFile.good()) {
|
||||
// Initialize variables used for reading in radioactive decay data
|
||||
G4bool floatMatch(false);
|
||||
const G4int nMode = 11;
|
||||
const G4int nMode = 12;
|
||||
G4double modeTotalBR[nMode] = {0.0};
|
||||
G4double modeSumBR[nMode];
|
||||
for (G4int i = 0; i < nMode; i++) {
|
||||
@@ -653,6 +650,8 @@ G4RadioactiveDecayBase::LoadDecayTable(const G4ParticleDefinition& theParentNucl
|
||||
break;
|
||||
case SpFission:
|
||||
modeTotalBR[10] = decayModeTotal; break;
|
||||
case Triton:
|
||||
modeTotalBR[11] = decayModeTotal; break;
|
||||
case RDM_ERROR:
|
||||
|
||||
default:
|
||||
@@ -672,6 +671,7 @@ G4RadioactiveDecayBase::LoadDecayTable(const G4ParticleDefinition& theParentNucl
|
||||
// indicated in the last column.
|
||||
a /= 1000.;
|
||||
c /= 1000.;
|
||||
b /= 100.;
|
||||
daughterFloatLevel = G4Ions::FloatLevelBase(daughterFloatFlag.back());
|
||||
|
||||
switch (theDecayMode) {
|
||||
@@ -821,6 +821,17 @@ G4RadioactiveDecayBase::LoadDecayTable(const G4ParticleDefinition& theParentNucl
|
||||
modeSumBR[10] += b;
|
||||
}
|
||||
break;
|
||||
case Triton:
|
||||
{
|
||||
G4TritonDecay* aTritonChannel =
|
||||
new G4TritonDecay(&theParentNucleus, b, c*MeV, a*MeV,
|
||||
daughterFloatLevel);
|
||||
// anAlphaChannel->DumpNuclearInfo();
|
||||
// anAlphaChannel->SetHLThreshold(halflifethreshold);
|
||||
theDecayTable->Insert(aTritonChannel);
|
||||
modeSumBR[11] += b;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDM_ERROR:
|
||||
|
||||
@@ -899,7 +910,6 @@ G4VParticleChange*
|
||||
G4RadioactiveDecayBase::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
{
|
||||
// Initialize G4ParticleChange object, get particle details and decay table
|
||||
|
||||
fParticleChangeForRadDecay.Initialize(theTrack);
|
||||
fParticleChangeForRadDecay.ProposeWeight(theTrack.GetWeight());
|
||||
const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
|
||||
@@ -934,13 +944,13 @@ G4RadioactiveDecayBase::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
if (!(IsApplicable(*theParticleDef) ) ) {
|
||||
// Particle is not an ion or is outside the nucleuslimits for decay
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cerr << "G4RadioactiveDecay::DecayIt : "
|
||||
if (GetVerboseLevel() > 0) {
|
||||
G4cout << "G4RadioactiveDecay::DecayIt : "
|
||||
<< theParticleDef->GetParticleName()
|
||||
<< " is not a valid nucleus for the RDM"<< G4endl;
|
||||
<< " is not an ion or is outside (Z,A) limits set for the decay. "
|
||||
<< " Set particle change accordingly. "
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
|
||||
|
||||
// Kill the parent particle
|
||||
@@ -955,12 +965,13 @@ G4RadioactiveDecayBase::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
if (theDecayTable == 0 || theDecayTable->entries() == 0) {
|
||||
// No data in the decay table. Set particle change parameters
|
||||
// to indicate this.
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel() > 0) {
|
||||
G4cerr <<"G4RadioactiveDecay::DecayIt : decay table not defined for ";
|
||||
G4cerr <<theParticleDef->GetParticleName() <<G4endl;
|
||||
G4cout << "G4RadioactiveDecay::DecayIt : "
|
||||
<< "decay table not defined for "
|
||||
<< theParticleDef->GetParticleName()
|
||||
<< ". Set particle change accordingly. "
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
|
||||
|
||||
// Kill the parent particle.
|
||||
@@ -971,6 +982,8 @@ G4RadioactiveDecayBase::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
|
||||
} else {
|
||||
// Data found. Try to decay nucleus
|
||||
|
||||
/*
|
||||
G4double energyDeposit = 0.0;
|
||||
G4double finalGlobalTime = theTrack.GetGlobalTime();
|
||||
G4double finalLocalTime = theTrack.GetLocalTime();
|
||||
@@ -1050,18 +1063,112 @@ G4RadioactiveDecayBase::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
fParticleChangeForRadDecay.ProposeLocalTime(finalLocalTime);
|
||||
// Reset NumberOfInteractionLengthLeft.
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
|
||||
*/
|
||||
// Decay without variance reduction
|
||||
DecayAnalog(theTrack);
|
||||
return &fParticleChangeForRadDecay ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4RadioactiveDecayBase::DecayAnalog(const G4Track& theTrack)
|
||||
{
|
||||
const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
|
||||
const G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
|
||||
G4DecayProducts* products = DoDecay(*theParticleDef);
|
||||
|
||||
// Check if the product is the same as input and kill the track if
|
||||
// necessary to prevent infinite loop (11/05/10, F.Lei)
|
||||
if (products->entries() == 1) {
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
|
||||
fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return;
|
||||
}
|
||||
|
||||
G4double energyDeposit = 0.0;
|
||||
G4double finalGlobalTime = theTrack.GetGlobalTime();
|
||||
G4double finalLocalTime = theTrack.GetLocalTime();
|
||||
|
||||
// Get parent particle information and boost the decay products to the
|
||||
// laboratory frame
|
||||
|
||||
// ParentEnergy used for the boost should be the total energy of the nucleus
|
||||
// of the parent ion without the energy of the shell electrons
|
||||
// (correction for bug 1359 by L. Desorgher)
|
||||
G4double ParentEnergy = theParticle->GetKineticEnergy()
|
||||
+ theParticle->GetParticleDefinition()->GetPDGMass();
|
||||
G4ThreeVector ParentDirection(theParticle->GetMomentumDirection());
|
||||
|
||||
if (theTrack.GetTrackStatus() == fStopButAlive) {
|
||||
// this condition seems to be always True, further investigation is needed (L.Desorgher)
|
||||
|
||||
// The particle is decayed at rest
|
||||
// Since the time is for the particle at rest, need to add additional time
|
||||
// lapsed between particle coming to rest and the actual decay. This time
|
||||
// is sampled with the mean-life of the particle. Need to protect the case
|
||||
// PDGTime < 0. (F.Lei 11/05/10)
|
||||
G4double temptime = -std::log(G4UniformRand() ) *
|
||||
theParticleDef->GetPDGLifeTime();
|
||||
if (temptime < 0.) temptime = 0.;
|
||||
finalGlobalTime += temptime;
|
||||
finalLocalTime += temptime;
|
||||
energyDeposit += theParticle->GetKineticEnergy();
|
||||
}
|
||||
products->Boost(ParentEnergy, ParentDirection);
|
||||
|
||||
// Add products in theParticleChangeForRadDecay.
|
||||
G4int numberOfSecondaries = products->entries();
|
||||
fParticleChangeForRadDecay.SetNumberOfSecondaries(numberOfSecondaries);
|
||||
|
||||
if (GetVerboseLevel() > 1) {
|
||||
G4cout << "G4RadioactiveDecay::DecayAnalog: Decay vertex :";
|
||||
G4cout << " Time: " << finalGlobalTime/ns << "[ns]";
|
||||
G4cout << " X:" << (theTrack.GetPosition()).x() /cm << "[cm]";
|
||||
G4cout << " Y:" << (theTrack.GetPosition()).y() /cm << "[cm]";
|
||||
G4cout << " Z:" << (theTrack.GetPosition()).z() /cm << "[cm]";
|
||||
G4cout << G4endl;
|
||||
G4cout << "G4Decay::DecayIt : decay products in Lab. Frame" << G4endl;
|
||||
products->DumpInfo();
|
||||
products->IsChecked();
|
||||
}
|
||||
|
||||
for (G4int index = 0; index < numberOfSecondaries; index++) {
|
||||
G4Track* secondary = new G4Track(products->PopProducts(), finalGlobalTime,
|
||||
theTrack.GetPosition() );
|
||||
secondary->SetCreatorModelIndex(theRadDecayMode);
|
||||
//Change for atomics relaxation
|
||||
if (theRadDecayMode == IT && index>0){
|
||||
if (index == numberOfSecondaries-1) secondary->SetCreatorModelIndex(IT);
|
||||
else secondary->SetCreatorModelIndex(30);
|
||||
}
|
||||
else if (theRadDecayMode >= KshellEC && theRadDecayMode <= NshellEC
|
||||
&& index <numberOfSecondaries-1){
|
||||
secondary->SetCreatorModelIndex(30);
|
||||
}
|
||||
secondary->SetGoodForTrackingFlag();
|
||||
secondary->SetTouchableHandle(theTrack.GetTouchableHandle());
|
||||
fParticleChangeForRadDecay.AddSecondary(secondary);
|
||||
}
|
||||
|
||||
delete products;
|
||||
|
||||
// Kill the parent particle
|
||||
fParticleChangeForRadDecay.ProposeTrackStatus(fStopAndKill) ;
|
||||
fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(energyDeposit);
|
||||
fParticleChangeForRadDecay.ProposeLocalTime(finalLocalTime);
|
||||
|
||||
// Reset NumberOfInteractionLengthLeft.
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
}
|
||||
|
||||
|
||||
G4DecayProducts*
|
||||
G4RadioactiveDecayBase::DoDecay(const G4ParticleDefinition& theParticleDef)
|
||||
{
|
||||
G4DecayProducts* products = 0;
|
||||
G4DecayTable* theDecayTable = GetDecayTable(&theParticleDef);
|
||||
|
||||
// Choose a decay channel.
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel() > 0) G4cout << "Select a channel..." << G4endl;
|
||||
@@ -1072,6 +1179,7 @@ G4RadioactiveDecayBase::DoDecay(const G4ParticleDefinition& theParticleDef)
|
||||
// for difference in mass defect.
|
||||
G4double parentPlusQ = theParticleDef.GetPDGMass() + 30.*MeV;
|
||||
G4VDecayChannel* theDecayChannel = theDecayTable->SelectADecayChannel(parentPlusQ);
|
||||
theRadDecayMode = (static_cast<G4NuclearDecay*>(theDecayChannel))->GetDecayMode();
|
||||
|
||||
if (theDecayChannel == 0) {
|
||||
// Decay channel not found.
|
||||
@@ -1083,8 +1191,8 @@ G4RadioactiveDecayBase::DoDecay(const G4ParticleDefinition& theParticleDef)
|
||||
// A decay channel has been identified, so execute the DecayIt.
|
||||
#ifdef G4VERBOSE
|
||||
if (GetVerboseLevel() > 1) {
|
||||
G4cerr << "G4RadioactiveDecay::DoIt : selected decay channel addr:";
|
||||
G4cerr << theDecayChannel << G4endl;
|
||||
G4cout << "G4RadioactiveDecay::DoIt : selected decay channel addr: "
|
||||
<< theDecayChannel << G4endl;
|
||||
}
|
||||
#endif
|
||||
products = theDecayChannel->DecayIt(theParticleDef.GetPDGMass() );
|
||||
@@ -1114,6 +1222,7 @@ void G4RadioactiveDecayBase::CollimateDecay(G4DecayProducts* products) {
|
||||
static const G4ParticleDefinition* neutron = G4Neutron::Definition();
|
||||
static const G4ParticleDefinition* gamma = G4Gamma::Definition();
|
||||
static const G4ParticleDefinition* alpha = G4Alpha::Definition();
|
||||
static const G4ParticleDefinition* triton = G4Triton::Definition();
|
||||
static const G4ParticleDefinition* proton = G4Proton::Definition();
|
||||
|
||||
G4ThreeVector newDirection; // Re-use to avoid memory churn
|
||||
@@ -1123,7 +1232,7 @@ void G4RadioactiveDecayBase::CollimateDecay(G4DecayProducts* products) {
|
||||
daughter->GetParticleDefinition();
|
||||
if (daughterType == electron || daughterType == positron ||
|
||||
daughterType == neutron || daughterType == gamma ||
|
||||
daughterType == alpha || daughterType == proton) CollimateDecayProduct(daughter);
|
||||
daughterType == alpha || daughterType == triton || daughterType == proton) CollimateDecayProduct(daughter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ std::istream &operator >> (std::istream& strm, G4RadioactiveDecayMode& q)
|
||||
{q = Proton2;}
|
||||
else if (a == "Neutron2")
|
||||
{q = Neutron2;}
|
||||
else if (a == "Triton")
|
||||
{q = Triton;}
|
||||
else
|
||||
{q = RDM_ERROR;}
|
||||
return strm;
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: G4TritonDecay.cc based on G4AlphaDecay //
|
||||
// Author: A.Mereagglia (CENBG), imported in G4repository by L.Desorgher //
|
||||
// Date: 24 June 2019, imported in Geant4 on 31 October 2019 //
|
||||
// Description: //
|
||||
// //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4TritonDecay.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4DecayProducts.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
G4TritonDecay::G4TritonDecay(const G4ParticleDefinition* theParentNucleus,
|
||||
const G4double& branch, const G4double& Qvalue,
|
||||
const G4double& excitationE,
|
||||
const G4Ions::G4FloatLevelBase& flb)
|
||||
: G4NuclearDecay("triton decay", Triton, excitationE, flb), transitionQ(Qvalue)
|
||||
{
|
||||
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
|
||||
SetBR(branch);
|
||||
|
||||
SetNumberOfDaughters(2);
|
||||
G4IonTable* theIonTable =
|
||||
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
|
||||
G4int daughterZ = theParentNucleus->GetAtomicNumber() - 1;
|
||||
G4int daughterA = theParentNucleus->GetAtomicMass() - 3;
|
||||
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE, flb) );
|
||||
SetDaughter(1, "triton");
|
||||
}
|
||||
|
||||
|
||||
G4TritonDecay::~G4TritonDecay()
|
||||
{}
|
||||
|
||||
|
||||
G4DecayProducts* G4TritonDecay::DecayIt(G4double)
|
||||
{
|
||||
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
|
||||
CheckAndFillParent();
|
||||
|
||||
// Fill G4MT_daughters with triton and residual nucleus (stored by SetDaughter)
|
||||
CheckAndFillDaughters();
|
||||
|
||||
G4double tritonMass = G4MT_daughters[1]->GetPDGMass();
|
||||
// Excitation energy included in PDG mass
|
||||
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
|
||||
|
||||
// Q value was calculated from atomic masses.
|
||||
// Use it to get correct triton energy.
|
||||
G4double cmMomentum = std::sqrt(transitionQ*(transitionQ + 2.*tritonMass)*
|
||||
(transitionQ + 2.*nucleusMass)*
|
||||
(transitionQ + 2.*tritonMass + 2.*nucleusMass) )/
|
||||
(transitionQ + tritonMass + nucleusMass)/2.;
|
||||
|
||||
// Set up final state
|
||||
// parentParticle is set at rest here because boost with correct momentum
|
||||
// is done later
|
||||
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
|
||||
G4DecayProducts* products = new G4DecayProducts(parentParticle);
|
||||
|
||||
G4double costheta = 2.*G4UniformRand()-1.0;
|
||||
G4double sintheta = std::sqrt(1.0 - costheta*costheta);
|
||||
G4double phi = twopi*G4UniformRand()*rad;
|
||||
G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),
|
||||
costheta);
|
||||
|
||||
G4double KE = std::sqrt(cmMomentum*cmMomentum + tritonMass*tritonMass)
|
||||
- tritonMass;
|
||||
G4DynamicParticle* daughterparticle =
|
||||
new G4DynamicParticle(G4MT_daughters[1], direction, KE, tritonMass);
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
KE = std::sqrt(cmMomentum*cmMomentum + nucleusMass*nucleusMass) - nucleusMass;
|
||||
daughterparticle =
|
||||
new G4DynamicParticle(G4MT_daughters[0], -1.0*direction, KE, nucleusMass);
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
// Energy conservation check
|
||||
// For triton decays, do final energy check against reaction Q value
|
||||
// which is well-measured using atomic mass differences. Nuclear masses
|
||||
// should not be used since they are not usually directly measured and we
|
||||
// always decay atoms and not fully stripped nuclei.
|
||||
/*
|
||||
G4int nProd = products->entries();
|
||||
G4DynamicParticle* temp = 0;
|
||||
G4double Esum = 0.0;
|
||||
for (G4int i = 0; i < nProd; i++) {
|
||||
temp = products->operator[](i);
|
||||
Esum += temp->GetKineticEnergy();
|
||||
}
|
||||
G4double eCons = (transitionQ - Esum)/keV;
|
||||
if (eCons > 1.e-07) G4cout << " Triton decay check: Ediff (keV) = " << eCons << G4endl;
|
||||
*/
|
||||
return products;
|
||||
}
|
||||
|
||||
|
||||
void G4TritonDecay::DumpNuclearInfo()
|
||||
{
|
||||
G4cout << " G4TritonDecay for parent nucleus " << GetParentName() << G4endl;
|
||||
G4cout << " decays to " << GetDaughterName(0) << " + " << GetDaughterName(1)
|
||||
<< " with branching ratio " << GetBR() << "% and Q value "
|
||||
<< transitionQ << G4endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user