Import Geant4 11.1.2 source tree

This commit is contained in:
Gabriele Cosmo
2023-06-19 17:17:14 +02:00
parent 84a556a9dc
commit aef78ca386
309 changed files with 35572 additions and 34678 deletions
@@ -6,6 +6,17 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-04-17 Alberto Ribon (hadr-casc-V11-00-06)
- G4BigBanger : added protection in the method G4BigBanger::generateBangInSCM
to avoid very rare cases of unphysical negative energy of one of the
secondaries produced by the Bertini model.
(Note: this problem was never reproduced in our tests, but was reported by
ATLAS with Geant4 10.6; the secondaries with negative - both total
and kinetic - energy were always neutrons, produced by the internal
Bertini nuclear de-excitation, after the intra-nuclear cascade.
Many thanks to Mihaly Novak for providing detailed debugging
information!)
## 2022-11-26 Gabriele Cosmo (hadr-casc-V11-00-05)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -225,6 +225,17 @@ void G4BigBanger::generateBangInSCM(G4double etot, G4int a, G4int z) {
particles.resize(a); // Use assignment to avoid temporaries
for(G4int i = 0; i < a; i++) {
G4int knd = i < z ? 1 : 2;
// Set to 0.0 the 4-th component (total energy) of the Lorentz momentum scm_momentums[i]
// in order to avoid very rare cases of unphysical negative (total and kinetic) energy
// (as reported by ATLAS with Geant4 10.6, but never reproduced in our tests).
// Note that these 4-vectors are actually 3-vectors, with null 4-th component in nearly
// all cases. After calling the method G4InuclElementaryParticle::fill (see below),
// the 4-th component of the momentum is set (in the method G4InuclParticle::setMomentum
// which in turn calls G4DynamicParticle::SetMomentum ) to the square root of the sum of
// the square of the mass and the square of the magnitude of the 3-momentum.
scm_momentums[i].setE( 0.0 );
particles[i].fill(scm_momentums[i], knd, G4InuclParticle::BigBanger);
};
};
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-03-17 Alberto Ribon (hadr-inclxx-V11-00-09)
- G4INCLNNToNLK2piChannel : fixed bug in the method fillFinalState.
Thanks to Dmitri Konstantinov for reporting it.
## 2022-11-26 Gabriele Cosmo (hadr-inclxx-V11-00-08)
- Fixed more compilation warnings for implicit type conversions.
@@ -102,7 +102,8 @@ namespace G4INCL {
Pion2Type = PiZero;
}
}if(iso == -2){
}
else if(iso == -2){
if(rdm*7. < 1.){
particle1->setType(Neutron);
KaonType = KZero;
@@ -6,6 +6,22 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-06-16 Vladimir Ivanchenko (hadr-hpp-V11-00-22)
- G4ParticleHPInelasticBaseFS - real fix of memory leak reported by Coverity
## 2023-06-07 Vladimir Ivanchenko
- G4ParticleHPInelasticBaseFS - fix potential memory leak reported by Coverity
## 2023-03-13 Vladimir Ivanchenko (hadr-hpp-V11-00-21)
- G4ParticleHPNucLevel : added new data structure for nuclear levels
- G4ParticleHPDeExGammas : rewitten in order to avoid usage of C-arrays,
which provoked a problem for CMS static build; code now fully based on
std::vector of G4ParticleHPNucLevel; public interfaces are not changed;
if in DB probability of decay for a given level is zero, it is
substituted by 1.e-6
- G4ParticleHPInelasticBaseFS, G4ParticleHPInelasticCompFS - gamma cascade
sampling is checked and simplified (removed unnecessary computations)
## 2023-02-06 Gabriele Cosmo (hadr-hpp-V11-00-20)
- Minor cleanup in G4ParticleHPDeExGammas header for data initialisation.
@@ -25,84 +25,41 @@
//
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
// V.Ivanchenko 23.04.2023 Rewritten
//
#ifndef G4ParticleHPDeExGammas_h
#define G4ParticleHPDeExGammas_h 1
#include <fstream>
#include <CLHEP/Units/PhysicalConstants.h>
#include "globals.hh"
#include "G4ios.hh"
#include "G4ParticleHPNucLevel.hh"
#include "G4ReactionProductVector.hh"
#include "G4Gamma.hh"
#include "G4ParticleHPLevel.hh"
#include "G4ParticleHPGamma.hh"
#include "G4ReactionProduct.hh"
#include "globals.hh"
#include <fstream>
#include <vector>
class G4ParticleHPDeExGammas
{
public:
G4ParticleHPDeExGammas()
{
}
~G4ParticleHPDeExGammas()
{
delete [] levelStart;
delete [] levelSize;
delete [] theLevels;
}
void Init(std::istream & aDataFile);
explicit G4ParticleHPDeExGammas();
~G4ParticleHPDeExGammas();
inline G4ReactionProductVector * GetDecayGammas(G4int aLevel)
{
if(aLevel>nLevels-1 || aLevel<0) return nullptr;
if(nLevels==0) return new G4ReactionProductVector();
G4ReactionProductVector * result = new G4ReactionProductVector;
G4DynamicParticleVector * theResult;
void Init(std::istream& aDataFile);
theResult = theLevels[aLevel]. GetDecayGammas();
G4ReactionProduct * theCurrent;
for(unsigned int i=0; i<theResult->size(); ++i)
G4ReactionProductVector* GetDecayGammas(G4int idx) const;
inline G4int GetNumberOfLevels() const { return nLevels; }
inline G4double GetLevelEnergy(G4int idx) const
{
theCurrent = new G4ReactionProduct;
*theCurrent = *(theResult->operator[](i));
delete theResult->operator[](i);
G4double costheta = 2.*G4UniformRand()-1;
G4double theta = std::acos(costheta);
G4double phi = CLHEP::twopi*G4UniformRand();
G4double sinth = std::sin(theta);
G4double en = theCurrent->GetTotalMomentum();
G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*costheta );
theCurrent->SetMomentum( temp ) ;
result->push_back(theCurrent);
return (idx < nLevels && idx >= 0) ? theLevels[idx]->GetLevelEnergy() : 0.0;
}
delete theResult;
return result;
}
inline G4ParticleHPLevel * GetLevel(G4int i)
{
if(i>nLevels-1) return nullptr;
return theLevels+i;
}
inline G4int GetNumberOfLevels() { return nLevels; }
inline G4double GetLevelEnergy(G4int aLevel)
{
if(aLevel>nLevels-1 || aLevel<0) return 0;
G4double result = theLevels[aLevel].GetLevelEnergy();
return result;
}
G4ParticleHPDeExGammas(const G4ParticleHPDeExGammas&) = delete;
const G4ParticleHPDeExGammas& operator=(const G4ParticleHPDeExGammas&) = delete;
private:
G4int * levelStart = nullptr;
G4int * levelSize = nullptr;
G4int nLevels = 0;
G4ParticleHPLevel * theLevels = nullptr;
G4int nLevels = 0;
std::vector<G4ParticleHPNucLevel*> theLevels;
};
#endif
@@ -29,26 +29,25 @@
#ifndef G4ParticleHPInelasticBaseFS_h
#define G4ParticleHPInelasticBaseFS_h 1
#include "globals.hh"
#include "G4HadProjectile.hh"
#include "G4HadFinalState.hh"
#include "G4ParticleHPFinalState.hh"
#include "G4ParticleHPAngular.hh"
#include "G4ParticleHPEnergyDistribution.hh"
#include "G4ParticleHPEnAngCorrelation.hh"
#include "G4ParticleHPPhotonDist.hh"
#include "G4ParticleHPDeExGammas.hh"
#include "G4HadProjectile.hh"
#include "G4Nucleus.hh"
#include "G4ParticleHPAngular.hh"
#include "G4ParticleHPDeExGammas.hh"
#include "G4ParticleHPEnAngCorrelation.hh"
#include "G4ParticleHPEnergyDistribution.hh"
#include "G4ParticleHPFinalState.hh"
#include "G4ParticleHPPhotonDist.hh"
#include "globals.hh"
class G4ParticleHPInelasticBaseFS : public G4ParticleHPFinalState
{
public:
G4ParticleHPInelasticBaseFS()
{
hasXsec = true;
hasXsec = true;
theXsection = new G4ParticleHPVector;
theEnergyDistribution = 0;
theFinalStatePhotons = 0;
theEnergyAngData = 0;
@@ -66,33 +65,31 @@ class G4ParticleHPInelasticBaseFS : public G4ParticleHPFinalState
if (theEnergyAngData != 0) delete theEnergyAngData;
if (theAngularDistribution != 0) delete theAngularDistribution;
}
void Init (G4double A, G4double Z, G4int M, G4String& dirName,
G4String& bit, G4ParticleDefinition*);
void BaseApply(const G4HadProjectile& theTrack,
G4ParticleDefinition** theDefs, G4int nDef);
void Init(G4double A, G4double Z, G4int M, G4String& dirName, G4String& bit,
G4ParticleDefinition*);
void BaseApply(const G4HadProjectile& theTrack, G4ParticleDefinition** theDefs, G4int nDef);
void InitGammas(G4double AR, G4double ZR);
virtual G4HadFinalState* ApplyYourself(const G4HadProjectile& theTrack) = 0;
virtual G4ParticleHPFinalState* New() = 0;
virtual G4double GetXsec(G4double anEnergy)
{
return std::max(0., theXsection->GetY(anEnergy));
}
virtual G4ParticleHPVector* GetXsec() {return theXsection;}
virtual G4ParticleHPVector* GetXsec() { return theXsection; }
protected:
G4ParticleHPVector* theXsection;
G4ParticleHPEnergyDistribution* theEnergyDistribution;
G4ParticleHPAngular* theAngularDistribution;
G4ParticleHPEnAngCorrelation* theEnergyAngData;
G4ParticleHPPhotonDist* theFinalStatePhotons;
G4double theNuclearMassDifference;
G4ParticleHPDeExGammas theGammas;
@@ -27,36 +27,34 @@
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
// June-2019 - E. Mendoza - re-build "two_body_reaction", to be used by
// incident charged particles (now isotropic emission in the CMS).
// Also restrict nresp use below 20 MeV (for future developments).
// incident charged particles (now isotropic emission in the CMS).
// Also restrict nresp use below 20 MeV (for future developments).
// Add photon emission when no data available.
#ifndef G4ParticleHPInelasticCompFS_h
#define G4ParticleHPInelasticCompFS_h 1
#include "globals.hh"
#include "G4HadProjectile.hh"
#include "G4HadFinalState.hh"
#include "G4ParticleHPFinalState.hh"
#include "G4ParticleHPAngular.hh"
#include "G4ParticleHPEnergyDistribution.hh"
#include "G4ParticleHPEnAngCorrelation.hh"
#include "G4ParticleHPPhotonDist.hh"
#include "G4ParticleHPDeExGammas.hh"
#include "G4Nucleus.hh"
#include "G4HadProjectile.hh"
#include "G4NRESP71M03.hh"
#include "G4Nucleus.hh"
#include "G4ParticleHPAngular.hh"
#include "G4ParticleHPDeExGammas.hh"
#include "G4ParticleHPEnAngCorrelation.hh"
#include "G4ParticleHPEnergyDistribution.hh"
#include "G4ParticleHPFinalState.hh"
#include "G4ParticleHPPhotonDist.hh"
#include "globals.hh"
class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
{
public:
G4ParticleHPInelasticCompFS()
{
QI.resize(51);
LR.resize(51);
for(G4int i=0; i<51; i++) {
hasXsec = true;
for (G4int i = 0; i < 51; i++) {
hasXsec = true;
theXsection[i] = 0;
theEnergyDistribution[i] = 0;
theAngularDistribution[i] = 0;
@@ -69,7 +67,7 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
virtual ~G4ParticleHPInelasticCompFS()
{
for(G4int i=0; i<51; i++) {
for (G4int i = 0; i < 51; i++) {
if (theXsection[i] != 0) delete theXsection[i];
if (theEnergyDistribution[i] != 0) delete theEnergyDistribution[i];
if (theAngularDistribution[i] != 0) delete theAngularDistribution[i];
@@ -78,8 +76,8 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
}
}
void Init(G4double A, G4double Z, G4int M, G4String& dirName,
G4String& aSFType, G4ParticleDefinition*);
void Init(G4double A, G4double Z, G4int M, G4String& dirName, G4String& aSFType,
G4ParticleDefinition*);
void InitGammas(G4double AR, G4double ZR);
@@ -96,12 +94,10 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
G4int SelectExitChannel(G4double eKinetic);
void CompositeApply(const G4HadProjectile& theTrack,
G4ParticleDefinition* aHadron);
void CompositeApply(const G4HadProjectile& theTrack, G4ParticleDefinition* aHadron);
inline void InitDistributionInitialState(G4ReactionProduct& anIncidentPart,
G4ReactionProduct& aTarget,
G4int it)
inline void InitDistributionInitialState(G4ReactionProduct& anIncidentPart,
G4ReactionProduct& aTarget, G4int it)
{
if (theAngularDistribution[it] != 0) {
theAngularDistribution[it]->SetTarget(aTarget);
@@ -113,32 +109,30 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
theEnergyAngData[it]->SetProjectileRP(anIncidentPart);
}
}
protected:
G4ParticleHPVector* theXsection[51];
G4ParticleHPEnergyDistribution* theEnergyDistribution[51];
G4ParticleHPAngular* theAngularDistribution[51];
G4ParticleHPEnAngCorrelation* theEnergyAngData[51];
G4ParticleHPPhotonDist* theFinalStatePhotons[51];
G4ParticleHPDeExGammas theGammas;
G4String gammaPath;
protected:
std::vector<G4double> QI;
std::vector<G4int> LR;
private:
// (projectile, target, hadron, mu of hadron)
// (projectile, target, hadron, mu of hadron)
void two_body_reaction(G4ReactionProduct* proj, G4ReactionProduct* targ,
G4ReactionProduct* product, G4double resExcitationEnergy);
G4NRESP71M03 nresp71_model;
G4bool use_nresp71_model(const G4ParticleDefinition* aDefinition, const G4int it,
G4bool use_nresp71_model(const G4ParticleDefinition* aDefinition, const G4int it,
const G4ReactionProduct& theTarget, G4ReactionProduct& boosted);
};
#endif
@@ -24,56 +24,54 @@
// ********************************************************************
//
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
// V. Ivanchenko, 21 April 2023
//
#ifndef G4ParticleHPLevel_h
#define G4ParticleHPLevel_h 1
// Data structure class for gamma levels to replace gamma data classes
// of P. Arce
//
#ifndef G4ParticleHPNucLevel_h
#define G4ParticleHPNucLevel_h 1
#include "G4ReactionProduct.hh"
#include "globals.hh"
#include "G4ios.hh"
#include <fstream>
#include "G4DynamicParticleVector.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
class G4ParticleHPGamma;
class G4ParticleHPLevel
#include <vector>
class G4ParticleHPNucLevel
{
public:
G4ParticleHPLevel()
{
nGammas = 0;
theGammas = 0;
levelEnergy = 0.0;
}
explicit G4ParticleHPNucLevel(G4double e);
~G4ParticleHPNucLevel() = default;
~G4ParticleHPLevel();
void SetNumberOfGammas(G4int aGammas);
void SetGamma(G4int i, G4ParticleHPGamma * aGamma);
G4DynamicParticleVector * GetDecayGammas();
inline void SetLevelEnergy(G4double anEnergy)
{
levelEnergy = anEnergy;
}
inline G4double GetLevelEnergy()
{
return levelEnergy;
}
void AddGamma(G4double e, G4double w, G4int idx);
void Normalize();
G4ReactionProduct* GetDecayGamma(G4int& idx) const;
inline G4double GetLevelEnergy() const { return levelEnergy; }
inline G4double GetNumberOfGammas() const { return nGammas; }
inline G4double GetGammaEnergy(G4int idx) const
{
return (idx < nGammas && idx >= 0) ? gammas[idx].gammaEnergy : 0.0;
}
G4ParticleHPNucLevel(const G4ParticleHPNucLevel&) = delete;
const G4ParticleHPNucLevel& operator=(const G4ParticleHPNucLevel&) = delete;
G4double GetGammaEnergy(G4int i);
private:
G4double levelEnergy;
G4int nGammas = 0;
G4double levelEnergy;
G4int nGammas;
G4ParticleHPGamma ** theGammas;
struct gammaData
{
G4double gammaEnergy;
G4double cumProbability;
G4int next;
};
std::vector<gammaData> gammas;
};
#endif
@@ -9,7 +9,6 @@ geant4_add_module(G4had_par_hp
G4NRESP71M03.hh
G4ParticleHPList.hh
G4ParticleHPIsoData.hh
G4ParticleHPLevel.hh
G4ParticleHP2AInelasticFS.hh
G4ParticleHPNames.hh
G4ParticleHP2N2AInelasticFS.hh
@@ -66,7 +65,6 @@ geant4_add_module(G4had_par_hp
G4ParticleHPFissionERelease.hh
G4ParticleHPFissionFS.hh
G4ParticleHPFissionSpectrum.hh
G4ParticleHPGamma.hh
G4ParticleHPHash.hh
G4ParticleHPHe3InelasticFS.hh
G4ParticleHPInelastic.hh
@@ -98,6 +96,7 @@ geant4_add_module(G4had_par_hp
G4ParticleHPNT2AInelasticFS.hh
G4ParticleHPNTInelasticFS.hh
G4ParticleHPNXInelasticFS.hh
G4ParticleHPNucLevel.hh
G4ParticleHPParticleYield.hh
G4ParticleHPPAInelasticFS.hh
G4ParticleHPPDInelasticFS.hh
@@ -142,9 +141,10 @@ geant4_add_module(G4had_par_hp
G4WattFissionSpectrumValues.hh
### FissionFragment Generator - end
### Headers of NeutronHP for backward compatibility - start
G4NeutronHPGamma.hh
G4NeutronHPLevel.hh
G4NeutronHPList.hh
G4NeutronHPIsoData.hh
G4NeutronHPLevel.hh
G4NeutronHP2AInelasticFS.hh
G4NeutronHPNames.hh
G4NeutronHP2N2AInelasticFS.hh
@@ -201,7 +201,6 @@ geant4_add_module(G4had_par_hp
G4NeutronHPFissionERelease.hh
G4NeutronHPFissionFS.hh
G4NeutronHPFissionSpectrum.hh
G4NeutronHPGamma.hh
G4NeutronHPHash.hh
G4NeutronHPHe3InelasticFS.hh
G4NeutronHPInelastic.hh
@@ -261,7 +260,6 @@ geant4_add_module(G4had_par_hp
G4InterpolationManager.cc
G4NRESP71M03.cc
G4ParticleHPIsoData.cc
G4ParticleHPLevel.cc
G4ParticleHP2AInelasticFS.cc
G4ParticleHPList.cc
G4ParticleHP2N2AInelasticFS.cc
@@ -318,7 +316,6 @@ geant4_add_module(G4had_par_hp
G4ParticleHPFissionBaseFS.cc
G4ParticleHPFissionData.cc
G4ParticleHPFissionFS.cc
G4ParticleHPGamma.cc
G4ParticleHPHe3InelasticFS.cc
G4ParticleHPInelastic.cc
G4ParticleHPInelasticBaseFS.cc
@@ -348,6 +345,7 @@ geant4_add_module(G4had_par_hp
G4ParticleHPNT2AInelasticFS.cc
G4ParticleHPNTInelasticFS.cc
G4ParticleHPNXInelasticFS.cc
G4ParticleHPNucLevel.cc
G4ParticleHPPAInelasticFS.cc
G4ParticleHPPDInelasticFS.cc
G4ParticleHPPInelasticFS.cc
@@ -32,117 +32,94 @@
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
#include "G4ParticleHPDeExGammas.hh"
#include "G4RandomDirection.hh"
#include "G4ReactionProduct.hh"
#include "G4SystemOfUnits.hh"
void G4ParticleHPDeExGammas::Init(std::istream & aDataFile)
G4ParticleHPDeExGammas::G4ParticleHPDeExGammas() {}
G4ParticleHPDeExGammas::~G4ParticleHPDeExGammas()
{
// G4cout << this << "ExGammas Init LEVEL " << G4endl; //GDEB
G4ParticleHPGamma ** theGammas = new G4ParticleHPGamma * [50];
G4int nGammas = 0;
G4int nBuff = 50;
for(;;)
{
G4ParticleHPGamma * theNew = new G4ParticleHPGamma;
if(!theNew->Init(aDataFile))
{
delete theNew;
for (auto& ptr : theLevels) {
delete ptr;
}
}
void G4ParticleHPDeExGammas::Init(std::istream& aDataFile)
{
// G4cout << "### G4ParticleHPDeExGammas::Init new file " << G4endl;
// ground state
auto level = new G4ParticleHPNucLevel(0.0);
G4double elevel0 = 0.0;
G4double elevel = 0.0;
G4double egamma = 0.0;
G4double prob = 0.0;
constexpr G4double eps = 1 * CLHEP::eV;
for (;;) {
if (aDataFile >> elevel) {
// next line
aDataFile >> egamma >> prob;
egamma *= CLHEP::keV;
elevel *= CLHEP::keV;
prob = std::max(prob, 1.e-6);
// G4cout << " El0=" << elevel0 << " El=" << elevel
// << " Eg=" << egamma << " w=" << prob << G4endl;
// save previous level and start a new level
if (std::abs(elevel - elevel0) > eps) {
level->Normalize();
theLevels.push_back(level);
++nLevels;
level = new G4ParticleHPNucLevel(elevel);
elevel0 = elevel;
// G4cout << " New level " << nLevels << " E=" << elevel << G4endl;
}
// find the next level
G4double e = elevel - egamma;
G4int next = -1;
G4double del = DBL_MAX;
for (G4int i = 0; i < nLevels; ++i) {
G4double de = std::abs(theLevels[i]->GetLevelEnergy() - e);
if (de < del) {
next = i;
del = de;
}
}
// save level data
if (next >= 0) {
level->AddGamma(egamma, prob, next);
// G4cout << " NLevel=" << nLevels << " Elevel=" << elevel
// << " Egamma=" << egamma << " W=" << prob << " next=" << next << G4endl;
}
}
else {
// end of file - save recent level
level->Normalize();
theLevels.push_back(level);
++nLevels;
// G4cout << "### End of file Nlevels=" << nLevels << G4endl;
break;
}
else
{
if(nGammas==nBuff)
{
nBuff+=50;
G4ParticleHPGamma ** buffer = new G4ParticleHPGamma * [nBuff];
for(G4int i=0;i<nGammas;i++) buffer[i] = theGammas[i];
delete [] theGammas;
theGammas = buffer;
}
theGammas[nGammas] = theNew;
nGammas++;
}
}
// all gammas are in. Now sort them into levels.
// count the levels
G4double currentE = 0;
G4double nextE = 0;
G4int i;
G4double epsilon = 0.01*keV;
for(i=0; i<nGammas; i++)
{
nextE = theGammas[i]->GetLevelEnergy();
if(std::abs(currentE-nextE)>epsilon) nLevels++;
currentE = nextE;
}
// G4cout << this << "LEVEL " << nLevels << G4endl; //GDEB
// Build the levels
theLevels = new G4ParticleHPLevel[nLevels];
levelStart = new G4int [nLevels];
levelSize = new G4int [nLevels];
// fill the levels
currentE = 0;
nextE = 0;
G4int levelCounter=-1;
for(i=0; i<nGammas; i++)
{
nextE = theGammas[i]->GetLevelEnergy();
if(std::abs(currentE-nextE)>epsilon)
{
levelCounter++;
levelStart[levelCounter] = i;
levelSize[levelCounter] = 0;
}
levelSize[levelCounter]++;
currentE = nextE;
}
for(i=0; i<nLevels; i++)
{
theLevels[i].SetNumberOfGammas(levelSize[i]);
for(G4int ii=levelStart[i]; ii<levelStart[i]+levelSize[i]; ii++)
{
theLevels[i].SetGamma(ii-levelStart[i], theGammas[ii]);
}
}
// set the next relation in the gammas.
G4double levelE, gammaE, currentLevelE;
G4double min;
for(i=0; i<nGammas; i++)
{
G4int it=-1;
gammaE = theGammas[i]->GetGammaEnergy();
currentLevelE = theGammas[i]->GetLevelEnergy();
min = currentLevelE-gammaE-epsilon;
for(G4int ii=0; ii<nLevels; ii++)
{
levelE = theLevels[ii].GetLevelEnergy();
if(std::abs(currentLevelE-(levelE+gammaE))<min)
{
min = std::abs(currentLevelE-(levelE+gammaE));
it = ii;
}
}
//080728
if ( it != -1 && currentLevelE == theLevels[it].GetLevelEnergy() )
{
//TK Comment; Some data file in /Inelastic/Gammas has inconsistent level data (no level to transit)
//G4cout << "DeExGammas Transition level error: it " << it << " " << currentLevelE << " " << gammaE << " " << theLevels[it-1].GetLevelEnergy() << " " << currentLevelE - theLevels[it-1].GetLevelEnergy() << G4endl;
// Forced to connect the next(previous) level
it +=-1;
}
//080728
if(it!=-1) theGammas[i]->SetNext(&theLevels[it]);
}
// some garbage collection
delete [] theGammas;
// and we are Done.
}
G4ReactionProductVector* G4ParticleHPDeExGammas::GetDecayGammas(G4int i) const
{
G4int idx = i;
if (idx >= nLevels || idx <= 0) return nullptr;
G4ReactionProductVector* result = new G4ReactionProductVector();
for (;;) {
if (idx <= 0) {
break;
}
auto ptr = theLevels[idx]->GetDecayGamma(idx);
if (nullptr != ptr) {
result->push_back(ptr);
}
}
return result;
}
@@ -1,62 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// neutron_hp -- source file
// J.P. Wellisch, Nov-1996
// A prototype of the low energy neutron transport model.
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
#include "G4ParticleHPGamma.hh"
#include "G4SystemOfUnits.hh"
G4ThreadLocal int G4ParticleHPGamma::instancecount = 0;
G4ParticleHPGamma::G4ParticleHPGamma()
{
next = 0;
instancecount ++;
levelEnergy = 0.0;
gammaEnergy = 0.0;
probability = 0.0;
}
G4ParticleHPGamma::~G4ParticleHPGamma() {instancecount--;}
G4bool G4ParticleHPGamma::Init(std::istream & aDataFile)
{
G4bool theResult = true;
if(aDataFile >> levelEnergy)
{
aDataFile >> gammaEnergy >> probability;
levelEnergy *= keV;
gammaEnergy *= keV;
}
else
{
theResult=false;
}
return theResult;
}
@@ -34,218 +34,230 @@
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
// June-2019 - E. Mendoza --> Added protection against residual with Z<0 or A<Z + adjust_final_state is not applied when data is in MF=6 format (no correlated particle emission) + bug correction (add Q value info to G4ParticleHPNBodyPhaseSpace).
// June-2019 - E. Mendoza --> Added protection against residual with Z<0 or A<Z + adjust_final_state
// is not applied when data is in MF=6 format (no correlated particle emission) + bug correction
// (add Q value info to G4ParticleHPNBodyPhaseSpace).
#include "G4ParticleHPInelasticBaseFS.hh"
#include "G4ParticleHPManager.hh"
#include "G4Nucleus.hh"
#include "G4NucleiProperties.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4Electron.hh"
#include "G4ParticleHPDataUsed.hh"
#include "G4He3.hh"
#include "G4IonTable.hh"
#include "G4NucleiProperties.hh"
#include "G4Nucleus.hh"
#include "G4ParticleHPDataUsed.hh"
#include "G4ParticleHPManager.hh"
void G4ParticleHPInelasticBaseFS::InitGammas(G4double AR, G4double ZR)
{
std::ostringstream ost;
ost <<gammaPath<<"z"<<ZR<<".a"<<AR;
G4String aName = ost.str();
std::ifstream from(aName, std::ios::in);
std::ostringstream ost;
ost << gammaPath << "z" << ZR << ".a" << AR;
G4String aName = ost.str();
std::ifstream from(aName, std::ios::in);
if(!from) return; // no data found for this isotope
std::ifstream theGammaData(aName, std::ios::in);
G4double eps = 0.001;
theNuclearMassDifference =
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(AR+eps),static_cast<G4int>(ZR+eps)) -
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps));
theGammas.Init(theGammaData);
if (!from) return; // no data found for this isotope
std::ifstream theGammaData(aName, std::ios::in);
G4double eps = 0.001;
theNuclearMassDifference =
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(AR + eps), static_cast<G4int>(ZR + eps))
- G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(theBaseA + eps),
static_cast<G4int>(theBaseZ + eps));
theGammas.Init(theGammaData);
}
void G4ParticleHPInelasticBaseFS::Init (G4double A, G4double Z, G4int M, G4String & dirName, G4String & bit, G4ParticleDefinition* )
void G4ParticleHPInelasticBaseFS::Init(G4double A, G4double Z, G4int M, G4String& dirName,
G4String& bit, G4ParticleDefinition*)
{
gammaPath = "/Inelastic/Gammas/";
if(!G4FindDataDir("G4NEUTRONHPDATA"))
throw G4HadronicException(__FILE__, __LINE__, "Please setenv G4NEUTRONHPDATA to point to the neutron cross-section files where Inelastic/Gammas data is found.");
if (!G4FindDataDir("G4NEUTRONHPDATA"))
throw G4HadronicException(__FILE__, __LINE__,
"Please setenv G4NEUTRONHPDATA to point to the neutron cross-section "
"files where Inelastic/Gammas data is found.");
G4String tBase = G4FindDataDir("G4NEUTRONHPDATA");
gammaPath = tBase+gammaPath;
gammaPath = tBase + gammaPath;
G4String tString = dirName;
G4bool dbool;
G4ParticleHPDataUsed aFile = theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M,tString, bit, dbool);
G4ParticleHPDataUsed aFile =
theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M, tString, bit, dbool);
G4String filename = aFile.GetName();
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug") ) G4cout << " G4ParticleHPInelasticBaseFS::Init FILE " << filename << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::Init FILE " << filename << G4endl;
#endif
SetAZMs( A, Z, M, aFile);
SetAZMs(A, Z, M, aFile);
if ( !dbool || ( Z<2.5 && ( std::abs(theNDLDataZ - Z)>0.0001 || std::abs(theNDLDataA - A)>0.0001)) )
if (!dbool
|| (Z < 2.5 && (std::abs(theNDLDataZ - Z) > 0.0001 || std::abs(theNDLDataA - A) > 0.0001)))
{
#ifdef G4PHPDEBUG
if(std::getenv("G4ParticleHPDebug_NamesLogging")) G4cout << "Skipped = "<< filename <<" "<<A<<" "<<Z<<G4endl;
if (std::getenv("G4ParticleHPDebug_NamesLogging"))
G4cout << "Skipped = " << filename << " " << A << " " << Z << G4endl;
#endif
hasAnyData = false;
hasFSData = false;
hasFSData = false;
hasXsec = false;
return;
}
std::istringstream theData(std::ios::in);
G4ParticleHPManager::GetInstance()->GetDataStream(filename,theData);
G4ParticleHPManager::GetInstance()->GetDataStream(filename, theData);
if(!theData) //"!" is a operator of ios
if (!theData) //"!" is a operator of ios
{
hasAnyData = false;
hasFSData = false;
hasFSData = false;
hasXsec = false;
// theData.close();
return; // no data for exactly this isotope and FS
return; // no data for exactly this isotope and FS
}
// here we go
G4int infoType, dataType, dummy=INT_MAX;
hasFSData = false;
while (theData >> infoType) // Loop checking, 11.05.2015, T. Koi
G4int infoType, dataType, dummy = INT_MAX;
hasFSData = false;
while (theData >> infoType) // Loop checking, 11.05.2015, T. Koi
{
theData >> dataType;
if(dummy==INT_MAX) theData >> Qvalue >> dummy;
Qvalue*=CLHEP::eV;
if (dummy == INT_MAX) theData >> Qvalue >> dummy;
Qvalue *= CLHEP::eV;
// In G4NDL4.5 this value is the MT number (<1000),
// in others is que Q-value in eV
if(dataType==3)
{
if (dataType == 3) {
G4int total;
theData >> total;
theXsection->Init(theData, total, CLHEP::eV);
}
else if(dataType==4)
{
else if (dataType == 4) {
theAngularDistribution = new G4ParticleHPAngular;
theAngularDistribution->Init(theData);
hasFSData = true;
hasFSData = true;
}
else if(dataType==5)
{
else if (dataType == 5) {
theEnergyDistribution = new G4ParticleHPEnergyDistribution;
theEnergyDistribution->Init(theData);
hasFSData = true;
hasFSData = true;
}
else if(dataType==6)
{
else if (dataType == 6) {
theEnergyAngData = new G4ParticleHPEnAngCorrelation(theProjectile);
theEnergyAngData->Init(theData);
hasFSData = true;
hasFSData = true;
}
else if(dataType==12)
{
else if (dataType == 12) {
theFinalStatePhotons = new G4ParticleHPPhotonDist;
theFinalStatePhotons->InitMean(theData);
hasFSData = true;
hasFSData = true;
}
else if(dataType==13)
{
else if (dataType == 13) {
theFinalStatePhotons = new G4ParticleHPPhotonDist;
theFinalStatePhotons->InitPartials(theData, theXsection);
hasFSData = true;
hasFSData = true;
}
else if(dataType==14)
{
else if (dataType == 14) {
theFinalStatePhotons->InitAngular(theData);
hasFSData = true;
hasFSData = true;
}
else if(dataType==15)
{
else if (dataType == 15) {
theFinalStatePhotons->InitEnergies(theData);
hasFSData = true;
hasFSData = true;
}
else
{
throw G4HadronicException(__FILE__, __LINE__, "Data-type unknown to G4ParticleHPInelasticBaseFS");
else {
throw G4HadronicException(__FILE__, __LINE__,
"Data-type unknown to G4ParticleHPInelasticBaseFS");
}
}
}
void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile & theTrack,
G4ParticleDefinition ** theDefs,
G4int nDef)
void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile& theTrack,
G4ParticleDefinition** theDefs, G4int nDef)
{
// prepare neutron
if ( theResult.Get() == NULL ) theResult.Put( new G4HadFinalState );
if (theResult.Get() == NULL) theResult.Put(new G4HadFinalState);
theResult.Get()->Clear();
G4double eKinetic = theTrack.GetKineticEnergy();
const G4HadProjectile *hadProjectile = &theTrack;
G4ReactionProduct incidReactionProduct( const_cast<G4ParticleDefinition *>(hadProjectile->GetDefinition()) );
incidReactionProduct.SetMomentum( hadProjectile->Get4Momentum().vect() );
incidReactionProduct.SetKineticEnergy( eKinetic );
const G4HadProjectile* hadProjectile = &theTrack;
G4ReactionProduct incidReactionProduct(
const_cast<G4ParticleDefinition*>(hadProjectile->GetDefinition()));
incidReactionProduct.SetMomentum(hadProjectile->Get4Momentum().vect());
incidReactionProduct.SetKineticEnergy(eKinetic);
// prepare target
G4double targetMass;
G4double eps = 0.0001;
targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) /
//theProjectile->GetPDGMass();
targetMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
static_cast<G4int>(theBaseZ + eps)))
/
// theProjectile->GetPDGMass();
G4Neutron::Neutron()->GetPDGMass();
// give priority to ENDF vales for target mass
if(theEnergyAngData!=0)
{ targetMass = theEnergyAngData->GetTargetMass(); }
if(theAngularDistribution!=0)
{ targetMass = theAngularDistribution->GetTargetMass(); }
if (theEnergyAngData != 0) {
targetMass = theEnergyAngData->GetTargetMass();
}
if (theAngularDistribution != 0) {
targetMass = theAngularDistribution->GetTargetMass();
}
// 110512 TKDB ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly recorded.
if ( targetMass == 0 )
{
//G4cout << "TKDB targetMass = 0; ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly recorded. This could be a similar situation." << G4endl;
//targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) / theProjectile->GetPDGMass();
targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) / G4Neutron::Neutron()->GetPDGMass();
// 110512 TKDB ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly
// recorded.
if (targetMass == 0) {
// G4cout << "TKDB targetMass = 0; ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is
// not properly recorded. This could be a similar situation." << G4endl; targetMass = (
// G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps),
// static_cast<G4int>(theBaseZ+eps))) / theProjectile->GetPDGMass();
targetMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
static_cast<G4int>(theBaseZ + eps)))
/ G4Neutron::Neutron()->GetPDGMass();
}
G4Nucleus aNucleus;
G4ReactionProduct theTarget;
G4ReactionProduct theTarget;
G4ThreeVector neuVelo = (1./G4Neutron::Neutron()->GetPDGMass())*incidReactionProduct.GetMomentum();
theTarget = aNucleus.GetBiasedThermalNucleus( targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
G4ThreeVector neuVelo =
(1. / G4Neutron::Neutron()->GetPDGMass()) * incidReactionProduct.GetMomentum();
theTarget =
aNucleus.GetBiasedThermalNucleus(targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
theTarget.SetDefinition( G4IonTable::GetIonTable()->GetIon( G4int(theBaseZ), G4int(theBaseA) , 0.0 ) );
theTarget.SetDefinition(G4IonTable::GetIonTable()->GetIon(G4int(theBaseZ), G4int(theBaseA), 0.0));
// prepare energy in target rest frame
G4ReactionProduct boosted;
boosted.Lorentz(incidReactionProduct, theTarget);
eKinetic = boosted.GetKineticEnergy();
G4double orgMomentum = boosted.GetMomentum().mag();
// Take N-body phase-space distribution, if no other data present.
if(!HasFSData()) // adding the residual is trivial here @@@
if (!HasFSData()) // adding the residual is trivial here @@@
{
G4ParticleHPNBodyPhaseSpace thePhaseSpaceDistribution;
G4double aPhaseMass=0;
G4double aPhaseMass = 0;
G4int ii;
for(ii=0; ii<nDef; ++ii)
{
aPhaseMass+=theDefs[ii]->GetPDGMass();
for (ii = 0; ii < nDef; ++ii) {
aPhaseMass += theDefs[ii]->GetPDGMass();
}
//----------------------------------------------------------------------------
if(Qvalue<1.*CLHEP::keV && Qvalue>-1.*CLHEP::keV) {
if (Qvalue < 1. * CLHEP::keV && Qvalue > -1. * CLHEP::keV) {
// Not in the G4NDL lib or not calculated yet:
// Calculate residual:
G4int ResidualA=theBaseA;
G4int ResidualZ=theBaseZ;
G4int ResidualA = theBaseA;
G4int ResidualZ = theBaseZ;
for (ii = 0; ii < nDef; ++ii) {
ResidualZ -= theDefs[ii]->GetAtomicNumber();
ResidualA -= theDefs[ii]->GetBaryonNumber();
}
if (ResidualA > 0 && ResidualZ > 0) {
G4ParticleDefinition* resid = G4IonTable::GetIonTable()->GetIon(ResidualZ,ResidualA);
Qvalue = incidReactionProduct.GetMass()+theTarget.GetMass()-aPhaseMass-resid->GetPDGMass();
G4ParticleDefinition* resid = G4IonTable::GetIonTable()->GetIon(ResidualZ, ResidualA);
Qvalue =
incidReactionProduct.GetMass() + theTarget.GetMass() - aPhaseMass - resid->GetPDGMass();
}
if (Qvalue > 400*CLHEP::MeV || Qvalue < -400*CLHEP::MeV) {
//Then Q value is probably too large ...
Qvalue = 1.1*CLHEP::keV;
if (Qvalue > 400 * CLHEP::MeV || Qvalue < -400 * CLHEP::MeV) {
// Then Q value is probably too large ...
Qvalue = 1.1 * CLHEP::keV;
}
}
//----------------------------------------------------------------------------
@@ -255,372 +267,341 @@ void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile & theTrack,
thePhaseSpaceDistribution.SetTarget(&theTarget);
thePhaseSpaceDistribution.SetQValue(Qvalue);
for(ii=0; ii<nDef; ++ii)
{
G4double massCode = 1000.*std::abs(theDefs[ii]->GetPDGCharge());
massCode += theDefs[ii]->GetBaryonNumber();
for (ii = 0; ii < nDef; ++ii) {
G4double massCode = 1000. * std::abs(theDefs[ii]->GetPDGCharge());
massCode += theDefs[ii]->GetBaryonNumber();
G4double dummy = 0;
G4ReactionProduct * aSec = thePhaseSpaceDistribution.Sample(eKinetic, massCode, dummy);
aSec->Lorentz(*aSec, -1.*theTarget);
G4DynamicParticle * aPart = new G4DynamicParticle();
G4ReactionProduct* aSec = thePhaseSpaceDistribution.Sample(eKinetic, massCode, dummy);
aSec->Lorentz(*aSec, -1. * theTarget);
G4DynamicParticle* aPart = new G4DynamicParticle();
aPart->SetDefinition(aSec->GetDefinition());
aPart->SetMomentum(aSec->GetMomentum());
delete aSec;
theResult.Get()->AddSecondary(aPart, secID);
theResult.Get()->AddSecondary(aPart, secID);
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug"))
G4cout << this
<< " G4ParticleHPInelasticBaseFS::BaseApply NoFSData add secondary "
<< aPart->GetParticleDefinition()->GetParticleName()
<< " E= " << aPart->GetKineticEnergy() << " NSECO "
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply NoFSData add secondary "
<< aPart->GetParticleDefinition()->GetParticleName()
<< " E= " << aPart->GetKineticEnergy() << " NSECO "
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
#endif
}
}
theResult.Get()->SetStatusChange(stopAndKill);
// Final momentum check should be done before return
G4ParticleDefinition* targ_pd = G4IonTable::GetIonTable()->GetIon ( (G4int)theBaseZ , (G4int)theBaseA , 0.0 );
G4LorentzVector targ_4p_lab ( theTarget.GetMomentum() , std::sqrt( targ_pd->GetPDGMass()*targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2() ) );
G4ParticleDefinition* targ_pd =
G4IonTable::GetIonTable()->GetIon((G4int)theBaseZ, (G4int)theBaseA, 0.0);
G4LorentzVector targ_4p_lab(
theTarget.GetMomentum(),
std::sqrt(targ_pd->GetPDGMass() * targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2()));
G4LorentzVector proj_4p_lab = theTrack.Get4Momentum();
G4LorentzVector init_4p_lab = proj_4p_lab + targ_4p_lab;
adjust_final_state ( init_4p_lab );
adjust_final_state(init_4p_lab);
return;
}
// set target and neutron in the relevant exit channel
if(theAngularDistribution!=0)
{
if (theAngularDistribution != 0) {
theAngularDistribution->SetTarget(theTarget);
theAngularDistribution->SetProjectileRP(incidReactionProduct);
}
else if(theEnergyAngData!=0)
{
else if (theEnergyAngData != 0) {
theEnergyAngData->SetTarget(theTarget);
theEnergyAngData->SetProjectileRP(incidReactionProduct);
}
G4ReactionProductVector * tmpHadrons = 0;
G4ReactionProductVector* tmpHadrons = 0;
#ifdef G4PHPDEBUG
//To avoid compilation error around line 532.
// To avoid compilation error around line 532.
G4int ii(0);
#endif
G4int dummy;
std::size_t i;
if(theEnergyAngData != 0)
{
if (theEnergyAngData != 0) {
tmpHadrons = theEnergyAngData->Sample(eKinetic);
if ( ! G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState() ) {
// Adjust A and Z in the case of miss much between selected data and target nucleus
if ( tmpHadrons != nullptr ) {
G4int sumA = 0;
G4int sumZ = 0;
G4int maxA = 0;
G4int jAtMaxA = 0;
for ( G4int j = 0 ; j != (G4int)tmpHadrons->size() ; ++j ) {
//G4cout << __FILE__ << " " << __LINE__ << "th line: tmpHadrons->at(j)->GetDefinition()->GetParticleName() = " << tmpHadrons->at(j)->GetDefinition()->GetParticleName() << G4endl;
if ( tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber() > maxA ) {
maxA = tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
jAtMaxA = j;
}
sumA += tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
sumZ += G4int( tmpHadrons->at(j)->GetDefinition()->GetPDGCharge() + eps );
}
G4int dA = (G4int)theBaseA + hadProjectile->GetDefinition()->GetBaryonNumber() - sumA;
G4int dZ = (G4int)theBaseZ + G4int( hadProjectile->GetDefinition()->GetPDGCharge() + eps ) - sumZ;
if ( dA < 0 || dZ < 0 ) {
G4int newA = tmpHadrons->at(jAtMaxA)->GetDefinition()->GetBaryonNumber() + dA ;
G4int newZ = G4int( tmpHadrons->at(jAtMaxA)->GetDefinition()->GetPDGCharge() + eps ) + dZ;
if(newA>newZ && newZ>0){
G4ParticleDefinition* pd = G4IonTable::GetIonTable()->GetIon ( newZ , newA );
tmpHadrons->at( jAtMaxA )->SetDefinition( pd );
}
}
if (!G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState()) {
// Adjust A and Z in the case of miss much between selected data and target nucleus
if (tmpHadrons != nullptr) {
G4int sumA = 0;
G4int sumZ = 0;
G4int maxA = 0;
G4int jAtMaxA = 0;
for (G4int j = 0; j != (G4int)tmpHadrons->size(); ++j) {
// G4cout << __FILE__ << " " << __LINE__ << "th line:
// tmpHadrons->at(j)->GetDefinition()->GetParticleName() = " <<
// tmpHadrons->at(j)->GetDefinition()->GetParticleName() << G4endl;
if (tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber() > maxA) {
maxA = tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
jAtMaxA = j;
}
sumA += tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
sumZ += G4int(tmpHadrons->at(j)->GetDefinition()->GetPDGCharge() + eps);
}
G4int dA = (G4int)theBaseA + hadProjectile->GetDefinition()->GetBaryonNumber() - sumA;
G4int dZ =
(G4int)theBaseZ + G4int(hadProjectile->GetDefinition()->GetPDGCharge() + eps) - sumZ;
if (dA < 0 || dZ < 0) {
G4int newA = tmpHadrons->at(jAtMaxA)->GetDefinition()->GetBaryonNumber() + dA;
G4int newZ = G4int(tmpHadrons->at(jAtMaxA)->GetDefinition()->GetPDGCharge() + eps) + dZ;
if (newA > newZ && newZ > 0) {
G4ParticleDefinition* pd = G4IonTable::GetIonTable()->GetIon(newZ, newA);
tmpHadrons->at(jAtMaxA)->SetDefinition(pd);
}
}
}
}
}
else if(theAngularDistribution!= 0)
{
G4bool * Done = new G4bool[nDef];
else if (theAngularDistribution != 0) {
G4bool* Done = new G4bool[nDef];
G4int i0;
for(i0=0; i0<nDef; ++i0) Done[i0] = false;
for (i0 = 0; i0 < nDef; ++i0)
Done[i0] = false;
tmpHadrons = new G4ReactionProductVector;
G4ReactionProduct * aHadron;
G4double localMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps)));
G4ThreeVector bufferedDirection(0,0,0);
for(i0=0; i0<nDef; ++i0)
{
if(!Done[i0])
{
G4ReactionProduct* aHadron;
G4double localMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
static_cast<G4int>(theBaseZ + eps)));
G4ThreeVector bufferedDirection(0, 0, 0);
for (i0 = 0; i0 < nDef; ++i0) {
if (!Done[i0]) {
aHadron = new G4ReactionProduct;
if(theEnergyDistribution!=0)
{
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(theEnergyDistribution->Sample(eKinetic, dummy));
}
else if(nDef == 1)
{
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(eKinetic);
}
else if(nDef == 2)
{
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(50*CLHEP::MeV);
}
else
{
throw G4HadronicException(__FILE__, __LINE__, "No energy distribution to sample from in InelasticBaseFS::BaseApply");
}
theAngularDistribution->SampleAndUpdate(*aHadron);
if(theEnergyDistribution==0 && nDef == 2)
{
if(i0==0)
{
G4double mass1 = theDefs[0]->GetPDGMass();
G4double mass2 = theDefs[1]->GetPDGMass();
G4double massn = theProjectile->GetPDGMass();
G4int z1 = static_cast<G4int>(theBaseZ+eps-theDefs[0]->GetPDGCharge()-theDefs[1]->GetPDGCharge());
G4int a1 = static_cast<G4int>(theBaseA+eps)-theDefs[0]->GetBaryonNumber()-theDefs[1]->GetBaryonNumber();
G4double concreteMass = G4NucleiProperties::GetNuclearMass(a1, z1);
G4double availableEnergy = eKinetic+massn+localMass-mass1-mass2-concreteMass;
// available kinetic energy in CMS (non relativistic)
G4double emin = availableEnergy+mass1+mass2 - std::sqrt((mass1+mass2)*(mass1+mass2)+orgMomentum*orgMomentum);
G4double p1=std::sqrt(2.*mass2*emin);
bufferedDirection = p1*aHadron->GetMomentum().unit();
if (theEnergyDistribution != 0) {
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(theEnergyDistribution->Sample(eKinetic, dummy));
}
else if (nDef == 1) {
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(eKinetic);
}
else if (nDef == 2) {
aHadron->SetDefinition(theDefs[i0]);
aHadron->SetKineticEnergy(50 * CLHEP::MeV);
}
else {
throw G4HadronicException(
__FILE__, __LINE__,
"No energy distribution to sample from in InelasticBaseFS::BaseApply");
}
theAngularDistribution->SampleAndUpdate(*aHadron);
if (theEnergyDistribution == 0 && nDef == 2) {
if (i0 == 0) {
G4double mass1 = theDefs[0]->GetPDGMass();
G4double mass2 = theDefs[1]->GetPDGMass();
G4double massn = theProjectile->GetPDGMass();
G4int z1 = static_cast<G4int>(theBaseZ + eps - theDefs[0]->GetPDGCharge()
- theDefs[1]->GetPDGCharge());
G4int a1 = static_cast<G4int>(theBaseA + eps) - theDefs[0]->GetBaryonNumber()
- theDefs[1]->GetBaryonNumber();
G4double concreteMass = G4NucleiProperties::GetNuclearMass(a1, z1);
G4double availableEnergy = eKinetic + massn + localMass - mass1 - mass2 - concreteMass;
// available kinetic energy in CMS (non relativistic)
G4double emin =
availableEnergy + mass1 + mass2
- std::sqrt((mass1 + mass2) * (mass1 + mass2) + orgMomentum * orgMomentum);
G4double p1 = std::sqrt(2. * mass2 * emin);
bufferedDirection = p1 * aHadron->GetMomentum().unit();
#ifdef G4PHPDEBUG
if(std::getenv("G4ParticleHPDebug")) // @@@@@ verify the nucleon counting...
{
G4cout << "G4ParticleHPInelasticBaseFS "<<z1<<" "<<theBaseZ<<" "<<a1<<" "<<theBaseA<<" "<<availableEnergy<<" "
<< emin<<G4endl;
if (std::getenv("G4ParticleHPDebug")) // @@@@@ verify the nucleon counting...
{
G4cout << "G4ParticleHPInelasticBaseFS " << z1 << " " << theBaseZ << " " << a1 << " "
<< theBaseA << " " << availableEnergy << " " << emin << G4endl;
}
#endif
}
else
{
bufferedDirection = -bufferedDirection;
}
// boost from cms to lab
}
else {
bufferedDirection = -bufferedDirection;
}
// boost from cms to lab
#ifdef G4PHPDEBUG
if(std::getenv("G4ParticleHPDebug"))
{
G4cout << " G4ParticleHPInelasticBaseFS "<<bufferedDirection.mag2()<<G4endl;
}
if (std::getenv("G4ParticleHPDebug")) {
G4cout << " G4ParticleHPInelasticBaseFS " << bufferedDirection.mag2() << G4endl;
}
#endif
aHadron->SetTotalEnergy( std::sqrt(aHadron->GetMass()*aHadron->GetMass()
+bufferedDirection.mag2()) );
aHadron->SetMomentum(bufferedDirection);
aHadron->Lorentz(*aHadron, -1.*(theTarget+incidReactionProduct));
#ifdef G4PHPDEBUG
if(std::getenv("G4ParticleHPDebug"))
{
G4cout << " G4ParticleHPInelasticBaseFS "<<aHadron->GetTotalEnergy()<<" "<<aHadron->GetMomentum()<<G4endl;
}
#endif
}
tmpHadrons->push_back(aHadron);
aHadron->SetTotalEnergy(
std::sqrt(aHadron->GetMass() * aHadron->GetMass() + bufferedDirection.mag2()));
aHadron->SetMomentum(bufferedDirection);
aHadron->Lorentz(*aHadron, -1. * (theTarget + incidReactionProduct));
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply FSData add secondary " << aHadron->GetDefinition()->GetParticleName() << " E= " << aHadron->GetKineticEnergy() << G4endl;
if (std::getenv("G4ParticleHPDebug")) {
G4cout << " G4ParticleHPInelasticBaseFS " << aHadron->GetTotalEnergy() << " "
<< aHadron->GetMomentum() << G4endl;
}
#endif
}
tmpHadrons->push_back(aHadron);
#ifdef G4PHPDEBUG
if (std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply FSData add secondary "
<< aHadron->GetDefinition()->GetParticleName()
<< " E= " << aHadron->GetKineticEnergy() << G4endl;
#endif
}
}
delete [] Done;
delete[] Done;
}
else
{
else {
throw G4HadronicException(__FILE__, __LINE__, "No data to create the neutrons in NInelasticFS");
}
G4ReactionProductVector * thePhotons = nullptr;
if(theFinalStatePhotons!=0)
{
G4ReactionProductVector* thePhotons = nullptr;
if (theFinalStatePhotons != 0) {
// the photon distributions are in the Nucleus rest frame.
G4ReactionProduct boosted_tmp;
boosted_tmp.Lorentz(incidReactionProduct, theTarget);
G4double anEnergy = boosted_tmp.GetKineticEnergy();
thePhotons = theFinalStatePhotons->GetPhotons(anEnergy);
if(thePhotons!=0)
{
for(i=0; i<thePhotons->size(); ++i)
{
if (thePhotons != 0) {
for (i = 0; i < thePhotons->size(); ++i) {
// back to lab
thePhotons->operator[](i)->Lorentz(*(thePhotons->operator[](i)), -1.*theTarget);
thePhotons->operator[](i)->Lorentz(*(thePhotons->operator[](i)), -1. * theTarget);
}
}
}
else if(theEnergyAngData!=0)
{
else if (theEnergyAngData != 0) {
// PA130927: do not create photons to adjust binding energy
G4bool bAdjustPhotons = true;
#ifdef PHP_AS_HP
bAdjustPhotons = true;
#ifdef PHP_AS_HP
bAdjustPhotons = true;
#else
if ( G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState() )
bAdjustPhotons = false;
if (G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState()) bAdjustPhotons = false;
#endif
if( bAdjustPhotons ) {
if (bAdjustPhotons) {
G4double theGammaEnergy = theEnergyAngData->GetTotalMeanEnergy();
G4double anEnergy = boosted.GetKineticEnergy();
theGammaEnergy = anEnergy-theGammaEnergy;
theGammaEnergy = anEnergy - theGammaEnergy;
theGammaEnergy += theNuclearMassDifference;
G4double eBindProducts = 0;
G4double eBindN = 0;
G4double eBindP = 0;
G4double eBindD = G4NucleiProperties::GetBindingEnergy(2,1);
G4double eBindT = G4NucleiProperties::GetBindingEnergy(3,1);
G4double eBindHe3 = G4NucleiProperties::GetBindingEnergy(3,2);
G4double eBindA = G4NucleiProperties::GetBindingEnergy(4,2);
G4int ia=0;
for(i=0; i<tmpHadrons->size(); i++)
{
if(tmpHadrons->operator[](i)->GetDefinition() == G4Neutron::Neutron())
{
eBindProducts+=eBindN;
}
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Proton::Proton())
{
eBindProducts+=eBindP;
}
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Deuteron::Deuteron())
{
eBindProducts+=eBindD;
}
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Triton::Triton())
{
eBindProducts+=eBindT;
}
else if(tmpHadrons->operator[](i)->GetDefinition() == G4He3::He3())
{
eBindProducts+=eBindHe3;
}
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Alpha::Alpha())
{
eBindProducts+=eBindA;
ia++;
}
}
G4double eBindD = G4NucleiProperties::GetBindingEnergy(2, 1);
G4double eBindT = G4NucleiProperties::GetBindingEnergy(3, 1);
G4double eBindHe3 = G4NucleiProperties::GetBindingEnergy(3, 2);
G4double eBindA = G4NucleiProperties::GetBindingEnergy(4, 2);
G4int ia = 0;
for (i = 0; i < tmpHadrons->size(); i++) {
if (tmpHadrons->operator[](i)->GetDefinition() == G4Neutron::Neutron()) {
eBindProducts += eBindN;
}
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Proton::Proton()) {
eBindProducts += eBindP;
}
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Deuteron::Deuteron()) {
eBindProducts += eBindD;
}
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Triton::Triton()) {
eBindProducts += eBindT;
}
else if (tmpHadrons->operator[](i)->GetDefinition() == G4He3::He3()) {
eBindProducts += eBindHe3;
}
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Alpha::Alpha()) {
eBindProducts += eBindA;
ia++;
}
}
theGammaEnergy += eBindProducts;
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply gamma Energy " << theGammaEnergy << " eBindProducts " << eBindProducts << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply gamma Energy " << theGammaEnergy
<< " eBindProducts " << eBindProducts << G4endl;
#endif
// Special treatment for Be9 + n -> 2n + Be8 -> 2n + a + a
if ( (G4int)(theBaseZ+eps) == 4 && (G4int)(theBaseA+eps) == 9 )
{
// This only valid for G4NDL3.13,,,
if ( std::abs( theNuclearMassDifference -
( G4NucleiProperties::GetBindingEnergy( 8 , 4 ) -
G4NucleiProperties::GetBindingEnergy( 9 , 4 ) ) ) < 1*CLHEP::keV
&& ia == 2 )
{
theGammaEnergy -= (2*eBindA);
}
}
G4ReactionProductVector * theOtherPhotons = nullptr;
G4int iLevel;
while(theGammaEnergy>=theGammas.GetLevelEnergy(0)) // Loop checking, 11.05.2015, T. Koi
{
for(iLevel=theGammas.GetNumberOfLevels()-1; iLevel>=0; --iLevel)
{
if(theGammas.GetLevelEnergy(iLevel)<theGammaEnergy) break;
}
if(iLevel==0||iLevel==theGammas.GetNumberOfLevels()-1)
{
theOtherPhotons = theGammas.GetDecayGammas(iLevel);
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply adding gamma from level "
<< iLevel << " "
<< theOtherPhotons->operator[](ii)->GetKineticEnergy(
) << G4endl;
#endif
}
else
{
G4double random = G4UniformRand();
G4double eLow = theGammas.GetLevelEnergy(iLevel);
G4double eHigh = theGammas.GetLevelEnergy(iLevel+1);
if(random > (eHigh-eLow)/(theGammaEnergy-eLow)) iLevel++;
theOtherPhotons = theGammas.GetDecayGammas(iLevel);
}
if(thePhotons==0) thePhotons = new G4ReactionProductVector;
if(theOtherPhotons != 0)
{
for(std::size_t iii=0; iii<theOtherPhotons->size(); ++iii)
{
thePhotons->push_back(theOtherPhotons->operator[](iii));
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug"))
G4cout << iii << " G4ParticleHPInelasticBaseFS::BaseApply adding gamma " << theOtherPhotons->operator[](iii)->GetKineticEnergy() << G4endl;
#endif
}
delete theOtherPhotons;
}
theGammaEnergy -= theGammas.GetLevelEnergy(iLevel);
if(iLevel == -1) break;
}
if ((G4int)(theBaseZ + eps) == 4 && (G4int)(theBaseA + eps) == 9) {
// This only valid for G4NDL3.13,,,
if (std::abs(theNuclearMassDifference
- (G4NucleiProperties::GetBindingEnergy(8, 4)
- G4NucleiProperties::GetBindingEnergy(9, 4)))
< 1 * CLHEP::keV
&& ia == 2)
{
theGammaEnergy -= (2 * eBindA);
}
}
if (theGammaEnergy > 0.0) {
for (G4int iLevel = theGammas.GetNumberOfLevels() - 1; iLevel > 0; --iLevel) {
G4double e = theGammas.GetLevelEnergy(iLevel);
if (e < theGammaEnergy) {
thePhotons = theGammas.GetDecayGammas(iLevel);
theGammaEnergy -= e;
break;
}
}
}
}
}
// fill the result
std::size_t nSecondaries = tmpHadrons->size();
std::size_t nPhotons = 0;
if(thePhotons!=0) { nPhotons = thePhotons->size(); }
if (thePhotons != 0) {
nPhotons = thePhotons->size();
}
nSecondaries += nPhotons;
G4DynamicParticle * theSec;
G4DynamicParticle* theSec;
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N hadrons "
<< nSecondaries-nPhotons << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N hadrons " << nSecondaries - nPhotons
<< G4endl;
#endif
for(i=0; i<nSecondaries-nPhotons; ++i)
{
theSec = new G4DynamicParticle;
theSec->SetDefinition(tmpHadrons->operator[](i)->GetDefinition());
theSec->SetMomentum(tmpHadrons->operator[](i)->GetMomentum());
theResult.Get()->AddSecondary(theSec, secID);
for (i = 0; i < nSecondaries - nPhotons; ++i) {
theSec = new G4DynamicParticle;
theSec->SetDefinition(tmpHadrons->operator[](i)->GetDefinition());
theSec->SetMomentum(tmpHadrons->operator[](i)->GetMomentum());
theResult.Get()->AddSecondary(theSec, secID);
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug")) G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary2 " << theSec->GetParticleDefinition()->GetParticleName() << " E= " << theSec->GetKineticEnergy() << " NSECO " << theResult.Get()->GetNumberOfSecondaries() << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary2 "
<< theSec->GetParticleDefinition()->GetParticleName()
<< " E= " << theSec->GetKineticEnergy() << " NSECO "
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
#endif
delete tmpHadrons->operator[](i);
}
delete tmpHadrons->operator[](i);
}
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N photons " << nPhotons << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N photons " << nPhotons << G4endl;
#endif
if(thePhotons != 0)
{
for(i=0; i<nPhotons; ++i)
{
theSec = new G4DynamicParticle;
if (thePhotons != 0) {
for (i = 0; i < nPhotons; ++i) {
theSec = new G4DynamicParticle;
theSec->SetDefinition(thePhotons->operator[](i)->GetDefinition());
theSec->SetMomentum(thePhotons->operator[](i)->GetMomentum());
theResult.Get()->AddSecondary(theSec, secID);
theResult.Get()->AddSecondary(theSec, secID);
#ifdef G4PHPDEBUG
if( std::getenv("G4ParticleHPDebug")) G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary3 " << theSec->GetParticleDefinition()->GetParticleName() << " E= " << theSec->GetKineticEnergy() << " NSECO " << theResult.Get()->GetNumberOfSecondaries() << G4endl;
if (std::getenv("G4ParticleHPDebug"))
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary3 "
<< theSec->GetParticleDefinition()->GetParticleName()
<< " E= " << theSec->GetKineticEnergy() << " NSECO "
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
#endif
delete thePhotons->operator[](i);
}
}
// some garbage collection
delete thePhotons;
delete tmpHadrons;
G4ParticleDefinition* targ_pd = G4IonTable::GetIonTable()->GetIon ( (G4int)theBaseZ , (G4int)theBaseA , 0.0 );
G4LorentzVector targ_4p_lab ( theTarget.GetMomentum() , std::sqrt( targ_pd->GetPDGMass()*targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2() ) );
G4ParticleDefinition* targ_pd =
G4IonTable::GetIonTable()->GetIon((G4int)theBaseZ, (G4int)theBaseA, 0.0);
G4LorentzVector targ_4p_lab(
theTarget.GetMomentum(),
std::sqrt(targ_pd->GetPDGMass() * targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2()));
G4LorentzVector proj_4p_lab = theTrack.Get4Momentum();
G4LorentzVector init_4p_lab = proj_4p_lab + targ_4p_lab;
//if data in MF=6 format (no correlated particle emission), then adjust_final_state can give severe errors:
if(theEnergyAngData==0){adjust_final_state ( init_4p_lab );}
// if data in MF=6 format (no correlated particle emission), then adjust_final_state can give
// severe errors:
if (theEnergyAngData == 0) {
adjust_final_state(init_4p_lab);
}
// clean up the primary neutron
theResult.Get()->SetStatusChange(stopAndKill);
File diff suppressed because it is too large Load Diff
@@ -1,89 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// neutron_hp -- source file
// J.P. Wellisch, Nov-1996
// A prototype of the low energy neutron transport model.
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
#include "G4ParticleHPLevel.hh"
#include "G4ParticleHPGamma.hh"
G4ParticleHPLevel::~G4ParticleHPLevel()
{
if(theGammas != 0)
{
for(G4int i=0; i<nGammas; i++) delete theGammas[i];
}
delete [] theGammas;
}
void G4ParticleHPLevel::SetNumberOfGammas(G4int aGammas)
{
nGammas = aGammas;
if(theGammas != 0)
{
for(G4int i=0; i<nGammas; i++) delete theGammas[i];
}
delete [] theGammas;
theGammas = new G4ParticleHPGamma * [nGammas];
}
void G4ParticleHPLevel::SetGamma(G4int i, G4ParticleHPGamma * aGamma)
{
theGammas[i] = aGamma;
SetLevelEnergy(aGamma->GetLevelEnergy());
}
G4double G4ParticleHPLevel::GetGammaEnergy(G4int i)
{
return theGammas[i]->GetGammaEnergy();
}
G4DynamicParticleVector * G4ParticleHPLevel::GetDecayGammas()
{
G4DynamicParticleVector * theResult;
G4double sum = 0;
G4double * running = new G4double[nGammas];
running[0] = 0;
G4int i;
for(i=0; i<nGammas; i++)
{
if(i!=0) running[i]=running[i-1];
running[i]+=theGammas[i]->GetWeight();
}
sum = running[nGammas-1];
G4int it(0);
G4double random = G4UniformRand();
for(i=0; i<nGammas; i++)
{
it = i;
if(random*sum < running[i]) break;
}
delete [] running;
theResult = theGammas[it]->GetDecayGammas();
return theResult;
}
@@ -23,75 +23,70 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// V. Ivanchenko, 21 April 2023 Data structure class for gamma levels
//
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
//
#ifndef G4ParticleHPGamma_h
#define G4ParticleHPGamma_h 1
#include "globals.hh"
#include "G4ios.hh"
#include <fstream>
#include "G4DynamicParticleVector.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleHPNucLevel.hh"
#include "G4Gamma.hh"
#include "G4ParticleHPLevel.hh"
#include "G4RandomDirection.hh"
#include "Randomize.hh"
class G4ParticleHPGamma
G4ParticleHPNucLevel::G4ParticleHPNucLevel(G4double e) : levelEnergy(e) {}
void G4ParticleHPNucLevel::AddGamma(G4double e, G4double w, G4int idx)
{
public:
G4ParticleHPGamma();
~G4ParticleHPGamma();
G4bool Init(std::istream & aDataFile);
inline void SetNext(G4ParticleHPLevel * aLevel)
{
next = aLevel;
gammaData x;
x.gammaEnergy = e;
x.cumProbability = w;
x.next = idx;
gammas.push_back(x);
++nGammas;
}
void G4ParticleHPNucLevel::Normalize()
{
if (gammas.empty()) {
return;
}
G4DynamicParticleVector * GetDecayGammas()
{
G4DynamicParticleVector * theResult;
if(next == 0)
{
theResult = new G4DynamicParticleVector;
G4double sum = 0.0;
for (auto& gam : gammas) {
sum += gam.cumProbability;
}
if (sum <= 0.0) {
return;
}
G4double norm = 1.0 / sum;
sum = 0;
for (auto& gam : gammas) {
sum += norm * gam.cumProbability;
gam.cumProbability = sum;
}
gammas[nGammas - 1].cumProbability = 1.0;
}
G4ReactionProduct* G4ParticleHPNucLevel::GetDecayGamma(G4int& idx) const
{
if (gammas.empty()) {
return nullptr;
}
G4double q = G4UniformRand();
G4double e = 0.0;
for (auto& gam : gammas) {
if (q <= gam.cumProbability) {
e = gam.gammaEnergy;
idx = gam.next;
break;
}
else
{
theResult = next->GetDecayGammas();
}
G4DynamicParticle * theNew = new G4DynamicParticle;
theNew->SetDefinition(G4Gamma::Gamma());
theNew->SetKineticEnergy(gammaEnergy);
theResult->push_back(theNew);
return theResult;
}
inline G4double GetLevelEnergy()
{
return levelEnergy;
if (e <= 0.0) {
return nullptr;
}
inline G4double GetGammaEnergy()
{
return gammaEnergy;
}
inline G4double GetWeight()
{
return probability;
}
private:
G4double levelEnergy;
G4double gammaEnergy;
G4double probability;
G4ParticleHPLevel * next;
static G4ThreadLocal int instancecount;
};
#endif
G4ThreeVector p = G4RandomDirection();
p *= e;
auto res = new G4ReactionProduct(G4Gamma::Gamma());
res->SetMomentum(p);
res->SetKineticEnergy(e);
return res;
}
+6
View File
@@ -7,6 +7,12 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-05-25 Alberto Ribon (hadr-util-V11-00-14)
- G4Fragment : replaced (fatal) G4HadronicException with G4Exception.
Note: in the method CalculateMassAndExcitationEnergy(), the exception type
is "EventMustBeAborted" to avoid rare crashes seen in INCLXX, which
are difficult to reproduce and fix.
## 2022-11-26 Gabriele Cosmo (hadr-util-V11-00-13)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -40,7 +40,7 @@
#include "G4Fragment.hh"
#include "G4SystemOfUnits.hh"
#include "G4HadronicException.hh"
#include "G4Exception.hh"
#include "G4ios.hh"
#include <iomanip>
@@ -167,9 +167,10 @@ G4Fragment::G4Fragment(const G4LorentzVector& aMomentum,
{
if(aParticleDefinition->GetPDGEncoding() != 22 &&
aParticleDefinition->GetPDGEncoding() != 11) {
G4String text = "G4Fragment::G4Fragment constructor for gamma used for "
+ aParticleDefinition->GetParticleName();
throw G4HadronicException(__FILE__, __LINE__, text);
G4ExceptionDescription ed;
ed << "Particle: " << aParticleDefinition->GetParticleName() << G4endl;
G4Exception( "G4Fragment::G4Fragment: constructor for gamma used for another type of particle ! ",
"HAD_FRAGMENT_01", FatalException, ed );
}
theGroundStateMass = aParticleDefinition->GetPDGMass();
}
@@ -178,11 +179,10 @@ void G4Fragment::CalculateMassAndExcitationEnergy()
{
// check input
if(theZ > theA || theZ + theL > theA) {
G4String text = "G4Fragment::CalculateMassAndExcitationEnergy: inconsistent number of nucleons is ignored";
G4cout << text << G4endl;
G4cout << " Z=" << theZ << " A=" << theA
<< " nLambdas=" << theL << G4endl;
throw G4HadronicException(__FILE__, __LINE__, text);
G4ExceptionDescription ed;
ed << "Fragment: Z=" << theZ << " A=" << theA << " nLambdas=" << theL << G4endl;
G4Exception( "G4Fragment::CalculateMassAndExcitationEnergy: inconsistent number of nucleons ! ",
"HAD_FRAGMENT_02", EventMustBeAborted, ed );
}
// compute mass
theGroundStateMass = ( theL == 0 )
@@ -315,11 +315,10 @@ void G4Fragment::ExcitationEnergyWarning()
void G4Fragment::NumberOfExitationWarning(const G4String& value)
{
G4cout << "G4Fragment::"<< value << " ERROR "
<< G4endl;
G4cout << this << G4endl;
G4String text = "G4Fragment::G4Fragment wrong exciton number ";
throw G4HadronicException(__FILE__, __LINE__, text);
G4ExceptionDescription ed;
ed << "Value=" << value << G4endl;
G4Exception( "G4Fragment::NumberOfExitationWarning : wrong exciton number ! ",
"HAD_FRAGMENT_03", FatalException, ed );
}
void G4Fragment::SetAngularMomentum(const G4ThreeVector& v)