Import Geant4 11.3.1 source tree
This commit is contained in:
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-03-25 Ivana Hrivnacova (proccuts-V11-02-00)
|
||||
- In G4ProductionCutsTable::UpdateCoupleTable:
|
||||
Make sure that the couple tables are updated if userEnergyCuts
|
||||
vectors are set
|
||||
|
||||
## 2023-10-24 Ivana Hrivnacova (proccuts-V11-01-01)
|
||||
- G4ProductionCutsTable - Added method CreateCoupleTables()
|
||||
separated from UpdateCoupleTable() needed to prepare
|
||||
|
||||
@@ -270,6 +270,15 @@ void G4ProductionCutsTable::UpdateCoupleTable(G4VPhysicalVolume* /*currWorld*/)
|
||||
firstUse = false;
|
||||
}
|
||||
|
||||
// Force update of coupleTable if userEnergyCuts vectors are set
|
||||
G4bool isRecalcNeeded = false;
|
||||
for (const auto* userVector : userEnergyCuts) {
|
||||
if (userVector != nullptr) {
|
||||
isRecalcNeeded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update RangeEnergy cuts tables
|
||||
std::size_t idx = 0;
|
||||
G4Timer timer;
|
||||
@@ -281,7 +290,7 @@ void G4ProductionCutsTable::UpdateCoupleTable(G4VPhysicalVolume* /*currWorld*/)
|
||||
{
|
||||
G4ProductionCuts* aCut = (*cItr)->GetProductionCuts();
|
||||
const G4Material* aMat = (*cItr)->GetMaterial();
|
||||
if((*cItr)->IsRecalcNeeded())
|
||||
if((*cItr)->IsRecalcNeeded() || isRecalcNeeded)
|
||||
{
|
||||
for(std::size_t ptcl=0; ptcl< NumberOfG4CutIndex; ++ptcl)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-01-14 Ben Morgan (emdna-V11-02-18)
|
||||
- Remove obsolete/commented references to G4AllocatorList.
|
||||
|
||||
## 2024-10-31 Hoang Tran (emdna-V11-02-17)
|
||||
- missing value in DNA PTB Ionization Structure;
|
||||
- missing GetMaterial() in DNA PTB Excitation and Elastic models (PR#78,by mjpietrzak)
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
|
||||
#include "G4FastList.hh"
|
||||
#include "G4ManyFastLists.hh"
|
||||
#include "G4AllocatorList.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4IT.hh"
|
||||
|
||||
|
||||
@@ -64,8 +64,6 @@ G4FastListNode<G4Track>* G4FastList<G4Track>::__GetNode(G4Track* __track)
|
||||
template<>
|
||||
void G4FastList<G4Track>::DeleteObject(G4Track* __track)
|
||||
{
|
||||
if (G4AllocatorList::GetAllocatorListIfExist() == nullptr) return;
|
||||
|
||||
auto __step = const_cast<G4Step*>(__track->GetStep());
|
||||
if (__step != nullptr)
|
||||
{
|
||||
|
||||
-14
@@ -35,7 +35,6 @@
|
||||
#include "G4MolecularConfiguration.hh"
|
||||
#include "G4MoleculeDefinition.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4AllocatorList.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
#include "G4MoleculeTable.hh"
|
||||
#include "G4Serialize.hh"
|
||||
@@ -147,10 +146,6 @@ G4MolecularConfiguration::GetManager()
|
||||
G4MolecularConfiguration::
|
||||
G4MolecularConfigurationManager::~G4MolecularConfigurationManager()
|
||||
{
|
||||
// G4cout << "Does G4AllocatorList exists= ";
|
||||
// G4cout << (G4AllocatorList::GetAllocatorListIfExist() ? "true":"false")
|
||||
// << G4endl;
|
||||
|
||||
G4MolecularConfigurationManager::MolElectronConfTable::iterator it1;
|
||||
G4MolecularConfigurationManager::ElectronOccupancyTable::
|
||||
iterator it2;
|
||||
@@ -507,15 +502,6 @@ G4MolecularConfiguration(const G4MoleculeDefinition* moleculeDef,
|
||||
G4MolecularConfiguration::~G4MolecularConfiguration()
|
||||
{
|
||||
if (fgManager != nullptr) fgManager->RemoveMolecularConfigurationFromTable(this);
|
||||
|
||||
// if (G4AllocatorList::GetAllocatorListIfExist())
|
||||
// {
|
||||
// if (fElectronOccupancy)
|
||||
// {
|
||||
// delete fElectronOccupancy;
|
||||
// fElectronOccupancy = 0;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
//______________________________________________________________________________
|
||||
|
||||
@@ -6,6 +6,13 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-02-07 L. Pandola (emlowen-V11-02-08)
|
||||
- Fix residual Coverity defect on G4ShellData
|
||||
|
||||
## 2025-01-09 L. Pandola
|
||||
- Fix Coverity warnings in Penenelope models, G4ShellData, G4FluoData and
|
||||
G4AugerTransition
|
||||
|
||||
## 2024-12-02 A. Ribon (emlowen-V11-02-07)
|
||||
- G4UAtomicDeexcitation : clear vector (vacancyArray) in the method
|
||||
G4UAtomicDeexcitation::GenerateParticles, to avoid rare non-reproducibility
|
||||
|
||||
@@ -64,10 +64,16 @@ G4AugerTransition::~G4AugerTransition()
|
||||
const std::vector<G4int>* G4AugerTransition::AugerOriginatingShellIds(G4int startShellId) const
|
||||
{
|
||||
auto shellId = augerOriginatingShellIdsMap.find(startShellId);
|
||||
|
||||
if (shellId == augerOriginatingShellIdsMap.end())
|
||||
{
|
||||
G4Exception("G4AugerTransition::AugerOriginatingShellIds()",
|
||||
"em2199",JustWarning,"Error: no Auger ID found");
|
||||
return nullptr;
|
||||
}
|
||||
const std::vector<G4int>* dataSet = &(*shellId).second;
|
||||
if (dataSet->empty())
|
||||
G4cout << "Error: no auger Id found"<< G4endl;
|
||||
G4Exception("G4AugerTransition::AugerOriginatingShellIds()",
|
||||
"em2198",JustWarning,"Error: no Auger ID found");
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,13 +157,15 @@ G4double G4FluoData::StartShellEnergy(G4int initIndex, G4int vacancyIndex) const
|
||||
else
|
||||
{
|
||||
auto pos = energyMap.find(vacancyIndex);
|
||||
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = (G4int)dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
if (pos != energyMap.end())
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = (G4int)dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
@@ -184,13 +186,15 @@ G4double G4FluoData::StartShellProb(G4int initIndex, G4int vacancyIndex) const
|
||||
else
|
||||
{
|
||||
auto pos = probabilityMap.find(vacancyIndex);
|
||||
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = (G4int)dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
if (pos != probabilityMap.end())
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = (G4int)dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
|
||||
@@ -497,7 +497,8 @@ G4double G4PenelopeBremsstrahlungAngular::CalculateEffectiveZ(const G4Material*
|
||||
}
|
||||
//Normalize
|
||||
for (G4int i=0;i<nElements;++i)
|
||||
(*StechiometricFactors)[i] /= MaxStechiometricFactor;
|
||||
if (MaxStechiometricFactor > 0.)
|
||||
(*StechiometricFactors)[i] /= MaxStechiometricFactor;
|
||||
|
||||
G4double sumz2 = 0;
|
||||
G4double sums = 0;
|
||||
@@ -509,7 +510,7 @@ G4double G4PenelopeBremsstrahlungAngular::CalculateEffectiveZ(const G4Material*
|
||||
}
|
||||
delete StechiometricFactors;
|
||||
|
||||
G4double ZBR = std::sqrt(sumz2/sums);
|
||||
G4double ZBR = (sums > 0.) ? std::sqrt(sumz2/sums) : 0.;
|
||||
fEffectiveZSq->insert(std::make_pair(material,ZBR));
|
||||
|
||||
return ZBR;
|
||||
|
||||
@@ -232,7 +232,8 @@ void G4PenelopeBremsstrahlungFS::BuildScaledXSTable(const G4Material* material,
|
||||
}
|
||||
//Normalize
|
||||
for (std::size_t i=0;i<nElements;i++)
|
||||
(*StechiometricFactors)[i] /= MaxStechiometricFactor;
|
||||
if (MaxStechiometricFactor > 0.)
|
||||
(*StechiometricFactors)[i] /= MaxStechiometricFactor;
|
||||
|
||||
G4double sumz2 = 0;
|
||||
G4double sums = 0;
|
||||
@@ -604,14 +605,14 @@ G4double G4PenelopeBremsstrahlungFS::SampleGammaEnergy(G4double energy,const G4M
|
||||
const G4double cut) const
|
||||
{
|
||||
std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
|
||||
if (!(fSamplingTable->count(theKey)) || !(fPBcut->count(theKey)))
|
||||
if (!(fSamplingTable->count(theKey)) || !(fPBcut->count(theKey)) ||
|
||||
!(fReducedXSTable->count(theKey)))
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Unable to retrieve the SamplingTable: " <<
|
||||
fSamplingTable->count(theKey) << " " <<
|
||||
fPBcut->count(theKey) << G4endl;
|
||||
ed << "Unable to retrieve the SamplingTable for " << mat->GetName() << G4endl;
|
||||
G4Exception("G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
|
||||
"em2014",FatalException,ed);
|
||||
return 0.;
|
||||
}
|
||||
const G4PhysicsTable* theTableInte = fSamplingTable->find(theKey)->second;
|
||||
const G4PhysicsTable* theTableRed = fReducedXSTable->find(theKey)->second;
|
||||
|
||||
@@ -257,7 +257,8 @@ G4double G4PenelopeBremsstrahlungModel::CrossSectionPerVolume(const G4Material*
|
||||
{
|
||||
G4cout << "G4PenelopeBremsstrahlungModel " << G4endl;
|
||||
G4cout << "Mean free path for gamma emission > " << cutEnergy/keV << " keV at " <<
|
||||
energy/keV << " keV = " << (1./crossPerVolume)/mm << " mm" << G4endl;
|
||||
energy/keV << " keV = " <<
|
||||
(crossPerVolume? (1./crossPerVolume)/mm : DBL_MAX) << " mm" << G4endl;
|
||||
}
|
||||
|
||||
return crossPerVolume;
|
||||
|
||||
@@ -236,7 +236,8 @@ G4double G4PenelopeComptonModel::CrossSectionPerVolume(const G4Material* materia
|
||||
|
||||
if (fVerboseLevel > 2)
|
||||
G4cout << "Compton mean free path at " << energy/keV << " keV for material " <<
|
||||
material->GetName() << " = " << (1./csvolume)/mm << " mm" << G4endl;
|
||||
material->GetName() << " = " <<
|
||||
(csvolume ? (1./csvolume)/mm : DBL_MAX) << " mm" << G4endl;
|
||||
return csvolume;
|
||||
}
|
||||
|
||||
|
||||
@@ -323,11 +323,13 @@ G4double G4PenelopeIonisationModel::CrossSectionPerVolume(const G4Material* mate
|
||||
{
|
||||
G4cout << "G4PenelopeIonisationModel " << G4endl;
|
||||
G4cout << "Mean free path for delta emission > " << cutEnergy/keV << " keV at " <<
|
||||
energy/keV << " keV = " << (1./crossPerVolume)/mm << " mm" << G4endl;
|
||||
energy/keV << " keV = " <<
|
||||
(crossPerVolume ? (1./crossPerVolume)/mm : DBL_MAX) << " mm" << G4endl;
|
||||
if (theXS)
|
||||
totalCross = (theXS->GetTotalCrossSection(energy))*moleculeDensity;
|
||||
G4cout << "Total free path for ionisation (no threshold) at " <<
|
||||
energy/keV << " keV = " << (1./totalCross)/mm << " mm" << G4endl;
|
||||
energy/keV << " keV = " <<
|
||||
(totalCross ? (1./totalCross)/mm : DBL_MAX) << " mm" << G4endl;
|
||||
}
|
||||
return crossPerVolume;
|
||||
}
|
||||
|
||||
@@ -493,7 +493,8 @@ G4double G4PenelopeRayleighModelMI::CrossSectionPerVolume(const G4Material* mate
|
||||
MaxStoichiometricFactor = (*StoichiometricFactors)[i];
|
||||
}
|
||||
for (std::size_t i=0;i<nElements;++i) {
|
||||
(*StoichiometricFactors)[i] /= MaxStoichiometricFactor;
|
||||
if (MaxStoichiometricFactor > 0.)
|
||||
(*StoichiometricFactors)[i] /= MaxStoichiometricFactor;
|
||||
}
|
||||
|
||||
//Equivalent atoms per molecule
|
||||
|
||||
@@ -192,31 +192,38 @@ void G4ShellData::PrintData() const
|
||||
auto posId = idMap.find(Z);
|
||||
std::vector<G4double>* ids = (*posId).second;
|
||||
auto posE = bindingMap.find(Z);
|
||||
G4DataVector* energies = (*posE).second;
|
||||
for (G4int i=0; i<nSh; ++i)
|
||||
if (posE != bindingMap.end())
|
||||
{
|
||||
G4int id = (G4int) (*ids)[i];
|
||||
G4double e = (*energies)[i] / keV;
|
||||
G4cout << i << ") ";
|
||||
G4DataVector* energies = (*posE).second;
|
||||
for (G4int i=0; i<nSh; ++i)
|
||||
{
|
||||
G4int id = (G4int) (*ids)[i];
|
||||
G4double e = (*energies)[i] / keV;
|
||||
G4cout << i << ") ";
|
||||
|
||||
if (occupancyData)
|
||||
{
|
||||
G4cout << " Occupancy: ";
|
||||
if (occupancyData)
|
||||
{
|
||||
G4cout << " Occupancy: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << " Shell id: ";
|
||||
}
|
||||
G4cout << id << " - Binding energy = "
|
||||
<< e << " keV ";
|
||||
if (occupancyData)
|
||||
{
|
||||
auto posOcc = occupancyPdfMap.find(Z);
|
||||
G4double prob = 0.;
|
||||
if (posOcc != occupancyPdfMap.end())
|
||||
{
|
||||
std::vector<G4double> probs = *((*posOcc).second);
|
||||
prob = probs[i];
|
||||
}
|
||||
G4cout << "- Probability = " << prob;
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << " Shell id: ";
|
||||
}
|
||||
G4cout << id << " - Binding energy = "
|
||||
<< e << " keV ";
|
||||
if (occupancyData)
|
||||
{
|
||||
auto posOcc = occupancyPdfMap.find(Z);
|
||||
std::vector<G4double> probs = *((*posOcc).second);
|
||||
G4double prob = probs[i];
|
||||
G4cout << "- Probability = " << prob;
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
G4cout << "-------------------------------------------------"
|
||||
<< G4endl;
|
||||
|
||||
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-02-07 Igor Semeniouk (emstand-V11-02-22)
|
||||
- G4OrePowellAtRestModel - Add missing decay plane rotation
|
||||
( random x axis phi )
|
||||
|
||||
## 2024-11-08 V.Ivanchenko (emstand-V11-02-21)
|
||||
- G4BraggModel - fixed problem of 4.12 MeV mu+ range reported in
|
||||
the Forum #12312.
|
||||
|
||||
@@ -103,6 +103,13 @@ void G4OrePowellAtRestModel::SampleSecondaries(
|
||||
G4ThreeVector PhotonMomentum2(0.,sin12,cos12);
|
||||
G4ThreeVector PhotonMomentum3(0.,sin13,cos13);
|
||||
|
||||
// Random x direction ( rotate decay plane along Z axis)
|
||||
|
||||
G4double phi = CLHEP::twopi * G4UniformRand();
|
||||
PhotonMomentum2.rotateZ(phi);
|
||||
PhotonMomentum3.rotateZ(phi);
|
||||
|
||||
|
||||
// First Gamma direction
|
||||
G4ThreeVector dir1 = G4RandomDirection();
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-12-22 Vladimir Ivanchenko (hadr-deex-V11-02-19)
|
||||
- G4ExcitationHandler, G4GammaTransition, G4PhotonEvaporation fixed problem
|
||||
#2584 - removed production of unphysical states
|
||||
|
||||
## 2024-10-29 Vladimir Ivanchenko (hadr-deex-V11-02-18)
|
||||
- G4LevelReader - reduced printouts on problems in nuclear level data
|
||||
- G4PolarizationTransition - use optimized G4LegendrePolinomial from
|
||||
|
||||
@@ -383,7 +383,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
}
|
||||
|
||||
// In case A <= 1 the fragment will not perform any nucleon emission
|
||||
if (A <= 1 || !isActive) {
|
||||
if (A <= 1 || !isActive || theInitialStatePtr->IsLongLived()) {
|
||||
theResults.push_back( theInitialStatePtr );
|
||||
|
||||
// check if a fragment is stable
|
||||
@@ -435,7 +435,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
std::size_t kk;
|
||||
for (kk=0; kk<theEvapList.size(); ++kk) {
|
||||
G4Fragment* frag = theEvapList[kk];
|
||||
if (fVerbose > 3) {
|
||||
if (fVerbose > 3) {
|
||||
G4cout << "Next evaporate: " << G4endl;
|
||||
G4cout << *frag << G4endl;
|
||||
}
|
||||
@@ -475,8 +475,13 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
// apply Evaporation, residual nucleus is always added to the results
|
||||
// photon evaporation is possible
|
||||
theEvaporation->BreakFragment(&results, frag);
|
||||
if (fVerbose > 3) {
|
||||
G4cout << "Evaporation Nsec= " << results.size() << G4endl;
|
||||
if (fVerbose > 3) {
|
||||
G4cout << kk << ". Evaporation: Nsec=" << results.size()
|
||||
<< " Z=" << frag->GetZ_asInt()
|
||||
<< " A=" << frag->GetA_asInt()
|
||||
<< " Eex=" << frag->GetExcitationEnergy()
|
||||
<< " stable=" << frag->IsLongLived()
|
||||
<< G4endl;
|
||||
}
|
||||
if (0 == results.size()) {
|
||||
theResults.push_back(frag);
|
||||
|
||||
+3
-3
@@ -120,7 +120,6 @@ private:
|
||||
G4int theZ{0};
|
||||
G4int theA{0};
|
||||
G4int fPoints{0};
|
||||
G4int fCode{0};
|
||||
G4int vShellNumber{-1};
|
||||
G4int MAXDEPOINT{10};
|
||||
std::size_t fIndex{0};
|
||||
@@ -132,7 +131,8 @@ private:
|
||||
G4double fProbability{0.0};
|
||||
G4double fStep{0.0};
|
||||
G4double fMaxLifeTime{DBL_MAX};
|
||||
|
||||
G4double fLocalTimeLimit{DBL_MAX};
|
||||
|
||||
G4double fTolerance;
|
||||
|
||||
G4bool fICM{true};
|
||||
@@ -161,7 +161,7 @@ G4PhotonEvaporation::InitialiseLevelManager(G4int Z, G4int A)
|
||||
theA = A;
|
||||
fIndex = 0;
|
||||
fLevelManager = fNuclearLevelData->GetLevelManager(theZ, theA);
|
||||
fLevelEnergyMax = fLevelManager ? fLevelManager->MaxLevelEnergy() : 0.0;
|
||||
fLevelEnergyMax = (nullptr != fLevelManager) ? fLevelManager->MaxLevelEnergy() : 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-4
@@ -89,6 +89,8 @@ G4GammaTransition::SampleTransition(G4Fragment* nucleus,
|
||||
|
||||
// Do complete Lorentz computation
|
||||
G4LorentzVector lv = nucleus->GetMomentum();
|
||||
|
||||
// final mass
|
||||
G4double mass = nucleus->GetGroundStateMass() + newExcEnergy;
|
||||
|
||||
// select secondary
|
||||
@@ -110,8 +112,11 @@ G4GammaTransition::SampleTransition(G4Fragment* nucleus,
|
||||
G4double emass = part->GetPDGMass();
|
||||
|
||||
// 2-body decay in rest frame
|
||||
G4double ecm = lv.mag();
|
||||
G4ThreeVector bst = lv.boostVector();
|
||||
G4double ecm = lv.mag();
|
||||
const G4double elim2 = 100.*CLHEP::eV*CLHEP::eV;
|
||||
G4bool atRest = (lv.vect().mag2() < elim2);
|
||||
G4ThreeVector bst(0.0, 0.0, 0.0);
|
||||
if (!atRest) { bst = lv.boostVector(); }
|
||||
if(!isGamma) { ecm += (CLHEP::electron_mass_c2 - bond_energy); }
|
||||
|
||||
//G4cout << "Ecm= " << ecm << " mass= " << mass << " emass= " << emass << G4endl;
|
||||
@@ -127,16 +132,19 @@ G4GammaTransition::SampleTransition(G4Fragment* nucleus,
|
||||
mom * fDirection.z(), energy);
|
||||
// residual
|
||||
energy = std::max(ecm - energy, mass);
|
||||
mom = std::sqrt(energy*energy - mass*mass);
|
||||
lv.set(-mom*fDirection.x(), -mom*fDirection.y(), -mom*fDirection.z(), energy);
|
||||
|
||||
// Lab system transform for short lived level
|
||||
lv.boost(bst);
|
||||
if (!atRest) {
|
||||
lv.boost(bst);
|
||||
res4mom.boost(bst);
|
||||
}
|
||||
|
||||
// modified primary fragment
|
||||
nucleus->SetExcEnergyAndMomentum(newExcEnergy, lv);
|
||||
|
||||
// gamma or e- are produced
|
||||
res4mom.boost(bst);
|
||||
result = new G4Fragment(res4mom, part);
|
||||
|
||||
//G4cout << " DeltaE= " << e0 - lv.e() - res4mom.e() + emass
|
||||
|
||||
+186
-151
@@ -50,14 +50,14 @@
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4float G4PhotonEvaporation::GREnergy[] = {0.0f};
|
||||
G4float G4PhotonEvaporation::GRWidth[] = {0.0f};
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex photEvaporationMutex = G4MUTEX_INITIALIZER;
|
||||
constexpr G4double timeLimit = 10*CLHEP::ns;
|
||||
constexpr G4double eLimit = 200*CLHEP::keV;
|
||||
}
|
||||
|
||||
G4PhotonEvaporation::G4PhotonEvaporation(G4GammaTransition* p)
|
||||
@@ -68,7 +68,7 @@ G4PhotonEvaporation::G4PhotonEvaporation(G4GammaTransition* p)
|
||||
}
|
||||
fNuclearLevelData = G4NuclearLevelData::GetInstance();
|
||||
fTolerance = 20*CLHEP::eV;
|
||||
|
||||
fCummProbability[0] = 0.0;
|
||||
if(nullptr == fTransition) { fTransition = new G4GammaTransition(); }
|
||||
|
||||
fSecID = G4PhysicsModelCatalog::GetModelID("model_G4PhotonEvaporation");
|
||||
@@ -89,6 +89,7 @@ void G4PhotonEvaporation::Initialise()
|
||||
G4DeexPrecoParameters* param = fNuclearLevelData->GetParameters();
|
||||
fTolerance = param->GetMinExcitation();
|
||||
fMaxLifeTime = param->GetMaxLifeTime();
|
||||
fLocalTimeLimit = fRDM ? fMaxLifeTime : std::max(fMaxLifeTime, timeLimit);
|
||||
fCorrelatedGamma = param->CorrelatedGamma();
|
||||
fICM = param->GetInternalConversionFlag();
|
||||
fVerbose = param->GetVerbose();
|
||||
@@ -103,7 +104,6 @@ void G4PhotonEvaporation::Initialise()
|
||||
|
||||
void G4PhotonEvaporation::InitialiseGRData()
|
||||
{
|
||||
G4AutoLock l(&photEvaporationMutex);
|
||||
if(0.0f == GREnergy[2]) {
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
const G4float GRWfactor = 0.3f;
|
||||
@@ -112,7 +112,6 @@ void G4PhotonEvaporation::InitialiseGRData()
|
||||
GRWidth[A] = GRWfactor*GREnergy[A];
|
||||
}
|
||||
}
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
G4Fragment*
|
||||
@@ -138,7 +137,7 @@ G4PhotonEvaporation::EmittedFragment(G4Fragment* nucleus)
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "G4PhotonEvaporation::EmittedFragment: "
|
||||
<< *nucleus << G4endl;
|
||||
if(fPolarization) { G4cout << "NucPolar: " << fPolarization << G4endl; }
|
||||
if (nullptr != fPolarization) { G4cout << "NucPolar: " << fPolarization << G4endl; }
|
||||
G4cout << " CorrGamma: " << fCorrelatedGamma << " RDM: " << fRDM
|
||||
<< " fPolarization: " << fPolarization << G4endl;
|
||||
}
|
||||
@@ -147,7 +146,7 @@ G4PhotonEvaporation::EmittedFragment(G4Fragment* nucleus)
|
||||
if(gamma != nullptr) { gamma->SetCreatorModelID(fSecID); }
|
||||
|
||||
// remove G4NuclearPolarizaton when reach ground state
|
||||
if(fNucPStore && fPolarization && 0 == fIndex) {
|
||||
if (nullptr != fNucPStore && nullptr != fPolarization && 0 == fIndex) {
|
||||
if(fVerbose > 3) {
|
||||
G4cout << "G4PhotonEvaporation::EmittedFragment: remove "
|
||||
<< fPolarization << G4endl;
|
||||
@@ -201,19 +200,20 @@ G4bool G4PhotonEvaporation::BreakUpChain(G4FragmentVector* products,
|
||||
|
||||
do {
|
||||
gamma = GenerateGamma(nucleus);
|
||||
if(gamma) {
|
||||
if (nullptr != gamma) {
|
||||
gamma->SetCreatorModelID(fSecID);
|
||||
products->push_back(gamma);
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "G4PhotonEvaporation::BreakUpChain: "
|
||||
<< *gamma << G4endl;
|
||||
G4cout << " Residual: " << *nucleus << G4endl;
|
||||
}
|
||||
// for next decays in the chain always sample time
|
||||
fSampleTime = true;
|
||||
}
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while(gamma);
|
||||
}
|
||||
// for next decays in the chain always sample time
|
||||
fSampleTime = true;
|
||||
if (fVerbose > 2) {
|
||||
G4cout << "G4PhotonEvaporation::BreakUpChain: next decay" << G4endl;
|
||||
if (nullptr != gamma) { G4cout << " " << *gamma << G4endl; }
|
||||
else { G4cout << " not possible" << G4endl; }
|
||||
G4cout << " Residual: " << *nucleus << G4endl;
|
||||
}
|
||||
// Loop checking, 22-Dec-2024, Vladimir Ivanchenko
|
||||
} while (!(nucleus->IsLongLived() || nucleus->GetExcitationEnergy() <= fTolerance));
|
||||
|
||||
// clear nuclear polarization end of chain
|
||||
if(nullptr != fPolarization) {
|
||||
@@ -232,7 +232,6 @@ G4PhotonEvaporation::GetEmissionProbability(G4Fragment* nucleus)
|
||||
fExcEnergy = nucleus->GetExcitationEnergy();
|
||||
G4int Z = nucleus->GetZ_asInt();
|
||||
G4int A = nucleus->GetA_asInt();
|
||||
fCode = 1000*Z + A;
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "G4PhotonEvaporation::GetEmissionProbability: Z="
|
||||
<< Z << " A=" << A << " Eexc(MeV)= " << fExcEnergy << G4endl;
|
||||
@@ -244,54 +243,60 @@ G4PhotonEvaporation::GetEmissionProbability(G4Fragment* nucleus)
|
||||
|
||||
// ignore gamma de-excitation for highly excited levels
|
||||
if(A >= MAXGRDATA) { A = MAXGRDATA-1; }
|
||||
//G4cout<<" GREnergy= "<< GREnergy[A]<<" GRWidth= "<<GRWidth[A]<<G4endl;
|
||||
|
||||
static const G4float GREfactor = 5.0f;
|
||||
if(fExcEnergy >= (G4double)(GREfactor*GRWidth[A] + GREnergy[A])) {
|
||||
G4double edelta = (G4double)(GREfactor*GRWidth[A] + GREnergy[A]);
|
||||
if (fVerbose > 2)
|
||||
G4cout << " GREnergy=" << GREnergy[A] << " GRWidth="<<GRWidth[A]
|
||||
<< " Edelta=" << edelta <<G4endl;
|
||||
if (fExcEnergy >= edelta) {
|
||||
return fProbability;
|
||||
}
|
||||
// probability computed assuming continium transitions
|
||||
// VI: continium transition are limited only to final states
|
||||
// below Fermi energy (this approach needs further evaluation)
|
||||
G4double emax = std::max(0.0, nucleus->ComputeGroundStateMass(Z, A-1)
|
||||
+ CLHEP::neutron_mass_c2 - nucleus->GetGroundStateMass());
|
||||
|
||||
// max energy level for continues transition
|
||||
emax = std::min(emax, fExcEnergy);
|
||||
const G4double eexcfac = 0.99;
|
||||
if(0.0 == emax || fExcEnergy*eexcfac <= emax) { emax = fExcEnergy*eexcfac; }
|
||||
|
||||
fStep = emax;
|
||||
// probability computed assuming continium transitions in the frame of the nucleus
|
||||
fStep = fExcEnergy;
|
||||
const G4double MaxDeltaEnergy = CLHEP::MeV;
|
||||
fPoints = std::min((G4int)(fStep/MaxDeltaEnergy) + 2, MAXDEPOINT);
|
||||
fStep /= ((G4double)(fPoints - 1));
|
||||
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "Emax= " << emax << " Npoints= " << fPoints
|
||||
<< " Eex= " << fExcEnergy << G4endl;
|
||||
G4cout << " Npoints= " << fPoints
|
||||
<< " Eex=" << fExcEnergy << " Estep=" << fStep << G4endl;
|
||||
}
|
||||
|
||||
// integrate probabilities
|
||||
G4double eres = (G4double)GREnergy[A];
|
||||
G4double wres = (G4double)GRWidth[A];
|
||||
G4double eres2= eres*eres;
|
||||
G4double wres2= wres*wres;
|
||||
G4double levelDensity = fNuclearLevelData->GetLevelDensity(Z,A,fExcEnergy);
|
||||
G4double xsqr = std::sqrt(levelDensity*fExcEnergy);
|
||||
|
||||
// initial state
|
||||
G4double levelDensity = fNuclearLevelData->GetLevelDensity(Z,A,fExcEnergy);
|
||||
G4double xdrt = G4Exp(2*std::sqrt(levelDensity*fExcEnergy));
|
||||
|
||||
// the loop over excitation energy of the residual nucleus
|
||||
// from 0 to fExcEnergy
|
||||
// gamma energy is defined via non-relativistic formula
|
||||
G4double egam = fExcEnergy;
|
||||
G4double gammaE2 = egam*egam;
|
||||
G4double gammaR2 = gammaE2*wres2;
|
||||
G4double egdp2 = gammaE2 - eres2;
|
||||
|
||||
G4double p0 = G4Exp(-2.0*xsqr)*gammaR2*gammaE2/(egdp2*egdp2 + gammaR2);
|
||||
G4double p1(0.0);
|
||||
G4double p0 = egam*gammaR2*gammaE2/(egdp2*egdp2 + gammaR2);
|
||||
G4double p1, e;
|
||||
|
||||
for(G4int i=1; i<fPoints; ++i) {
|
||||
egam -= fStep;
|
||||
gammaE2 = egam*egam;
|
||||
gammaR2 = gammaE2*wres2;
|
||||
egdp2 = gammaE2 - eres2;
|
||||
p1 = G4Exp(2.0*(std::sqrt(levelDensity*std::abs(fExcEnergy - egam)) - xsqr))
|
||||
*gammaR2*gammaE2/(egdp2*egdp2 + gammaR2);
|
||||
if (i + 1 == fPoints) {
|
||||
p1 = 0.0;
|
||||
} else {
|
||||
gammaE2 = egam*egam;
|
||||
gammaR2 = gammaE2*wres2;
|
||||
egdp2 = gammaE2 - eres2;
|
||||
e = fExcEnergy - egam;
|
||||
levelDensity = fNuclearLevelData->GetLevelDensity(Z, A, e);
|
||||
p1 = egam*G4Exp(2.0*(std::sqrt(levelDensity*e)))*gammaR2*gammaE2/(egdp2*egdp2 + gammaR2);
|
||||
}
|
||||
fProbability += (p1 + p0);
|
||||
fCummProbability[i] = fProbability;
|
||||
if(fVerbose > 3) {
|
||||
@@ -304,7 +309,7 @@ G4PhotonEvaporation::GetEmissionProbability(G4Fragment* nucleus)
|
||||
|
||||
static const G4double NormC = 1.25*CLHEP::millibarn
|
||||
/(CLHEP::pi2*CLHEP::hbarc*CLHEP::hbarc);
|
||||
fProbability *= fStep*NormC*A;
|
||||
fProbability *= fStep*NormC*A/xdrt;
|
||||
if(fVerbose > 1) { G4cout << "prob= " << fProbability << G4endl; }
|
||||
return fProbability;
|
||||
}
|
||||
@@ -326,7 +331,7 @@ G4PhotonEvaporation::GetFinalLevelEnergy(G4int Z, G4int A, G4double energy)
|
||||
{
|
||||
G4double E = energy;
|
||||
InitialiseLevelManager(Z, A);
|
||||
if(fLevelManager) {
|
||||
if (nullptr != fLevelManager) {
|
||||
E = fLevelManager->NearestLevelEnergy(energy, fIndex);
|
||||
if(E > fLevelEnergyMax + fTolerance) { E = energy; }
|
||||
}
|
||||
@@ -344,14 +349,20 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
|
||||
{
|
||||
if(!isInitialised) { Initialise(); }
|
||||
G4Fragment* result = nullptr;
|
||||
G4double eexc = nucleus->GetExcitationEnergy();
|
||||
if(eexc <= fTolerance) { return result; }
|
||||
|
||||
// initial level
|
||||
G4double eexc = nucleus->GetExcitationEnergy();
|
||||
InitialiseLevelManager(nucleus->GetZ_asInt(), nucleus->GetA_asInt());
|
||||
nucleus->SetLongLived(false);
|
||||
// long life time flag - "true" for a fragment, which will be tracked
|
||||
G4bool isLL = false;
|
||||
// lifetime of the fragment
|
||||
G4double ltime = 0.0;
|
||||
fExcEnergy = eexc;
|
||||
// index is unknown - default is the ground state
|
||||
fIndex = 0;
|
||||
|
||||
G4double time = nucleus->GetCreationTime();
|
||||
|
||||
G4double elevel = eexc;
|
||||
G4double efinal = 0.0;
|
||||
G4double ratio = 0.0;
|
||||
vShellNumber = -1;
|
||||
@@ -360,69 +371,82 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
|
||||
G4int multiP = 0;
|
||||
G4bool isGamma = true;
|
||||
G4bool isDiscrete = false;
|
||||
G4bool finalDiscrete = false;
|
||||
|
||||
const G4NucLevel* level = nullptr;
|
||||
std::size_t ntrans = 0;
|
||||
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "GenerateGamma: " << " Eex= " << eexc
|
||||
G4cout << "## GenerateGamma: Z=" << theZ << " A=" << theA << " Eex= " << eexc
|
||||
<< " Eexmax= " << fLevelEnergyMax << G4endl;
|
||||
}
|
||||
// initial discrete state
|
||||
if(nullptr != fLevelManager && eexc <= fLevelEnergyMax + fTolerance) {
|
||||
// initial discrete state is ground level
|
||||
if (eexc <= fTolerance) {
|
||||
isDiscrete = true;
|
||||
|
||||
// initial state may be a discrete level
|
||||
} else if (nullptr != fLevelManager && eexc <= fLevelEnergyMax + fTolerance) {
|
||||
fIndex = fLevelManager->NearestLevelIndex(eexc);
|
||||
G4double elevel = fLevelManager->LevelEnergy(fIndex);
|
||||
elevel = fLevelManager->LevelEnergy(fIndex);
|
||||
isDiscrete = (std::abs(elevel - eexc) < fTolerance);
|
||||
if(fVerbose > 2) {
|
||||
G4cout << " index= " << fIndex
|
||||
<< " lTime= " << fLevelManager->LifeTime(fIndex) << G4endl;
|
||||
G4cout << " Level index=" << fIndex
|
||||
<< " lTime=" << fLevelManager->LifeTime(fIndex)
|
||||
<< " Elevel=" << elevel
|
||||
<< " isDiscrete:" << isDiscrete << G4endl;
|
||||
}
|
||||
if(isDiscrete && 0 < fIndex) {
|
||||
// for discrete transition
|
||||
level = fLevelManager->GetLevel(fIndex);
|
||||
if(nullptr != level) {
|
||||
if(fVerbose > 2) {
|
||||
G4cout << " ntrans= " << ntrans << " JP= " << JP1
|
||||
<< " RDM: " << fRDM << G4endl;
|
||||
}
|
||||
ntrans = level->NumberOfTransitions();
|
||||
G4int idxfl = fLevelManager->FloatingLevel(fIndex);
|
||||
// for floating level check levels with the same energy
|
||||
if(fLevelManager->FloatingLevel(fIndex) > 0 && 0 == ntrans &&
|
||||
std::abs(elevel - fLevelManager->LevelEnergy(fIndex-1)) < fTolerance) {
|
||||
if (idxfl > 0) {
|
||||
auto newlevel = fLevelManager->GetLevel(fIndex-1);
|
||||
if(nullptr != newlevel && newlevel->NumberOfTransitions() > 0) {
|
||||
--fIndex;
|
||||
level = newlevel;
|
||||
ntrans = level->NumberOfTransitions();
|
||||
G4double newenergy = fLevelManager->LevelEnergy(fIndex-1);
|
||||
if (nullptr != newlevel && std::abs(elevel - newenergy) < fTolerance) {
|
||||
std::size_t newntrans = newlevel->NumberOfTransitions();
|
||||
if (newntrans > 0) {
|
||||
--fIndex;
|
||||
level = newlevel;
|
||||
elevel = newenergy;
|
||||
ntrans = newntrans;
|
||||
}
|
||||
}
|
||||
}
|
||||
JP1 = std::abs(fLevelManager->TwoSpinParity(fIndex));
|
||||
if(fVerbose > 2) {
|
||||
G4cout << " ntrans= " << ntrans << " JP= " << JP1
|
||||
<< " RDM: " << fRDM << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if a level has no defined transitions
|
||||
if (0 == ntrans) {
|
||||
isDiscrete = false;
|
||||
// if a level has no defined transitions
|
||||
if (0 == ntrans) {
|
||||
isDiscrete = false;
|
||||
}
|
||||
// transition from continues spectrum to the ground state
|
||||
} else if (0 == fIndex) {
|
||||
isDiscrete = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(fVerbose > 2) {
|
||||
G4long prec = G4cout.precision(4);
|
||||
G4cout << "GenerateGamma: Z= " << nucleus->GetZ_asInt()
|
||||
<< " A= " << nucleus->GetA_asInt()
|
||||
<< " Exc= " << eexc << " Emax= "
|
||||
<< fLevelEnergyMax << " idx= " << fIndex
|
||||
<< " fCode= " << fCode << " fPoints= " << fPoints
|
||||
<< " Ntr= " << ntrans << " discrete: " << isDiscrete
|
||||
<< " fProb= " << fProbability << G4endl;
|
||||
G4cout << " Z=" << nucleus->GetZ_asInt()
|
||||
<< " A=" << nucleus->GetA_asInt()
|
||||
<< " Exc=" << eexc << " Emax="
|
||||
<< fLevelEnergyMax << " idx=" << fIndex
|
||||
<< " fPoints= " << fPoints
|
||||
<< " Ntr=" << ntrans << " discrete:" << isDiscrete
|
||||
<< G4endl;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
|
||||
// continues part
|
||||
if(!isDiscrete) {
|
||||
// we compare current excitation versus value used for probability
|
||||
// computation and also Z and A used for probability computation
|
||||
if(fCode != 1000*theZ + theA || eexc != fExcEnergy) {
|
||||
GetEmissionProbability(nucleus);
|
||||
}
|
||||
// primary fragment is in continium
|
||||
GetEmissionProbability(nucleus);
|
||||
|
||||
if(fProbability == 0.0) {
|
||||
fPoints = 1;
|
||||
efinal = 0.0;
|
||||
@@ -440,60 +464,64 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
|
||||
}
|
||||
}
|
||||
}
|
||||
// final discrete level
|
||||
// final discrete level or continues exitation energy
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "Continues proposes Efinal= " << efinal << G4endl;
|
||||
G4cout << "Continues proposes Efinal=" << efinal
|
||||
<< " Initial Idx=" << fIndex << G4endl;
|
||||
}
|
||||
|
||||
if(nullptr != fLevelManager) {
|
||||
if(efinal < fLevelEnergyMax) {
|
||||
fIndex = fLevelManager->NearestLevelIndex(efinal, fIndex);
|
||||
efinal = fLevelManager->LevelEnergy(fIndex);
|
||||
// protection - take level below
|
||||
if(efinal >= eexc && 0 < fIndex) {
|
||||
--fIndex;
|
||||
efinal = fLevelManager->LevelEnergy(fIndex);
|
||||
}
|
||||
nucleus->SetFloatingLevelNumber(fLevelManager->FloatingLevel(fIndex));
|
||||
|
||||
// not allowed to have final energy above max energy
|
||||
// if G4LevelManager exist
|
||||
} else {
|
||||
efinal = fLevelEnergyMax;
|
||||
// final discrete level
|
||||
if (efinal < fLevelEnergyMax + fTolerance) {
|
||||
fIndex = fLevelManager->NearestLevelIndex(efinal, fIndex);
|
||||
G4double el = fLevelManager->LevelEnergy(fIndex);
|
||||
// protection - take level below
|
||||
if (el >= eexc + fTolerance && 0 < fIndex) {
|
||||
--fIndex;
|
||||
el = fLevelManager->LevelEnergy(fIndex);
|
||||
}
|
||||
// further decays will be discrete
|
||||
if (std::abs(efinal - el) <= eLimit) {
|
||||
efinal = el;
|
||||
finalDiscrete = true;
|
||||
} else {
|
||||
fIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fVerbose > 2) {
|
||||
G4cout << "Continues emission efinal(MeV)= " << efinal << G4endl;
|
||||
G4cout << "Continues emission efinal(MeV)= " << efinal
|
||||
<< " idxFinal=" << fIndex << " isdiscrete:" << isDiscrete << G4endl;
|
||||
}
|
||||
//discrete part ground state
|
||||
} else if (0 == fIndex) {
|
||||
G4bool isLL = false;
|
||||
if (nullptr != fLevelManager) {
|
||||
G4double ltime = fLevelManager->LifeTime(0);
|
||||
if(ltime > fMaxLifeTime) { isLL = true; }
|
||||
}
|
||||
nucleus->SetLongLived(isLL);
|
||||
return result;
|
||||
|
||||
//discrete part
|
||||
// initial continues and final ground state
|
||||
} else if (0 == fIndex) {
|
||||
efinal = 0.0;
|
||||
isDiscrete = false;
|
||||
if (nullptr != fLevelManager) { finalDiscrete = true; }
|
||||
|
||||
// discrete part for excited nucleus
|
||||
} else {
|
||||
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "Discrete emission from level Index= " << fIndex
|
||||
<< " Elevel= " << fLevelManager->LevelEnergy(fIndex)
|
||||
<< " Ltime= " << fLevelManager->LifeTime(fIndex)
|
||||
<< " LtimeMax= " << fMaxLifeTime
|
||||
<< " RDM= " << fRDM << " ICM= " << fICM << G4endl;
|
||||
if (fVerbose > 2) {
|
||||
G4cout << "Discrete emission from level Index=" << fIndex
|
||||
<< " Elevel=" << fLevelManager->LevelEnergy(fIndex)
|
||||
<< " Ltime=" << fLevelManager->LifeTime(fIndex)
|
||||
<< " LtimeMax=" << fLocalTimeLimit
|
||||
<< " RDM=" << fRDM << " ICM=" << fICM << G4endl;
|
||||
}
|
||||
|
||||
// stable fragment has life time -1 or above the limit
|
||||
// if is called from the radioactive decay the life time is not checked
|
||||
G4double ltime = fLevelManager->LifeTime(fIndex);
|
||||
if (!fRDM && ltime > fMaxLifeTime) {
|
||||
// stable fragment has life time DBL_MAX
|
||||
ltime = fLevelManager->LifeTime(fIndex);
|
||||
|
||||
// stable isomer - no sampling of transition
|
||||
if (ltime == DBL_MAX) {
|
||||
nucleus->SetFloatingLevelNumber(0);
|
||||
nucleus->SetLongLived(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
// sampling index of a final level
|
||||
std::size_t idx = 0;
|
||||
if(1 < ntrans) {
|
||||
idx = level->SampleGammaTransition(G4UniformRand());
|
||||
@@ -502,7 +530,10 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
|
||||
G4cout << "Ntrans= " << ntrans << " idx= " << idx
|
||||
<< " ICM= " << fICM << " abs(JP1)= " << JP1 << G4endl;
|
||||
}
|
||||
G4double prob = level->GammaProbability(idx);
|
||||
|
||||
// sampling IC or gamma transition
|
||||
G4double prob = (G4double)level->GammaProbability(idx);
|
||||
|
||||
// prob = 0 means that there is only internal conversion
|
||||
if (prob < 1.0) {
|
||||
G4double rndm = G4UniformRand();
|
||||
@@ -514,53 +545,57 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
|
||||
}
|
||||
}
|
||||
}
|
||||
// it is discrete transition with possible gamma correlation
|
||||
// it is a discrete transition with possible gamma correlation
|
||||
ratio = level->MultipolarityRatio(idx);
|
||||
multiP = level->TransitionType(idx);
|
||||
fIndex = level->FinalExcitationIndex(idx);
|
||||
JP2 = std::abs(fLevelManager->TwoSpinParity(fIndex));
|
||||
finalDiscrete = true;
|
||||
|
||||
// final energy and time
|
||||
// final level parameters
|
||||
efinal = fLevelManager->LevelEnergy(fIndex);
|
||||
// time is sampled if decay not prompt and this class called not
|
||||
// from radioactive decay and isomer production is enabled
|
||||
if(fSampleTime && ltime < DBL_MAX) {
|
||||
if(fSampleTime && ltime > 0.0) {
|
||||
time -= ltime*G4Log(G4UniformRand());
|
||||
}
|
||||
nucleus->SetFloatingLevelNumber(fLevelManager->FloatingLevel(fIndex));
|
||||
}
|
||||
|
||||
G4bool isLL = false;
|
||||
if(nullptr != fLevelManager) {
|
||||
G4double ltime = fLevelManager->LifeTime(fIndex);
|
||||
if(ltime > fMaxLifeTime) { isLL = true; }
|
||||
ltime = 0.0;
|
||||
if (finalDiscrete) {
|
||||
ltime = fLevelManager->LifeTime(fIndex);
|
||||
JP2 = fLevelManager->TwoSpinParity(fIndex);
|
||||
}
|
||||
nucleus->SetLongLived(isLL);
|
||||
|
||||
// protection for floating levels
|
||||
if(std::abs(efinal - eexc) <= fTolerance) { return result; }
|
||||
|
||||
result = fTransition->SampleTransition(nucleus, efinal, ratio, JP1,
|
||||
JP2, multiP, vShellNumber,
|
||||
isDiscrete, isGamma);
|
||||
if(nullptr != result) { result->SetCreationTime(time); }
|
||||
|
||||
// updated residual nucleus
|
||||
// sample continues or discrete transition if transition
|
||||
// is above distance between floating level
|
||||
if (std::abs(efinal - eexc) > fTolerance) {
|
||||
result = fTransition->SampleTransition(nucleus, efinal, ratio, JP1,
|
||||
std::abs(JP2), multiP, vShellNumber,
|
||||
isDiscrete, isGamma);
|
||||
if (nullptr != result) { result->SetCreationTime(time); }
|
||||
}
|
||||
// update parameters of the fragment
|
||||
nucleus->SetCreationTime(time);
|
||||
nucleus->SetSpin(0.5*JP2);
|
||||
if(nullptr != fPolarization) { fPolarization->SetExcitationEnergy(efinal); }
|
||||
if (nullptr != fPolarization) { fPolarization->SetExcitationEnergy(efinal); }
|
||||
|
||||
if (finalDiscrete) {
|
||||
G4int idxfl = fLevelManager->FloatingLevel(fIndex);
|
||||
nucleus->SetFloatingLevelNumber(idxfl);
|
||||
|
||||
// ignore the floating levels with zero energy and create ground state
|
||||
if(efinal == 0.0 && fIndex > 0) {
|
||||
fIndex = 0;
|
||||
nucleus->SetFloatingLevelNumber(fLevelManager->FloatingLevel(0));
|
||||
if (ltime > fLocalTimeLimit) { isLL = true; }
|
||||
}
|
||||
nucleus->SetLongLived(isLL);
|
||||
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "Final level E= " << efinal << " time= " << time
|
||||
<< " idxFinal= " << fIndex << " isDiscrete: " << isDiscrete
|
||||
<< " isGamma: " << isGamma << " multiP= " << multiP
|
||||
<< " shell= " << vShellNumber
|
||||
if (fVerbose > 2) {
|
||||
G4String ss = "## ";
|
||||
if (isLL && efinal > 0.0 && efinal < MeV) { ss += "=I="; }
|
||||
if (isLL && efinal >= MeV) { ss += "=J="; }
|
||||
if (efinal >= 6*MeV) { ss += "=K="; }
|
||||
G4cout << " " << ss << " Efinal=" << efinal
|
||||
<< " Efrag=" << nucleus->GetExcitationEnergy()
|
||||
<< " lt=" << ltime
|
||||
<< " idxFin=" << fIndex << " isDiscrete:" << isDiscrete
|
||||
<< " isGamma:" << isGamma << " isStable:" << isLL
|
||||
<< " multiP=" << multiP << " shell=" << vShellNumber
|
||||
<< " abs(JP1)= " << JP1 << " abs(JP2)= " << JP2 << G4endl;
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-01-10 Vladimir Ivanchenko (radioactive_decay-V11-02-06)
|
||||
- G4RadioactiveDecay - fixed problem 2592 - enable biasing in radioactive decay
|
||||
|
||||
## 2024-08-14 Gabriele Cosmo (radioactive_decay-V11-02-05)
|
||||
- Fixed reported Coverity defects for use of std::move().
|
||||
|
||||
|
||||
@@ -877,6 +877,8 @@ G4RadioactiveDecay::DecayIt(const G4Track& theTrack, const G4Step&)
|
||||
G4ThreeVector currentPosition;
|
||||
currentPosition = theTrack.GetPosition();
|
||||
|
||||
fParticleChangeForRadDecay.SetSecondaryWeightByProcess(true);
|
||||
|
||||
G4IonTable* theIonTable;
|
||||
G4ParticleDefinition* parentNucleus;
|
||||
|
||||
|
||||
@@ -7,6 +7,14 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-03-05 Vladimir Ivanchenko (hadr-util-V11-02-06)
|
||||
- G4HadronicDeveloperParameters - added limitation of warning printout on
|
||||
change of parameters (NA64 request).
|
||||
|
||||
## 2025-01-09 Vladimir Ivanchenko
|
||||
- G4Fragment - added protection against precision loss in computation of a boost
|
||||
vector at rest
|
||||
|
||||
## 2024-10-29 Vladimir Ivanchenko (hadr-util-V11-02-05)
|
||||
- G4LegendrePolynomial - optimized implementation by Isaac Kunen GitHub PR #70
|
||||
|
||||
|
||||
@@ -89,6 +89,9 @@ class G4HadronicDeveloperParameters
|
||||
void issue_non_eligible_value( const G4String& name );
|
||||
void issue_is_already_defined( const G4String& name );
|
||||
void issue_is_modified( const G4String& name );
|
||||
|
||||
G4int nWarn{0};
|
||||
G4int nWarnMax{5};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -205,7 +205,9 @@ void G4Fragment::SetExcEnergyAndMomentum(G4double eexc,
|
||||
{
|
||||
theExcitationEnergy = eexc;
|
||||
theMomentum.set(0.0, 0.0, 0.0, theGroundStateMass + eexc);
|
||||
theMomentum.boost(v.boostVector());
|
||||
const G4double elim2 = 100.*CLHEP::eV*CLHEP::eV;
|
||||
if (v.vect().mag2() > elim2)
|
||||
theMomentum.boost(v.boostVector());
|
||||
}
|
||||
|
||||
G4double G4Fragment::GetBindingEnergy() const
|
||||
|
||||
@@ -332,6 +332,8 @@ void G4HadronicDeveloperParameters::issue_is_already_defined( const G4String& na
|
||||
G4Exception( "G4HadronicDeveloperParameters" , "HadDevPara_004", FatalException , text );
|
||||
}
|
||||
void G4HadronicDeveloperParameters::issue_is_modified( const G4String& name ) {
|
||||
if (nWarn > nWarnMax) { return; }
|
||||
++nWarn;
|
||||
G4String text("Parameter ");
|
||||
text += name;
|
||||
text += " has changed from default value.";
|
||||
|
||||
@@ -6,6 +6,12 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-02-12 Ben Morgan (procscore-V11-02-01)
|
||||
- Apply [GitHub PR 80](https://github.com/Geant4/geant4/pull/80)
|
||||
- Changes to `G4EnergySplitter` to ensure that each call to `SplitEnergyInVolumes()`
|
||||
utilizes the correct phantom parameterization.
|
||||
- Fixes [Bugzilla 2636](https://bugzilla-geant4.kek.jp/show_bug.cgi?id=2636)
|
||||
|
||||
## 2024-10-10 Pedro Arce (procscore-V11-02-00)
|
||||
- Safeguard for 0 energy deposited in G4EnergySplitter
|
||||
- Fix bug #2629
|
||||
|
||||
@@ -72,7 +72,6 @@ class G4EnergySplitter
|
||||
private:
|
||||
void GetStepLength(G4int stepNo, G4double& stepLength);
|
||||
|
||||
void GetPhantomParam(G4bool mustExist);
|
||||
G4bool IsPhantomVolume(G4VPhysicalVolume* pv);
|
||||
|
||||
G4EnergyLossForExtrapolator* theElossExt;
|
||||
|
||||
@@ -66,7 +66,10 @@ inline void G4EnergySplitter::SetNIterations(G4int niter)
|
||||
//-----------------------------------------------------------------------
|
||||
inline G4Material* G4EnergySplitter::GetVoxelMaterial(G4int stepNo)
|
||||
{
|
||||
if (thePhantomParam == nullptr) GetPhantomParam(true);
|
||||
if (thePhantomParam == nullptr) {
|
||||
G4Exception("G4EnergySplitter::GetVoxelMaterial()", "PhantomParamError",
|
||||
FatalException, "Phantom parameterisation not set -- SplitEnergyInVolumes() must be called first");
|
||||
}
|
||||
G4int voxelID;
|
||||
GetVoxelID(stepNo, voxelID);
|
||||
return thePhantomParam->GetMaterial(voxelID);
|
||||
|
||||
@@ -82,7 +82,14 @@ G4int G4EnergySplitter::SplitEnergyInVolumes(const G4Step* aStep)
|
||||
return (G4int)theEnergies.size();
|
||||
}
|
||||
|
||||
if (thePhantomParam == nullptr) GetPhantomParam(true);
|
||||
//----- Get the phantom parameterisation from the G4Step
|
||||
auto preStepPhysVol = aStep->GetPreStepPoint()->GetPhysicalVolume();
|
||||
if (!IsPhantomVolume(preStepPhysVol)) {
|
||||
G4Exception("G4EnergySplitter::SplitEnergyInVolumes", "PhantomParamError", FatalException,
|
||||
"SplitEnergyInVolumes() called for a step not in a phantom volume");
|
||||
}
|
||||
auto phantomVol = static_cast<G4PVParameterised*>(preStepPhysVol);
|
||||
thePhantomParam = static_cast<G4PhantomParameterisation*>(phantomVol->GetParameterisation());
|
||||
|
||||
//----- Distribute energy deposited in voxels
|
||||
std::vector<std::pair<G4int, G4double>> rnsl =
|
||||
@@ -278,23 +285,6 @@ G4int G4EnergySplitter::SplitEnergyInVolumes(const G4Step* aStep)
|
||||
return (G4int)theEnergies.size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void G4EnergySplitter::GetPhantomParam(G4bool mustExist)
|
||||
{
|
||||
G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
|
||||
for (const auto pv : *pvs) {
|
||||
if (IsPhantomVolume(pv)) {
|
||||
const auto pvparam = static_cast<const G4PVParameterised*>(pv);
|
||||
G4VPVParameterisation* param = pvparam->GetParameterisation();
|
||||
thePhantomParam = static_cast<G4PhantomParameterisation*>(param);
|
||||
}
|
||||
}
|
||||
|
||||
if ((thePhantomParam == nullptr) && mustExist)
|
||||
G4Exception("G4EnergySplitter::GetPhantomParam", "PhantomParamError", FatalException,
|
||||
"No G4PhantomParameterisation found !");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
G4bool G4EnergySplitter::IsPhantomVolume(G4VPhysicalVolume* pv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user