Import Geant4 11.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2025-12-05 08:54:02 +01:00
parent a499fb82e9
commit b4a16de652
6484 changed files with 232674 additions and 221097 deletions
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-11-06 Gabriele Cosmo (hadr-inclxx-V11-03-03)
- Fixed compilation warning for implicit type conversion on macOS/XCode
in G4INCLAntinucleiAtrestEntryChannel::getAnnihilationPosition().
## 2025-10-01 Jean-Christophe David (hadr-inclxx-V11-03-02)
- Extension of the INCLXX model to handle antineutron (at rest and in-flight).
- Fix the use of INCL for the reactions antineutron + H1/H2 and decay omega/eta
- Forbid the use of SRC
- back to no hyperremnant.
## 2025-05-16 Ben Morgan (hadr-inclxx-V11-03-01)
- Replace the URL root.cern.ch with canonical root.cern
- Fixes [GitHub PR 87](https://github.com/Geant4/geant4/pull/87)
@@ -0,0 +1,75 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4INCLParticle.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLAllocationPool.hh"
#include "G4INCLFinalState.hh"
#ifndef G4INCAntinucleiAtrestEntry_hh
#define G4INCLAntinucleiAtrestEntry_hh 1
namespace G4INCL{
class FinalState;
class AntinucleiAtrestEntryChannel: public IChannel{
public :
AntinucleiAtrestEntryChannel(Nucleus *n, Cluster *ac, ThreeVector pos1, ThreeVector pos2);
AntinucleiAtrestEntryChannel(Nucleus *n, Particle *p);
virtual ~AntinucleiAtrestEntryChannel();
void fillFinalState(FinalState *fs);
ThreeVector getAnnihilationPosition(ThreeVector nbarPos, ThreeVector pbarPos);
ParticleList makeMesonStar();
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus * const n);
private:
Nucleus *theNucleus;
Cluster *theantiComposite;
ThreeVector Posnbar; //Position of the annihilation from PbarAtrestEntryChannel
ThreeVector Pospbar; //Position of the annihilation from NbarAtrestEntryChannel
Particle *Meson; // For fillFinalState
G4int pbarListSize; //To know who is coming from pbar annihilation
INCL_DECLARE_ALLOCATION_POOL(AntinucleiAtrestEntryChannel)
};
}
#endif
@@ -97,6 +97,8 @@ namespace G4INCL {
G4bool isElastic;
G4bool isStrangeProduction;
void generateSrcPairsMethod(ParticleList &theList, const int then, const int thez, G4INCL::Particle*, G4INCL::Particle*);
INCL_DECLARE_ALLOCATION_POOL(BinaryCollisionAvatar)
};
@@ -126,7 +126,7 @@ namespace G4INCL {
particleKineticEnergies.push_back((*p)->getKineticEnergy());
}
ProjectileRemnant * const aPR = n->getProjectileRemnant();
if(aPR && aPR->getA()>0) {
if(aPR && (aPR->getA()>0 || aPR->getA()<0)) {
particleMomenta.push_back(aPR->getMomentum());
particleKineticEnergies.push_back(aPR->getKineticEnergy());
outgoingParticles.push_back(aPR);
@@ -218,7 +218,7 @@ namespace G4INCL {
particleCMMomenta.push_back((*p)->getMomentum());
}
ProjectileRemnant * const aPR = n->getProjectileRemnant();
if(aPR && aPR->getA()>0) {
if(aPR && aPR->getA()!=0) {
aPR->boost(thePTBoostVector);
particleCMMomenta.push_back(aPR->getMomentum());
outgoingParticles.push_back(aPR);
@@ -375,10 +375,16 @@ namespace G4INCL {
/// \brief Initialise the "cascade" for pbar on H2
void preCascade_pbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
/// \brief Finalise the "cascade" and clean up for pbar on H1
/// \brief Initialise the "cascade" for nbar on H1
void preCascade_nbarH1(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
/// \brief Initialise the "cascade" for nbar on H2
void preCascade_nbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
/// \brief Finalise the "cascade" and clean up for pbar/nbar on H1
void postCascade_pbarH1(ParticleList const &outgoingParticles);
/// \brief Finalise the "cascade" and clean up for pbar on H2
/// \brief Finalise the "cascade" and clean up for pbar/nbar on H2
void postCascade_pbarH2(ParticleList const &outgoingParticles, ParticleList const &H2Particles);
};
}
@@ -63,6 +63,7 @@ namespace G4INCL {
theSpin(0.,0.,0.),
theParticleSampler(NULL)
{
if(A >= 0){
setType(Composite);
theZ = Z;
theA = A;
@@ -71,6 +72,16 @@ namespace G4INCL {
if(createParticleSampler)
theParticleSampler = new ParticleSampler(A,Z,S);
}
else {
setType(antiComposite);
theZ = Z;
theA = A;
theS = S;
setINCLMass();
if(createParticleSampler)
theParticleSampler = new ParticleSampler(A,Z,S);
}
}
/**
* A cluster can be directly built from a list of particles.
@@ -86,6 +97,11 @@ namespace G4INCL {
for(Iterator i = begin; i != end; ++i) {
addParticle(*i);
}
if (theA < 0){
setType(antiComposite);
thePosition /= (-theA);
}
else
thePosition /= theA;
setINCLMass();
adjustMomentumFromEnergy();
@@ -260,8 +276,13 @@ namespace G4INCL {
theTotalMomentum += (*p)->getMomentum();
//theTotalEnergy += (*p)->getEnergy();
}
if(theA>=0){
theCMPosition /= theA;
// assert((unsigned int)theA==particles.size());
} else if (theA < 0){
theCMPosition /= -theA;
//assert(-theA==particles.size());
}
// Now determine the CM velocity of the particles
// commented out because currently unused, see below
@@ -270,7 +291,13 @@ namespace G4INCL {
// The new particle positions and momenta are scaled by a factor of
// \f$\sqrt{A/(A-1)}\f$, so that the resulting density distributions in
// the CM have the same variance as the one we started with.
const G4double rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
G4double rescaling;
if (theA>0)
rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
else if (theA<0)
rescaling = std::sqrt(((G4double)(-theA))/((G4double)((-theA)-1)));
else
rescaling = 0 ;
// Loop again to boost and reposition
for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
@@ -278,7 +305,10 @@ namespace G4INCL {
// does not!
// (*p)->boost(betaCM);
// Here is what the Fortran version does:}
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
if (theA>0)
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
else if (theA<0)
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/(-theA))*rescaling);
// Set the CM position of the particles
(*p)->setPosition(((*p)->getPosition()-theCMPosition)*rescaling);
@@ -441,7 +471,7 @@ namespace G4INCL {
theDynamicalPotential += (*p)->getEnergy();
}
theDynamicalPotential -= getTableMass();
theDynamicalPotential /= theA;
theDynamicalPotential /= std::abs(theA);
return theDynamicalPotential;
}
@@ -76,6 +76,8 @@ namespace G4INCL {
* \return the ParticleEntryAvatar for the projectile particle
**/
ParticleEntryAvatar *bringToSurface(Particle *p, Nucleus * const n);
ParticleEntryAvatar *bringToSurfaceAbar(Particle *p, Nucleus * const n);
/** \brief Modify the momentum of an incoming cluster and position it on
* the surface of the target.
@@ -67,6 +67,8 @@ namespace G4INCL {
* \param n distorting nucleus
**/
ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const;
ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const;
/** \brief Modify the momentum of the incoming cluster and position it on
* the surface of the nucleus.
@@ -66,6 +66,15 @@ namespace G4INCL {
* \param n distorting nucleus
**/
ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const;
/** \brief Position the particle on the surface of the nucleus.
* ONLY FOR ANTIDEUTERON !!!
* This method does not perform any distortion.
*
* \param p incoming particle
* \param n distorting nucleus
**/
ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const;
/** \brief Position the cluster on the surface of the nucleus.
*
@@ -86,7 +95,7 @@ namespace G4INCL {
* trajectories. **/
G4double maxImpactParameter(ParticleSpecies const &p, const G4double /*kinE*/, Nucleus const *
const n) const {
if(p.theType == Composite)
if(p.theType == Composite || p.theType == antiComposite)
return 2.*ParticleTable::getLargestNuclearRadius(p.theA, p.theZ)
+ n->getUniverseRadius();
else
@@ -54,10 +54,14 @@ namespace G4INCL {
G4double piNToEtaN(Particle const * const p1, Particle const * const p2);
G4double piNToOmegaN(Particle const * const p1, Particle const * const p2);
G4double piNToEtaPrimeN(Particle const * const p1, Particle const * const p2);
G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
G4double etaNToLK(Particle const * const p1, Particle const * const p2);
G4double etaNToSK(Particle const * const p1, Particle const * const p2);
G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
G4double NNToNNEta(Particle const * const p1, Particle const * const p2);
@@ -143,7 +147,8 @@ namespace G4INCL {
* \return the interaction distance
*/
G4double interactionDistanceNN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
G4double interactionDistanceNbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
G4double interactionDistancenbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
/** \brief Compute the "interaction distance".
*
* Defined on the basis of the average value of the pi-N cross sections at
@@ -88,6 +88,12 @@ namespace G4INCL {
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - LK/SK Channel
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for Eta production - NN entrance channel
virtual G4double NNToNNEta(Particle const * const p1, Particle const * const p2);
@@ -98,7 +98,13 @@ namespace G4INCL {
virtual G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - LK/SKChannel
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for Eta production - NN entrance channel
virtual G4double NNToNNEta(Particle const * const particle1, Particle const * const particle2);
@@ -74,8 +74,12 @@ namespace G4INCL {
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - pipiN Channel
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - pipiN Channel
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for eta-N --> LK/SK
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for Eta production (inclusive) - NN entrance channel
virtual G4double NNToNNEta(Particle const * const particle1, Particle const * const particle2);
@@ -92,11 +96,11 @@ namespace G4INCL {
/// \brief Cross section for X pion production - NN Channel
virtual G4double NNToxPiNN(const G4int xpi, Particle const * const p1, Particle const * const p2);
/// \brief Cross section for X pion production - NNEta Channel
virtual G4double NNToNNEtaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
/// \brief Cross section for X pion production - NNEta Channel
virtual G4double NNToNNEtaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
/// \brief Cross section for N-Delta-Eta production - NNEta Channel
virtual G4double NNToNDeltaEta(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for N-Delta-Eta production - NNEta Channel
virtual G4double NNToNDeltaEta(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for X pion production - NNOmega Channel
virtual G4double NNToNNOmegaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
@@ -161,9 +165,9 @@ namespace G4INCL {
G4double piMinuspToOmegaN(Particle const * const p1, Particle const * const p2);
G4double piMinuspToOmegaN(const G4double ECM);
// G4double piPluspOnePi(Particle const * const p1, Particle const * const p2);
// G4double piMinuspOnePi(Particle const * const p1, Particle const * const p2);
// G4double piMinuspOnePi(Particle const * const p1, Particle const * const p2);
// G4double piPluspTwoPi(Particle const * const p1, Particle const * const p2);
// G4double piMinuspTwoPi(Particle const * const p1, Particle const * const p2);
// G4double piMinuspTwoPi(Particle const * const p1, Particle const * const p2);
/// \brief Cross section for One (more) pion production - piN entrance channel
// virtual G4double piNOnePi(Particle const * const p1, Particle const * const p2);
@@ -174,22 +178,22 @@ namespace G4INCL {
/// \brief Cross section for Three (more) pion production - piN entrance channel
///virtual G4double piNThreePi(Particle const * const p1, Particle const * const p2);
/// \brief Isotopic Cross section for Eta production (inclusive) - NN entrance channel
virtual G4double NNToNNEtaIso(const G4double ener, const G4int iso);
/// \brief Isotopic Cross section for Eta production (inclusive) - NN entrance channel
virtual G4double NNToNNEtaIso(const G4double ener, const G4int iso);
/// \brief Isotopic Cross section for Eta production (exclusive) - NN entrance channel
virtual G4double NNToNNEtaExcluIso(const G4double ener, const G4int iso);
/// \brief Isotopic Cross section for Eta production (exclusive) - NN entrance channel
virtual G4double NNToNNEtaExcluIso(const G4double ener, const G4int iso);
/// \brief Cross section for direct 1-pion production - NNEta channel
virtual G4double NNToNNEtaOnePi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 1-pion production - NNEta channel
virtual G4double NNToNNEtaOnePiOrDelta(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 2-pion production - NNEta channel
virtual G4double NNToNNEtaTwoPi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 3-pion production - NNEta channel
virtual G4double NNToNNEtaThreePi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 4-pion production - NNEta channel
virtual G4double NNToNNEtaFourPi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 1-pion production - NNEta channel
virtual G4double NNToNNEtaOnePi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 1-pion production - NNEta channel
virtual G4double NNToNNEtaOnePiOrDelta(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 2-pion production - NNEta channel
virtual G4double NNToNNEtaTwoPi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 3-pion production - NNEta channel
virtual G4double NNToNNEtaThreePi(Particle const * const part1, Particle const * const part2);
/// \brief Cross section for direct 4-pion production - NNEta channel
virtual G4double NNToNNEtaFourPi(Particle const * const part1, Particle const * const part2);
/// \brief Isotopic Cross section for Omega production (inclusive) - NN entrance channel
@@ -210,8 +214,8 @@ namespace G4INCL {
virtual G4double NNToNNOmegaFourPi(Particle const * const part1, Particle const * const part2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - elastic Channel
virtual G4double etaNElastic(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for mesonic resonance absorption on nucleon - elastic Channel
virtual G4double etaNElastic(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNElastic(Particle const * const p1, Particle const * const p2);
@@ -219,7 +223,9 @@ namespace G4INCL {
virtual G4double omegaNInelastic(Particle const * const p1, Particle const * const p2);
/// \brief Cross sections for omega-induced 2Pi emission on nucleon
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
};
}
@@ -90,7 +90,7 @@ namespace G4INCL {
virtual G4double NDeltaToNNKKb(Particle const * const p1, Particle const * const p2);
/// \brief Nucleon-Pion to Stange particles cross sections
/// \brief Nucleon-Pion to Strange particles cross sections
virtual G4double NpiToLK(Particle const * const p1, Particle const * const p2);
G4double p_pimToLK0(Particle const * const p1, Particle const * const p2);
virtual G4double NpiToSK(Particle const * const p1, Particle const * const p2);
@@ -126,6 +126,15 @@ namespace G4INCL {
virtual G4double p_kmToL_pp_pm(Particle const * const p1, Particle const * const p2);
virtual G4double NKbToNKbpi(Particle const * const p1, Particle const * const p2);
virtual G4double NKbToNKb2pi(Particle const * const p1, Particle const * const p2);
/// \brief eta-Nucleon cross sections
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
/// \brief Omega-Nucleon cross sections
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
protected:
/// \brief Maximum number of outgoing pions in NN collisions
@@ -43,11 +43,12 @@
#include "G4INCLIChannel.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLAllocationPool.hh"
#include "G4INCLSrcChannel.hh"
namespace G4INCL {
class DeltaProductionChannel : public IChannel {
public:
DeltaProductionChannel(Particle *, Particle *);
DeltaProductionChannel(Particle *, Particle *, Nucleus *n = nullptr);
virtual ~DeltaProductionChannel();
void fillFinalState(FinalState *fs);
@@ -56,6 +57,8 @@ namespace G4INCL {
G4double sampleDeltaMass(G4double ecm);
Particle *particle1, *particle2;
Nucleus *thenucleus;
SrcChannel *srcChannel;
static const G4int maxTries;
INCL_DECLARE_ALLOCATION_POOL(DeltaProductionChannel)
@@ -36,11 +36,12 @@
#include "globals.hh"
#include "G4INCLParticle.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLAllocationPool.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLParticle.hh"
#include "G4INCLSrcChannel.hh"
#ifndef G4INCLElasticChannel_HH_
#define G4INCLElasticChannel_HH_ 1
@@ -49,17 +50,19 @@ namespace G4INCL {
class ElasticChannel : public IChannel {
public:
ElasticChannel(Particle *p1, Particle *p2);
ElasticChannel(Particle *p1, Particle *p2, Nucleus *n = nullptr);
virtual ~ElasticChannel();
void fillFinalState(FinalState *fs);
private:
Particle *particle1, *particle2;
Nucleus *thenucleus;
SrcChannel *srcChannel;
INCL_DECLARE_ALLOCATION_POOL(ElasticChannel)
};
}
} // namespace G4INCL
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
#ifndef G4INCLEtaOrOmegaNToLKChannel_hh
#define G4INCLEtaOrOmegaNToLKChannel_hh 1
#include "G4INCLParticle.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLAllocationPool.hh"
namespace G4INCL {
class EtaOrOmegaNToLKChannel : public IChannel {
public:
EtaOrOmegaNToLKChannel(Particle *, Particle *);
virtual ~EtaOrOmegaNToLKChannel();
void fillFinalState(FinalState *fs);
private:
Particle *particle1, *particle2;
INCL_DECLARE_ALLOCATION_POOL(EtaOrOmegaNToLKChannel);
};
}
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
#ifndef G4INCLEtaOrOmegaNToSKChannel_hh
#define G4INCLEtaOrOmegaNToSKChannel_hh 1
#include "G4INCLParticle.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLAllocationPool.hh"
namespace G4INCL {
class EtaOrOmegaNToSKChannel : public IChannel {
public:
EtaOrOmegaNToSKChannel(Particle *, Particle *);
virtual ~EtaOrOmegaNToSKChannel();
void fillFinalState(FinalState *fs);
private:
Particle *particle1, *particle2;
INCL_DECLARE_ALLOCATION_POOL(EtaOrOmegaNToSKChannel);
};
}
#endif
@@ -77,6 +77,8 @@ namespace G4INCL {
* \return the ParticleEntryAvatar for the projectile particle
**/
virtual ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const = 0;
virtual ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const = 0;
/** \brief Modify the momentum of an incoming cluster and position it on
* the surface of the target.
@@ -90,12 +90,20 @@ namespace G4INCL {
/// \brief Cross section for EtaN->PiPiN
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2) = 0;
/// \brief Cross section for EtaN->LK/SK
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2) = 0;
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2) = 0;
/// \brief Cross section for OmegaN->PiN
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2) = 0;
/// \brief Cross section for OmegaN->PiPiN
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2) = 0;
/// \brief Cross section for OmegaN->LK/SK
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2) = 0;
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2) = 0;
/// \brief Cross section for EtaPrimeN->PiN
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2) = 0;
@@ -85,6 +85,7 @@ namespace G4INCL {
virtual G4double shootAtrest(ParticleType const t, const G4double kineticEnergy) = 0;
virtual G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) = 0;
virtual G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) = 0;
virtual G4double shootCompositeAtrest(ParticleSpecies const &s, const G4double kineticEnergy) = 0;
public:
@@ -71,17 +71,30 @@ namespace G4INCL {
/// \brief Release the memory allocated for the backup particles
static void deleteBackupParticles();
/**
* static instance
*/
static InteractionAvatar* Instance();
protected:
virtual G4INCL::IChannel* getChannel() = 0;
G4bool bringParticleInside(Particle * const p);
void setSrcPartner(Particle *p /*, const ThreeVector m*/);
/** \brief Apply local-energy transformation, if appropriate
*
* \param p particle to apply the transformation to
*/
void preInteractionLocalEnergy(Particle * const p);
ThreeVector getboostVector(){return boostVector;}
void setboostVector(ThreeVector& v){boostVector = v;}
protected:
virtual G4INCL::IChannel* getChannel() = 0;
G4bool bringParticleInside(Particle * const p);
EventInfo theEventInfo;
/** \brief Store the state of the particles before the interaction
*
@@ -99,6 +112,8 @@ namespace G4INCL {
* The state must first be stored by calling preInteractionBlocking().
*/
void restoreParticles() const;
void restoreSrcPartner(FinalState * fs);
/// \brief true if the given avatar should use local energy
G4bool shouldUseLocalEnergy() const;
@@ -112,6 +127,10 @@ namespace G4INCL {
G4double weight;
private:
static G4ThreadLocal InteractionAvatar* interactionAvatar;
static G4ThreadLocal Particle *backupPartner;
static ThreeVector mbackupPartner;
/// \brief RootFunctor-derived object for enforcing energy conservation in N-N.
class ViolationEMomentumFunctor : public RootFunctor {
public:
@@ -0,0 +1,91 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* G4INCLNbarAtrestEntryChannel.hh
*
* \date Aug 21, 2024
* \author Olivier Lourgo
*/
#include "G4INCLParticle.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLAllocationPool.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLICoulomb.hh"
#include <utility>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#ifndef G4INCLNbarAtrestEntry_hh
#define G4INCLNbarAtrestEntry_hh 1
namespace G4INCL{
class FinalState;
class NbarAtrestEntryChannel :public IChannel {
public :
NbarAtrestEntryChannel(Nucleus *n, Particle *p);
virtual ~NbarAtrestEntryChannel();
void fillFinalState(FinalState *fs);
ParticleList makeMesonStar();
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus * const n);
G4bool ProtonIsTheVictim();
ThreeVector getAnnihilationPosition();
G4double Pabs(G4double x, G4double value);
G4double densityP();
G4double densityN();
G4double overlapP(G4double &x);
G4double overlapN(G4double &x);
G4double read_file(std::string filename, std::vector<G4double>& probabilities, std::vector<std::vector<std::string>>& particle_types);
G4int findStringNumber(G4double rdm, std::vector<G4double> yields);
private:
Nucleus *theNucleus;
Particle *theParticle;
INCL_DECLARE_ALLOCATION_POOL(NbarAtrestEntryChannel)
};
}
#endif
@@ -87,6 +87,8 @@ namespace G4INCL {
if(t==Composite) {
return transmissionRadius[t] +
ParticleTable::getNuclearRadius(t, p->getA(), p->getZ());
} else if(t==antiComposite){
return transmissionRadius[t] + ParticleTable::getNuclearRadius(t,-(p->getA()),-(p->getZ()));
} else
return transmissionRadius[t];
};
@@ -97,6 +99,7 @@ namespace G4INCL {
*/
G4double getTransmissionRadius(ParticleType type) const {
// assert(type!=Composite);
// assert(type!=antiComposite);
return transmissionRadius[type];
};
@@ -65,7 +65,7 @@ namespace G4INCL {
G4double vProton, vNeutron;
G4double vDeltaPlusPlus, vDeltaPlus, vDeltaZero, vDeltaMinus;
G4double vSigmaPlus, vSigmaZero, vSigmaMinus, vLambda;
G4double vantiProton;
G4double vantiProton, vantiNeutron;
void initialize();
@@ -62,7 +62,7 @@
namespace G4INCL {
enum AnnihilationType {Def=0, PType, NType, PTypeInFlight, NTypeInFlight, NbarPTypeInFlight, NbarNTypeInFlight};
enum AnnihilationType {Def=0, PType, NType, PTypeInFlight, NTypeInFlight, NbarPTypeInFlight, NbarNTypeInFlight, DNbarNPbarPType, DNbarNPbarNType, DNbarPPbarPType, DNbarPPbarNType};
class Nucleus : public Cluster {
public:
@@ -94,6 +94,15 @@ namespace G4INCL {
theNpInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
theNnInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
}
if(p->isLambda())
theNlInitial++;
if(p->getType() == SigmaPlus)
theNSpInitial++;
if(p->getType() == SigmaZero)
theNSzInitial++;
if(p->getType() == SigmaMinus)
theNSmInitial++;
if(p->isPion()) {
theNpionplusInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
theNpionminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
@@ -103,7 +112,8 @@ namespace G4INCL {
theNkaonminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
}
if(p->isAntiNucleon()) {
theNantiprotonInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
if (p->getZ()<0) theNantiprotonInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
else theNantineutronInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
}
if(!p->isTargetSpectator()) theStore->getBook().incrementCascading();
};
@@ -129,6 +139,7 @@ namespace G4INCL {
G4int getNumberOfEnteringPions() const { return theNpionplusInitial+theNpionminusInitial; };
G4int getNumberOfEnteringKaons() const { return theNkaonplusInitial+theNkaonminusInitial; };
G4int getNumberOfEnteringantiProtons() const { return theNantiprotonInitial; };
G4int getNumberOfEnteringantiNeutrons() const { return theNantineutronInitial; };
/** \brief Outgoing - incoming separation energies.
*
@@ -158,16 +169,25 @@ namespace G4INCL {
case SigmaPlus:
case SigmaZero:
case SigmaMinus:
case antiProton:
//case antiNeutron:
//case antiLambda:
S += thePotential->getSeparationEnergy(*i);
break;
case antiSigmaPlus:
case antiSigmaZero:
case antiSigmaMinus:
case antiLambda:
case antiProton:
case antiNeutron:
S -= thePotential->getSeparationEnergy(*i);
break;
case Composite:
S += (*i)->getZ() * thePotential->getSeparationEnergy(Proton)
+ ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(Neutron)
- (*i)->getS() * thePotential->getSeparationEnergy(Lambda);
break;
case antiComposite:
S -= (*i)->getZ() * thePotential->getSeparationEnergy(antiProton)
+ ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(antiNeutron);
break;
default:
break;
}
@@ -175,11 +195,16 @@ namespace G4INCL {
S -= theNpInitial * thePotential->getSeparationEnergy(Proton);
S -= theNnInitial * thePotential->getSeparationEnergy(Neutron);
S -= theNlInitial * thePotential->getSeparationEnergy(Lambda);
S -= theNSpInitial * thePotential->getSeparationEnergy(SigmaPlus);
S -= theNSzInitial * thePotential->getSeparationEnergy(SigmaZero);
S -= theNSmInitial * thePotential->getSeparationEnergy(SigmaMinus);
S -= theNpionplusInitial*thePotential->getSeparationEnergy(PiPlus);;
S -= theNkaonplusInitial*thePotential->getSeparationEnergy(KPlus);
S -= theNpionminusInitial*thePotential->getSeparationEnergy(PiMinus);
S -= theNkaonminusInitial*thePotential->getSeparationEnergy(KMinus);
S -= theNantiprotonInitial*thePotential->getSeparationEnergy(antiProton);
S += theNantiprotonInitial*thePotential->getSeparationEnergy(antiProton);
S += theNantineutronInitial*thePotential->getSeparationEnergy(antiNeutron);
return S;
}
@@ -241,9 +266,15 @@ namespace G4INCL {
/// \brief Force emission of all Lambda (desexitation code with strangeness not implanted yet)
G4int emitInsideLambda();
/// \brief Force emission of all Antilambda
G4int emitInsideAntilambda();
/// \brief Force emission of all Kaon inside the nucleus
G4bool emitInsideKaon();
/// \brief Force emission of all Antinucleon inside the nucleus
G4bool emitInsideAnnihilationProducts();
/** \brief Compute the recoil momentum and spin of the nucleus. */
void computeRecoilKinematics();
@@ -319,6 +350,14 @@ namespace G4INCL {
if((*i)->isLambda()) return true;
return false;
}
///\brief Returns true if the nucleus contains any Antilambda.
inline G4bool containsAntilambda() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isAntiLambda()) return true;
return false;
}
///\brief Returns true if the nucleus contains any Sigma.
inline G4bool containsSigma() {
@@ -335,22 +374,50 @@ namespace G4INCL {
if((*i)->isKaon()) return true;
return false;
}
///\brief Returns true if the nucleus contains any Antinucleons.
inline G4bool containsAntinucleon() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isAntiNucleon()) return true;
return false;
}
///\brief Returns true if the nucleus contains any etas.
inline G4bool containsEtas() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isEta()) return true;
return false;
}
///\brief Returns true if the nucleus contains any etas.
inline G4bool containsEtas() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isEta()) return true;
return false;
}
///\brief Returns true if the nucleus contains any omegas.
inline G4bool containsOmegas() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isOmega()) return true;
return false;
}
///\brief Returns true if the nucleus contains any omegas.
inline G4bool containsOmegas() {
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isOmega()) return true;
return false;
}
///\brief Resets the src partners.
inline void resetSrc(){
ParticleList const &inside = theStore->getParticles();
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
(*i)->resetSrcPartner();
}
inline void setSrcInternalEnergy(double value){
srcInternalEnergy = value;
}
inline void updateInternalEnergy(double value){
initialInternalEnergy += value;
}
G4double getSrcInternalEnergy() const {
return srcInternalEnergy;
}
/**
@@ -398,6 +465,8 @@ namespace G4INCL {
G4double energy;
G4int Z, A, S;
};
void restoreSrcPartner(Particle *particle, ThreeVector m);
/// \brief Compute charge, mass, energy and momentum balance
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const;
@@ -509,6 +578,11 @@ namespace G4INCL {
G4int theNpInitial;
/// \brief The number of entering neutrons
G4int theNnInitial;
/// \brief The number of entering hyperons
G4int theNlInitial;
G4int theNSpInitial;
G4int theNSzInitial;
G4int theNSmInitial;
/// \brief The number of entering pions
G4int theNpionplusInitial;
G4int theNpionminusInitial;
@@ -517,8 +591,11 @@ namespace G4INCL {
G4int theNkaonminusInitial;
/// \brief The number of entering antiprotons
G4int theNantiprotonInitial;
/// \brief The number of entering antineutrons
G4int theNantineutronInitial;
G4double initialInternalEnergy;
G4double srcInternalEnergy;
ThreeVector incomingAngularMomentum, incomingMomentum;
ThreeVector initialCenterOfMass;
G4bool remnant;
@@ -45,7 +45,7 @@
namespace G4INCL {
enum EntryType{Default, APAR}; //D
enum EntryType{Default, APAR, ANAR, ADAR}; //D
class ParticleEntryAvatar: public G4INCL::IAvatar {
public:
@@ -197,7 +197,7 @@ namespace G4INCL {
}
std::sort(energies.begin(), energies.end());
// assert(energies.size()==(unsigned int)theA);
//assert(energies.size()==(unsigned int)theA || energies.size()== (unsigned int)-theA);
theGroundStateEnergies.resize(energies.size());
// Compute the partial sums of the CM energies -- they are our reference
// ground-state energies for any number of nucleons
@@ -0,0 +1,85 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* \file G4INCLSrcChannel.hh
*
* \date Feb 24, 2022
* \author Jose Luis Rodriguez-Sanchez
*/
#include "G4INCLAllocationPool.hh"
#include "G4INCLFinalState.hh"
#include "G4INCLIChannel.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLParticle.hh"
#include "G4INCLEventInfo.hh"
#ifndef G4INCLSrcChannel_HH
#define G4INCLSrcChannel_HH 1
namespace G4INCL {
class SrcChannel : public IChannel {
public:
SrcChannel(Particle *p1, Particle *p2, Nucleus *n);
virtual ~SrcChannel();
void fillFinalState(FinalState *fs);
void fillFinalState(FinalState *fs, ParticleType , ParticleType);
private:
Particle *particle1, *particle2;
ParticleType ftype1, ftype2;
Particle *srcpartner;
Nucleus *thenucleus;
double fDistSrc;
EventInfo theEventInfo;
/**
* Compute the current number of src pairs.
*/
Particle *findpairpartner(Particle *pt);
INCL_DECLARE_ALLOCATION_POOL(SrcChannel)
};
} // namespace G4INCL
#endif /* G4INCLSrcChannel_HH */
@@ -85,7 +85,8 @@ namespace G4INCL {
G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy);
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy);
G4double shootCompositeAtrest(ParticleSpecies const &s, const G4double kineticEnergy);
/**
* Set the stopping time of the simulation.
@@ -197,6 +197,12 @@ namespace G4INCL {
for(ParticleIter p=pl.begin(), e=pl.end(); p!=e; ++p)
addToOutgoing(*p);
}
/** \brief add the particle to the missed particle list (for dbar).
*
* \param p pointer to the particle to be added
*/
void addToMissed(Particle *p) { missed.push_back(p); }
/**
* Remove the particle from the system. This also removes all
@@ -221,6 +227,12 @@ namespace G4INCL {
* cascade).
*/
ParticleList const & getOutgoingParticles() const { return outgoing; }
/**
* Return the list of missed particles (i.e. particles that have missed the
* nucleus and so do not participate in the cascade, only for dbar).
*/
ParticleList const & getMissedParticles() const { return missed; }
/** \brief Returns a list of dynamical spectators
*
@@ -233,7 +245,7 @@ namespace G4INCL {
ParticleList spectators;
for(ParticleIter p=outgoing.begin(), e=outgoing.end(); p!=e; ++p) {
if((*p)->isProjectileSpectator()) {
// assert((*p)->isNucleon() || (*p)->isLambda());
// assert((*p)->isNucleon() || (*p)->isLambda() || (*p)->isAntiNucleon());
spectators.push_back(*p); // add them to the list we will return
}
}
@@ -251,6 +263,12 @@ namespace G4INCL {
* participate in collisions).
*/
ParticleList const & getParticles() const { return inside; }
/**
* Return the list of "active" particles (i.e. particles that can
* participate in collisions) to define the src-pairs.
*/
ParticleList & getParticlesforSrc() { return inside; }
/**
* Return the pointer to the Book object which keeps track of
@@ -425,6 +443,11 @@ namespace G4INCL {
* List of outgoing particles
*/
ParticleList outgoing;
/**
* List of missed particles (for dbar)
*/
ParticleList missed;
/**
* List of geometrical spectators
@@ -3,6 +3,7 @@
# Define the Geant4 Module.
geant4_add_module(G4hadronic_inclxx_physics
PUBLIC_HEADERS
G4INCLAntinucleiAtrestEntryChannel.hh
G4INCLAvatarDumpAction.hh
G4INCLBinaryCollisionAvatar.hh
G4INCLCascade.hh
@@ -33,6 +34,8 @@ geant4_add_module(G4hadronic_inclxx_physics
G4INCLEtaNElasticChannel.hh
G4INCLEtaNToPiNChannel.hh
G4INCLEtaNToPiPiNChannel.hh
G4INCLEtaOrOmegaNToLKChannel.hh
G4INCLEtaOrOmegaNToSKChannel.hh
G4INCLIClusteringModel.hh
G4INCLICoulomb.hh
G4INCLICrossSections.hh
@@ -42,6 +45,7 @@ geant4_add_module(G4hadronic_inclxx_physics
G4INCLIPhaseSpaceGenerator.hh
G4INCLIPropagationModel.hh
G4INCLKinematicsUtils.hh
G4INCLNbarAtrestEntryChannel.hh
G4INCLNDeltaEtaProductionChannel.hh
G4INCLNDeltaOmegaProductionChannel.hh
G4INCLNDeltaToDeltaLKChannel.hh
@@ -131,12 +135,14 @@ geant4_add_module(G4hadronic_inclxx_physics
G4INCLRecombinationChannel.hh
G4INCLReflectionChannel.hh
G4INCLSigmaZeroDecayChannel.hh
G4INCLSrcChannel.hh
G4INCLStandardPropagationModel.hh
G4INCLStore.hh
G4INCLStrangeAbsorbtionChannel.hh
G4INCLSurfaceAvatar.hh
G4INCLTransmissionChannel.hh
SOURCES
G4INCLAntinucleiAtrestEntryChannel.cc
G4INCLAvatarDumpAction.cc
G4INCLBinaryCollisionAvatar.cc
G4INCLCascade.cc
@@ -165,9 +171,12 @@ geant4_add_module(G4hadronic_inclxx_physics
G4INCLEtaNElasticChannel.cc
G4INCLEtaNToPiNChannel.cc
G4INCLEtaNToPiPiNChannel.cc
G4INCLEtaOrOmegaNToLKChannel.cc
G4INCLEtaOrOmegaNToSKChannel.cc
G4INCLInteractionAvatar.cc
G4INCLINuclearPotential.cc
G4INCLKinematicsUtils.cc
G4INCLNbarAtrestEntryChannel.cc
G4INCLNDeltaEtaProductionChannel.cc
G4INCLNDeltaOmegaProductionChannel.cc
G4INCLNDeltaToDeltaLKChannel.cc
@@ -252,6 +261,7 @@ geant4_add_module(G4hadronic_inclxx_physics
G4INCLRecombinationChannel.cc
G4INCLReflectionChannel.cc
G4INCLSigmaZeroDecayChannel.cc
G4INCLSrcChannel.cc
G4INCLStandardPropagationModel.cc
G4INCLStore.cc
G4INCLStrangeAbsorbtionChannel.cc
@@ -0,0 +1,147 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* G4INCLAntinucleiAtrestEntryChannel.cc
*
*
* \author Olivier Lourgo
*/
#include "G4INCLAntinucleiAtrestEntryChannel.hh"
#include "G4INCLNbarAtrestEntryChannel.hh"
#include "G4INCLPbarAtrestEntryChannel.hh"
#include "G4INCLPhaseSpaceGenerator.hh"
namespace G4INCL{
AntinucleiAtrestEntryChannel::AntinucleiAtrestEntryChannel(Nucleus *n, Cluster *ac, ThreeVector pos1, ThreeVector pos2)
:theNucleus(n), theantiComposite(ac), Posnbar(pos1), Pospbar(pos2){}
AntinucleiAtrestEntryChannel::AntinucleiAtrestEntryChannel(Nucleus *n, Particle *p):theNucleus(n),Meson(p){}
AntinucleiAtrestEntryChannel::~AntinucleiAtrestEntryChannel(){}
ThreeVector AntinucleiAtrestEntryChannel::getAnnihilationPosition(ThreeVector nbarPos, ThreeVector pbarPos){ //Choose between the pbar or nbar annihilation position
if((nbarPos - pbarPos).mag2() <= ParticleTable::getLargestNuclearRadius(-theantiComposite->getA(),- theantiComposite->getZ())){
//If the annihilions positions are close (the radius of a deuteron) then we have 2 sources for the meson star
return ThreeVector(999.,999.,999.);
}
if(nbarPos.mag2() <= pbarPos.mag2())
return nbarPos;
else
return pbarPos;
}
ParticleList AntinucleiAtrestEntryChannel::makeMesonStar(){
ParticleList Antiparticles = theantiComposite->getParticles();
Particle *nbar=nullptr;
Particle *pbar=nullptr;
for(ParticleIter p =Antiparticles.begin(), e=Antiparticles.end(); p!=e; ++p){
if((*p)->getType()==antiProton)
pbar = *p;
else if((*p)->getType()==antiNeutron)
nbar = *p;
else
INCL_ERROR("ERROR : something else than antiNeutron or antiProton in antiComposite");
}
PbarAtrestEntryChannel *pbarChannel = new PbarAtrestEntryChannel(theNucleus, pbar);
NbarAtrestEntryChannel *nbarChannel = new NbarAtrestEntryChannel(theNucleus, nbar);
ParticleList TotalStarList = pbarChannel->makeMesonStar(); //pbar in first because polarisation of the dbar (Coulomb)
ParticleList nbarMesonStar = nbarChannel->makeMesonStar();
pbarListSize = (G4int)TotalStarList.size();
for(ParticleIter p=nbarMesonStar.begin(), e=nbarMesonStar.end(); p!=e; ++p){
TotalStarList.push_back(*p);
}
Pospbar = pbarChannel->getAnnihilationPosition();
Posnbar = nbarChannel->getAnnihilationPosition();
G4double EnergyofFinalMesonStar = 0;
G4int a=theNucleus->getA();
G4int z=theNucleus->getZ();
G4int stra=theNucleus->getS();
if(theNucleus->getAnnihilationType()==DNbarPPbarPType){
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z+2,stra)- ParticleTable::getTableMass(a,z+1,stra));
}
else if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){
//Correction for all but they all cancel out !
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z+1,stra)- ParticleTable::getTableMass(a,z,stra));
}
else if(theNucleus->getAnnihilationType()==DNbarNPbarNType){
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z,stra) - ParticleTable::getTableMass(a,z-1,stra));
}
PhaseSpaceGenerator::generate(EnergyofFinalMesonStar, TotalStarList);
return TotalStarList;
}
IAvatarList AntinucleiAtrestEntryChannel::bringMesonStar(ParticleList const &pL, Nucleus * const n){
ThreeVector ann_position = getAnnihilationPosition(Posnbar,Pospbar);
IAvatarList theAvatarList;
G4int cnt=1;
if (ann_position.getX() == 999. && ann_position.getY() == 999. && ann_position.getZ() == 999.){
INCL_DEBUG("Particle are close to each other : 2 sources of annihilation "<< '\n');
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p){
if(cnt <= pbarListSize){
(*p)->setPosition(Pospbar);
}
else
(*p)->setPosition(Posnbar);
theAvatarList.push_back(new ParticleEntryAvatar(0.0, n, *p, ADAR));
cnt++;
}
}
else{
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p){
(*p)->setPosition(ann_position);
theAvatarList.push_back(new ParticleEntryAvatar(0.0, n, *p, ADAR));
}
}
return theAvatarList;
}
void AntinucleiAtrestEntryChannel::fillFinalState(FinalState *fs){
const G4double energyBefore = Meson->getEnergy();
fs->addEnteringParticle(Meson);
INCL_DEBUG("Entering antiComposite annihilation product added " << '\n');
fs->setTotalEnergyBeforeInteraction(energyBefore);
}
}
@@ -68,6 +68,8 @@
#include "G4INCLEtaNToPiPiNChannel.hh"
#include "G4INCLOmegaNElasticChannel.hh"
#include "G4INCLOmegaNToPiNChannel.hh"
#include "G4INCLEtaOrOmegaNToLKChannel.hh"
#include "G4INCLEtaOrOmegaNToSKChannel.hh"
#include "G4INCLNNToNLKChannel.hh"
#include "G4INCLNNToNSKChannel.hh"
#include "G4INCLNNToNLKpiChannel.hh"
@@ -141,6 +143,67 @@ namespace G4INCL {
BinaryCollisionAvatar::~BinaryCollisionAvatar() {
}
void BinaryCollisionAvatar::generateSrcPairsMethod(ParticleList &theList,
const G4int theN,
const G4int theZ,
G4INCL::Particle *p1,
G4INCL::Particle *p2) {
std::vector<ThreeVector> posp;
std::vector<ThreeVector> posn;
posp.resize(theZ);
posn.resize(theN);
for (int i = 0; i < theZ + theN; ++i) {
theList[i]->setNumberOfSrcPair(0);
}
theNucleus->getStore()->getBook().setSrcPairs(0);
// Check that the loops in theZ and theN do what we wish!
G4int npairs = 0;
for (G4int i = 0; i < theZ; ++i) {
Particle *ap = theList[i];
posp[i] = ap->getPosition();
for (G4int j = 0; j < theN; ++j) {
Particle *an = theList[j + theZ];
posn[j] = an->getPosition();
if ((posn[j] - posp[i]).mag() < ParticleTable::getsrcPairDistance() &&
ap->getSrcPair() == 0 && an->getSrcPair() == 0 &&
ap->getType() != an->getType() && ap->isTargetSpectator() == 1 &&
an->isTargetSpectator() == 1) {
npairs++;
theNucleus->getStore()->getBook().incrementSrcPairs();
if (an == p1 || an == p2 || ap == p1 || ap == p2) {
theList[i]->setNumberOfSrcPair(npairs);
theList[j + theZ]->setNumberOfSrcPair(npairs);
}
}
}
}
G4int nbp = 0, nbn = 0;
for (G4int i = 0; i < theZ + theN; ++i) {
if (theList[i]->getSrcPair() > 0 && theList[i]->getType() == Proton)
nbp++;
if (theList[i]->getSrcPair() > 0 && theList[i]->getType() == Neutron)
nbn++;
}
if (nbp != nbn) {
INCL_DEBUG("Pairs: " << nbp << " " << nbn << '\n');
for (G4int i = 0; i < theZ; ++i) {
INCL_DEBUG(ParticleTable::getName(theList[i]->getType())
<< " " << theList[i]->isTargetSpectator() << " "
<< theList[i]->getSrcPair());
}
INCL_DEBUG("----------- End ------------------" << '\n');
}
return;
}
G4INCL::IChannel* BinaryCollisionAvatar::getChannel() {
// We already check cutNN at avatar creation time, but we have to check it
@@ -182,12 +245,21 @@ namespace G4INCL {
minimumDistance -= particle2->getPosition();
const G4double betaDotX = boostVector.dot(minimumDistance);
const G4double minDist = Math::tenPi*(minimumDistance.mag2() + betaDotX*betaDotX / (1.-boostVector.mag2()));
if(minDist > theCrossSection) {
Config const *theConfig=theNucleus->getStore()->getConfig();
if ((minDist > theCrossSection) &&
(!((particle1->getType()==antiProton && particle1->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
(particle2->getType()==antiProton && particle2->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
(particle1->getType()==antiNeutron && particle1->getKineticEnergy() <= particle1->getPotentialEnergy()) ||
(particle2->getType()==antiNeutron && particle2->getKineticEnergy() <= particle2->getPotentialEnergy())))) {
if(!((particle1->isAntiNucleon() && particle1->getEnergy() <= particle1->getINCLMass()) ||
(particle2->isAntiNucleon() && particle2->getEnergy() <= particle2->getINCLMass()))){
INCL_DEBUG("CM distance of approach is too small: " << minDist << ">" <<
theCrossSection <<"; returning a NULL channel" << '\n');
InteractionAvatar::restoreParticles();
return NULL;
}
}
/** Bias apply for this reaction in order to get the same
* ParticleBias for all stange particles.
@@ -261,15 +333,50 @@ namespace G4INCL {
if(elasticCX > rChannel) {
// Elastic NN channel
isElastic = true;
weight = counterweight;
if (theNucleus->getStore()->getBook().getAcceptedCollisions() == 0 &&
theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 0 &&
ParticleTable::getsrcPairConfig()) {
INCL_DEBUG("NN-SRC interaction: elastic channel chosen" << '\n');
ParticleList &inside = theNucleus->getStore()->getParticlesforSrc();
G4int zz = theNucleus->getZ();
generateSrcPairsMethod(inside, theNucleus->getA() - zz, zz, particle1,
particle2);
if ((particle1->getSrcPair() > 0 || particle2->getSrcPair() > 0)) {
return new ElasticChannel(particle1, particle2, theNucleus);
} else {
INCL_DEBUG("NN interaction: elastic channel chosen" << '\n');
theNucleus->resetSrc();
return new ElasticChannel(particle1, particle2);
}
} else {
INCL_DEBUG("NN interaction: elastic channel chosen" << '\n');
weight = counterweight;
return new ElasticChannel(particle1, particle2);
}
} else if((elasticCX + deltaProductionCX) > rChannel) {
isElastic = false;
// NN -> N Delta channel is chosen
weight = counterweight;
if (theNucleus->getStore()->getBook().getAcceptedCollisions() == 0 &&
theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 0 &&
ParticleTable::getsrcPairConfig()) {
INCL_DEBUG("NN-SRC interaction: Delta channel chosen" << '\n');
ParticleList &inside = theNucleus->getStore()->getParticlesforSrc();
G4int zz = theNucleus->getZ();
generateSrcPairsMethod(inside, theNucleus->getA() - zz, zz, particle1,
particle2);
if ((particle1->getSrcPair() > 0 || particle2->getSrcPair() > 0)) {
return new DeltaProductionChannel(particle1, particle2, theNucleus);
} else {
INCL_DEBUG("NN interaction: Delta channel chosen" << '\n');
theNucleus->resetSrc();
return new DeltaProductionChannel(particle1, particle2);
}
} else {
INCL_DEBUG("NN interaction: Delta channel chosen" << '\n');
weight = counterweight;
return new DeltaProductionChannel(particle1, particle2);
}
} else if(elasticCX + deltaProductionCX + onePiProductionCX > rChannel) {
isElastic = false;
// NN -> PiNN channel is chosen
@@ -948,8 +1055,10 @@ namespace G4INCL {
const G4double elasticCX = CrossSections::elastic(particle1, particle2);
const G4double onePiProductionCX = CrossSections::etaNToPiN(particle1, particle2);
const G4double twoPiProductionCX = CrossSections::etaNToPiPiN(particle1, particle2);
const G4double LKProductionCX = CrossSections::etaNToLK(particle1, particle2);
const G4double SKProductionCX = CrossSections::etaNToSK(particle1, particle2);
const G4double totCX=CrossSections::total(particle1, particle2);
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)<1.);
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)-LKProductionCX-SKProductionCX<1.);
const G4double rChannel=Random::shoot() * totCX;
@@ -968,11 +1077,29 @@ namespace G4INCL {
// EtaN -> EtaPiPiN channel is chosen
INCL_DEBUG("EtaN interaction: PiPiN channel chosen" << '\n');
return new EtaNToPiPiNChannel(particle1, particle2);
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX > rChannel) {
isElastic = false;
// EtaN -> LK channel is chosen
INCL_DEBUG("EtaN interaction: LK channel chosen" << '\n');
return new EtaOrOmegaNToLKChannel(particle1, particle2);
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX + SKProductionCX > rChannel) {
isElastic = false;
// EtaN -> SK channel is chosen
INCL_DEBUG("EtaN interaction: SK channel chosen" << '\n');
return new EtaOrOmegaNToSKChannel(particle1, particle2);
}
else {
INCL_WARN("inconsistency within the EtaN Cross Sections (sum!=inelastic)" << '\n');
if(twoPiProductionCX>0.) {
if(SKProductionCX>0.) {
INCL_WARN("Returning a SK channel" << '\n');
isElastic = false;
return new EtaOrOmegaNToSKChannel(particle1, particle2);
} else if(LKProductionCX>0.) {
INCL_WARN("Returning a LK channel" << '\n');
isElastic = false;
return new EtaOrOmegaNToLKChannel(particle1, particle2);
} else if(twoPiProductionCX>0.) {
INCL_WARN("Returning a PiPiN channel" << '\n');
isElastic = false;
return new EtaNToPiPiNChannel(particle1, particle2);
@@ -993,8 +1120,10 @@ namespace G4INCL {
const G4double elasticCX = CrossSections::elastic(particle1, particle2);
const G4double onePiProductionCX = CrossSections::omegaNToPiN(particle1, particle2);
const G4double twoPiProductionCX = CrossSections::omegaNToPiPiN(particle1, particle2);
const G4double LKProductionCX = CrossSections::omegaNToLK(particle1, particle2);
const G4double SKProductionCX = CrossSections::omegaNToSK(particle1, particle2);
const G4double totCX=CrossSections::total(particle1, particle2);
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)<1.);
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX + LKProductionCX + SKProductionCX)<1.);
const G4double rChannel=Random::shoot() * totCX;
@@ -1013,10 +1142,28 @@ namespace G4INCL {
// OmegaN -> PiPiN channel is chosen
INCL_DEBUG("OmegaN interaction: PiPiN channel chosen" << '\n');
return new OmegaNToPiPiNChannel(particle1, particle2);
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX > rChannel) {
isElastic = false;
// OmegaN -> LK channel is chosen
INCL_DEBUG("EtaN interaction: LK channel chosen" << '\n');
return new EtaOrOmegaNToLKChannel(particle1, particle2);
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX + SKProductionCX > rChannel) {
isElastic = false;
// OmegaN -> SK channel is chosen
INCL_DEBUG("EtaN interaction: SK channel chosen" << '\n');
return new EtaOrOmegaNToSKChannel(particle1, particle2);
}
else {
INCL_WARN("inconsistency within the OmegaN Cross Sections (sum!=inelastic)" << '\n');
if(twoPiProductionCX>0.) {
if(SKProductionCX>0.) {
INCL_WARN("Returning a SK channel" << '\n');
isElastic = false;
return new EtaOrOmegaNToSKChannel(particle1, particle2);
} else if(LKProductionCX>0.) {
INCL_WARN("Returning a LK channel" << '\n');
isElastic = false;
return new EtaOrOmegaNToLKChannel(particle1, particle2);
} else if(twoPiProductionCX>0.) {
INCL_WARN("Returning a PiPiN channel" << '\n');
isElastic = false;
return new OmegaNToPiPiNChannel(particle1, particle2);
@@ -1242,6 +1389,66 @@ namespace G4INCL {
}
} else if ((particle1->isNucleon() && particle2->isAntiNucleon()) || (particle2->isNucleon() && particle1->isAntiNucleon())) {
//// NNbar
//Forcing annihilationfor emitInsideAntinucleon at the end of cascade && annihilation if E <= M + p_threhsold (from antideuteron in generateBinaryCollisionAvatar())
/*const Particle *antinucleon;
const Particle *nucleon;
if (particle1->isAntiNucleon()) {
antinucleon = particle1;
nucleon = particle2;
}
else {
antinucleon = particle2;
nucleon = particle1;
}
double Esquared = antinucleon->getEnergy() * antinucleon->getEnergy();
double antinucleon_threshold=0;
if(antinucleon->getType()==antiNeutron)
antinucleon_threshold = theNucleus->getStore()->getConfig()->getnbAtrestThreshold();
else if(antinucleon->getType() == antiProton)
antinucleon_threshold = theNucleus->getStore()->getConfig()->getAtrestThreshold();
else
INCL_ERROR("neither antiproton nor antineutron");*/
//double Sum_at_rest = antinucleon->getINCLMass() * antinucleon->getINCLMass() + antinucleon_threshold*antinucleon_threshold;
// Force the annihilation when T < Threshold (at rest)
//Config const *theConfig=theNucleus->getStore()->getConfig();
if ((theCrossSection == 9999.) || // XS=9999. means force annihilation
((particle1->getType()==antiProton && particle1->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
(particle2->getType()==antiProton && particle2->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
(particle1->getType()==antiNeutron && particle1->getKineticEnergy() <= particle1->getPotentialEnergy()) ||
(particle2->getType()==antiNeutron && particle2->getKineticEnergy() <= particle2->getPotentialEnergy())) ||
((particle1->getType()==antiProton && particle1->getEnergy() <= particle1->getINCLMass()) ||
(particle2->getType()==antiProton && particle2->getEnergy() <= particle2->getINCLMass()) ||
(particle1->getType()==antiNeutron && particle1->getEnergy() <= particle1->getINCLMass()) ||
(particle2->getType()==antiNeutron && particle2->getEnergy() <= particle2->getINCLMass())))
{
isElastic = false;
AnnihilationType atype0;
if((particle1->getType()==antiProton && particle2->getType()==Proton) || (particle2->getType()==antiProton && particle1->getType()==Proton)){
atype0 = PTypeInFlight;
}
else if((particle1->getType()==antiProton && particle2->getType()==Neutron) || (particle2->getType()==antiProton && particle1->getType()==Neutron)){
atype0 = NTypeInFlight;
}
else if((particle1->getType()==antiNeutron && particle2->getType()==Proton) || (particle2->getType()==antiNeutron && particle1->getType()==Proton)){
atype0 = NbarPTypeInFlight;
}
else if((particle1->getType()==antiNeutron && particle2->getType()==Neutron) || (particle2->getType()==antiNeutron && particle1->getType()==Neutron)){
atype0 = NbarNTypeInFlight;
}
else{
atype0 = Def;
INCL_ERROR("Annihilation type problem " << '\n');
}
theNucleus->setAType(atype0);
return new NNbarToAnnihilationChannel(theNucleus, particle1, particle2);
}
//delete antinucleon;
//delete nucleon;
// Usual interactions
const G4double totCX = CrossSections::total(particle1, particle2);
const G4double NNbElasticCX = CrossSections::NNbarElastic(particle1,particle2);
const G4double NNbCEXCX = CrossSections::NNbarCEX(particle1,particle2);
@@ -47,6 +47,8 @@
#include "G4INCLNuclearMassTable.hh"
#include "G4INCLGlobalInfo.hh"
#include "G4INCLNucleus.hh"
#include "G4INCLDecayAvatar.hh"
#include "G4INCLStore.hh"
#include "G4INCLPauliBlocking.hh"
@@ -191,7 +193,7 @@ namespace G4INCL {
<< "Target configuration rejected." << '\n');
return false;
}
if(projectileSpecies.theType==Composite &&
if((projectileSpecies.theType==Composite || projectileSpecies.theType == antiComposite)&&
(projectileSpecies.theZ==projectileSpecies.theA || projectileSpecies.theZ==0)) {
INCL_ERROR("Unsupported projectile: A = " << projectileSpecies.theA << " Z = " << projectileSpecies.theZ << " S = " << projectileSpecies.theS << '\n'
<< "Projectile configuration rejected." << '\n');
@@ -209,12 +211,23 @@ namespace G4INCL {
//reset
G4bool ProtonIsTheVictim = false;
G4bool NeutronIsTheVictim = false;
G4bool DNbProtonIsTheVictim = false;
G4bool DPbProtonIsTheVictim = false;
theEventInfo.annihilationP = false;
theEventInfo.annihilationN = false;
G4bool isModelA = true; //Antideuteron
//G4double AnnihilationBarrier = kineticEnergy;
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){
G4double SpOverSn = 1.331;//from experiments with deuteron (E.Klempt)
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType == antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())){
double SpOverSn;
if(projectileSpecies.theType == antiProton)
SpOverSn = 1.331;//from experiments with deuteron (E.Klempt)
else if(projectileSpecies.theType == antiNeutron)
SpOverSn = 1./1.331; //Opposite for antineutron
else{
SpOverSn = 1;
INCL_ERROR("Neither antiProton nor antiNeutron annihilated");
}
//INCL_WARN("theA number set to A-1 from " << A <<'\n');
G4double neutronprob;
@@ -241,8 +254,78 @@ namespace G4INCL {
theZ = Z;
NeutronIsTheVictim = true;
}
} else if(projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()){
if(Z > 30)
isModelA=false;
else if(Z > 9 && Z <=30){ //Maybe change and add another dependance than Z
double rndmA = Random::shoot();
if(rndmA > 0.5)//Random threshold : should be improved to take into account the orbit in which the separation takes place.
isModelA=false;
}
if(isModelA){
//Antideuteron Model A case : 2 annihilation at the same time
double pbarSpOverSn = 1.331;
double nbarSpOverSn = 1./1.331;
double pbarneutronprob;
double nbarneutronprob;
if(theConfig->isNaturalTarget()){
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 2;
nbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + nbarSpOverSn*Z);
pbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + pbarSpOverSn*Z);
}
else{
theA = A - 2;
nbarneutronprob = (A - Z)/(A - Z + nbarSpOverSn*Z);
pbarneutronprob = (A - Z)/(A - Z + pbarSpOverSn*Z);
}
else{ // not annihilation of pbar
theS = S;
G4double rndm = Random::shoot(); //for nbar
G4double rndm2 = Random::shoot(); //for pbar
if (rndm >= nbarneutronprob){ // nbarp
DNbProtonIsTheVictim = true;
if(rndm2 >= pbarneutronprob){ // pbarp
theZ = Z - 2;
DPbProtonIsTheVictim = true;
} else if(rndm2 < pbarneutronprob){ //pbarn
theZ = Z - 1;
}
} else if(rndm < nbarneutronprob){//nbarn
if(rndm2 >= pbarneutronprob){ // pbarp
theZ = Z - 1;
DPbProtonIsTheVictim = true;
} else if(rndm2 < pbarneutronprob){ //pbarn
theZ = Z;
}
}
} else if (!isModelA){//Model B : Antiproton is detached from antideuteron
double SpOverSn = 1.331;
double neutronprob;
if(theConfig->isNaturalTarget()){
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 1;
neutronprob = (theA + 1 - Z)/(theA + 1 - Z + SpOverSn*Z);
}
else{
theA = A - 1;
neutronprob = (A - Z)/(A - Z + SpOverSn*Z);
}
theS = S;
double rndm = Random::shoot();
if(rndm >= neutronprob){ //proton is annihilated
theEventInfo.annihilationP = true;
theZ = Z - 1;
ProtonIsTheVictim = true;
}
else{ //neutron is annihilated
theEventInfo.annihilationN = true;
theZ = Z;
NeutronIsTheVictim = true;
}
}
}
else{ // not annihilation of pbar, nbar, dbar
theZ = Z;
theS = S;
if(theConfig->isNaturalTarget())
@@ -256,6 +339,21 @@ namespace G4INCL {
theAType = PType;
if(NeutronIsTheVictim == true && ProtonIsTheVictim == false)
theAType = NType;
if(projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && isModelA){
if(DNbProtonIsTheVictim == true && DPbProtonIsTheVictim ==true)
theAType = DNbarPPbarPType;
else if(DNbProtonIsTheVictim == false && DPbProtonIsTheVictim ==true)
theAType = DNbarNPbarPType;
else if(DNbProtonIsTheVictim == false && DPbProtonIsTheVictim == false)
theAType = DNbarNPbarNType;
else if(DNbProtonIsTheVictim == true && DPbProtonIsTheVictim ==false)
theAType = DNbarPPbarNType;
} else if (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && !isModelA){
if(ProtonIsTheVictim == true && NeutronIsTheVictim == false)
theAType = PType;
if(NeutronIsTheVictim == true && ProtonIsTheVictim == false)
theAType = NType;
}
//D
@@ -268,7 +366,8 @@ namespace G4INCL {
// For forced CN events
initMaxInteractionDistance(projectileSpecies, kineticEnergy);
// Set the geometric cross sectiony section
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType == antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
|| (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
G4int currentA = A;
if(theConfig->isNaturalTarget()){
currentA = ParticleTable::drawRandomNaturalIsotope(Z);
@@ -296,10 +395,13 @@ namespace G4INCL {
G4bool INCL::initializeTarget(const G4int A, const G4int Z, const G4int S, AnnihilationType theAType) {
delete nucleus;
if (theAType==PType || theAType==NType) {
if (theAType==PType || theAType==NType || theAType==DNbarNPbarPType || theAType==DNbarNPbarNType ||theAType==DNbarPPbarPType || theAType==DNbarPPbarNType) {
G4double newmaxUniverseRadius=0.;
if (theAType==PType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z+1);
else newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z);
else if (theAType==NType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z);
else if (theAType==DNbarPPbarPType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z+2);
else if (theAType==DNbarNPbarNType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z);
else if (theAType==DNbarNPbarPType || theAType==DNbarPPbarNType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z+1);
nucleus = new Nucleus(A, Z, S, theConfig, newmaxUniverseRadius, theAType);
}
else{
@@ -358,9 +460,12 @@ namespace G4INCL {
}
const G4String& dataPath0(G4FindDataDir("G4INCLDATA"));
const G4String& dataPathppbar(dataPath0 + "/rawppbarFS.dat");
// const G4String& dataPathnpbar(dataPath0 + "/rawnpbarFS.dat"); // NOT used!
const G4String& dataPathnpbar(dataPath0 + "/rawnpbarFS.dat");
const G4String& dataPathppbark(dataPath0 + "/rawppbarFSkaonic.dat");
// const G4String& dataPathnpbark(dataPath0 + "/rawnpbarFSkaonic.dat"); // NOT used!
const G4String& dataPathnpbark(dataPath0 + "/rawnpbarFSkaonic.dat");
const G4String dataPathnbarp(dataPath0 + "/rawnbarpFS.dat");
const G4String dataPathnbarn(dataPath0 + "/rawnbarnFS.dat");
#else
std::string path;
if (theConfig) path = theConfig->getINCLXXDataFilePath();
@@ -372,6 +477,13 @@ namespace G4INCL {
INCL_DEBUG("Reading https://doi.org/10.1016/j.physrep.2005.03.002 ppbar kaonic final states" << dataPathppbark << '\n');
const std::string& dataPathnpbark(path + "/rawnpbarFSkaonic.dat");
INCL_DEBUG("Reading https://doi.org/10.1007/BF02818764 and https://link.springer.com/article/10.1007/BF02754930 npbar kaonic final states" << dataPathnpbark << '\n');
const std::string& dataPathnbarp(path + "/rawnnbarpFS.dat ");
INCL_DEBUG("Reading nbarp final states" << dataPathnbarp << '\n');
const std::string& dataPathnbarpk(path + "/rawnbarpFSkaonic.dat");
INCL_DEBUG("Reading nbarp kaonic final states");
const std::string& dataPathnbarn(path + "/rawnbarnFS.dat");
INCL_DEBUG("Reading nbarn final states" << dataPathnbarn << '\n');
#endif
//read probabilities and particle types from file
@@ -387,7 +499,10 @@ namespace G4INCL {
ThreeVector annihilationPosition(0.,0.,0.);
if (rdm < (1.-kaonicFSprob)) { // pionic FS was chosen
INCL_DEBUG("pionic pp final state chosen" << '\n');
sum = read_file(dataPathppbar, probabilities, particle_types);
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathppbar, probabilities, particle_types);}
else
{sum = read_file(dataPathnpbar, probabilities, particle_types);}
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
@@ -441,7 +556,10 @@ namespace G4INCL {
}
} else {
INCL_DEBUG("kaonic pp final state chosen" << '\n');
sum = read_file(dataPathppbark, probabilities, particle_types);
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathppbark, probabilities, particle_types);}
else
{sum = read_file(dataPathnpbark, probabilities, particle_types);}
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
@@ -493,7 +611,7 @@ namespace G4INCL {
}
//compute energies of mesons with a phase-space model
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton);
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton)+kineticEnergy;
if (starlist.size() < 2) {
INCL_ERROR("should never happen, at least 2 final state particles!" << '\n');
} else if (starlist.size() == 2) {
@@ -517,7 +635,210 @@ namespace G4INCL {
theGlobalInfo.nShots++;
return theEventInfo;
} // pbar on H1
} // pbar on H1/H2
if ((projectileSpecies.theType==antiNeutron)&& (targetA==1 || targetA==2) && targetZ==1 && targetS==0) {
if (targetA==1) {
preCascade_nbarH1(projectileSpecies, kineticEnergy);
} else {
preCascade_nbarH2(projectileSpecies, kineticEnergy);
theEventInfo.annihilationP = false;
theEventInfo.annihilationN = false;
G4double SpOverSn = 1./1.331; //from experiments with deuteron (E.Klempt)
ThreeVector dummy(0.,0.,0.);
double rndm = Random::shoot()*(SpOverSn+1);
if (rndm <= SpOverSn) { //proton is annihilated
theEventInfo.annihilationP = true;
Particle *p2 = new Particle(Neutron, dummy, dummy);
starlistH2.push_back(p2);
//delete p2;
} else { //neutron is annihilated
theEventInfo.annihilationN = true;
Particle *p2 = new Particle(Proton, dummy, dummy);
starlistH2.push_back(p2);
//delete p2;
}
}
// File names
#ifdef INCLXX_IN_GEANT4_MODE
if (!G4FindDataDir("G4INCLDATA") ) {
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4INCLDATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the INCL++ model" << G4endl;
G4Exception("G4INCLDataFile::readData()","rawpnbarFS.dat, ...", FatalException, ed);
}
G4String dataPath0{G4FindDataDir("G4INCLDATA")};
G4String dataPathnbarp(dataPath0 + "/rawnbarpFS.dat");
G4String dataPathnbarn(dataPath0 + "/rawnbarnFS.dat");
G4String dataPathnbarnk(dataPath0 + "/rawppbarFSkaonic.dat");
G4String dataPathnbarpk(dataPath0 + "/rawnbarpFSkaonic.dat");
#else
G4String path;
if (theConfig) path = theConfig->getINCLXXDataFilePath();
std::string dataPathnbarn(path + "/rawnbarnFS.dat");
INCL_DEBUG("Reading nbarn final states" << dataPathnbarn << '\n');
std::string dataPathnbarp(path + "/rawnbarpFS.dat");
INCL_DEBUG("Reading nbarp final states" << dataPathnbarp << '\n');
std::string dataPathnbarnk(path + "/rawppbarFSkaonic.dat");
INCL_DEBUG("Reading nbarn kaonic final states" << dataPathnbarnk << '\n');
std::string dataPathnbarpk(path + "/rawnbarpFSkaonic.dat");
INCL_DEBUG("Reading nbarp kaonic final states" << dataPathnbarpk << '\n');
#endif
//read probabilities and particle types from file
std::vector<double> probabilities; //will store each FS yield
std::vector<std::vector<G4String>> particle_types; //will store particle names
double sum = 0.0; //will contain a sum of probabilities of all FS in the file
double kaonicFSprob=0.05; //probability to kave kaonic FS
ParticleList starlist;
ThreeVector mommy; //momentum to be assigned later
double rdm = Random::shoot();
ThreeVector annihilationPosition(0.,0.,0.);
if (rdm < (1.-kaonicFSprob)) { // pionic FS was chosen
INCL_DEBUG("pionic nn final state chosen" << '\n');
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathnbarp, probabilities, particle_types);}
else
{sum = read_file(dataPathnbarn, probabilities, particle_types);}
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return theEventInfo;
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
if (particle_types[n][j] == "pi0") {
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "pi-") {
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "pi+") {
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "omega") {
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "eta") {
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "rho-") {
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
} else if (particle_types[n][j] == "rho+") {
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
} else if (particle_types[n][j] == "rho0") {
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(pp);
} else {
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
#else
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
#endif
}
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "Some non-existing FS particle detected when reading pbar FS files" << G4endl;
#else
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
#endif
}
}
} else {
INCL_DEBUG("kaonic pp final state chosen" << '\n');
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathnbarpk, probabilities, particle_types);}
else
{sum = read_file(dataPathnbarnk, probabilities, particle_types);}
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return theEventInfo;
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
if (particle_types[n][j] == "pi0") {
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "pi-") {
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "pi+") {
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "omega") {
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "eta") {
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "K-") {
Particle *p = new Particle(KMinus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "K+") {
Particle *p = new Particle(KPlus, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "K0") {
Particle *p = new Particle(KZero, mommy, annihilationPosition);
starlist.push_back(p);
} else if (particle_types[n][j] == "K0b") {
Particle *p = new Particle(KZeroBar, mommy, annihilationPosition);
starlist.push_back(p);
} else {
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
#else
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
#endif
}
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "Some non-existing FS particle detected when reading pbar FS files" << G4endl;
#else
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
#endif
}
}
}
//compute energies of mesons with a phase-space model
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton)+kineticEnergy;
if (starlist.size() < 2) {
INCL_ERROR("should never happen, at least 2 final state particles!" << '\n');
} else if (starlist.size() == 2) {
ParticleIter first = starlist.begin();
ParticleIter last = std::next(first, 1);
G4double m1 = (*first)->getMass();
G4double m2 = (*last)->getMass();
G4double s = energyOfMesonStar*energyOfMesonStar;
G4double mom1 = std::sqrt(s/4. - (std::pow(m1,2) + std::pow(m2,2))/2. - std::pow(m1,2)*std::pow(m2,2)/s + (std::pow(m1,4) + 2.*std::pow(m1*m2,2) + std::pow(m2,4))/(4.*s));
ThreeVector momentello = Random::normVector(mom1);
(*first)->setMomentum(momentello);
(*first)->adjustEnergyFromMomentum();
(*last)->setMomentum(-momentello);
(*last)->adjustEnergyFromMomentum();
} else {
PhaseSpaceGenerator::generate(energyOfMesonStar, starlist);
}
if (targetA==1) postCascade_pbarH1(starlist);
else postCascade_pbarH2(starlist,starlistH2);
theGlobalInfo.nShots++;
return theEventInfo;
} // nbar on H1/H2
// ReInitialize the bias vector
Particle::INCLBiasVector.clear();
@@ -569,6 +890,22 @@ namespace G4INCL {
theEventInfo.At = (Short_t)nucleus->getA()+1;
theEventInfo.Zt = (Short_t)nucleus->getZ();
}
else if(nucleus->getAnnihilationType()==DNbarNPbarNType ){
theEventInfo.annihilationN = true;
theEventInfo.At = (Short_t)nucleus->getA()+2;
theEventInfo.Zt = (Short_t)nucleus->getZ();
}
else if(nucleus->getAnnihilationType()==DNbarPPbarPType ){
theEventInfo.annihilationP = true;
theEventInfo.At = (Short_t)nucleus->getA()+2;
theEventInfo.Zt = (Short_t)nucleus->getZ()+2;
}
else if(nucleus->getAnnihilationType()==DNbarPPbarNType || nucleus->getAnnihilationType()==DNbarNPbarPType ){
theEventInfo.annihilationN = true;
theEventInfo.annihilationP = true;
theEventInfo.At = (Short_t)nucleus->getA()+2;
theEventInfo.Zt = (Short_t)nucleus->getZ()+1;
}
else {
theEventInfo.At = (Short_t)nucleus->getA();
theEventInfo.Zt = (Short_t)nucleus->getZ();
@@ -578,7 +915,8 @@ namespace G4INCL {
// Fill in the event information
//Particle *pbar = new Particle;
//PbarAtrestEntryChannel *obj = new PbarAtrestEntryChannel(nucleus, pbar);
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){ //D
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType==antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
|| (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){ //D
INCL_DEBUG("at rest annihilation" << '\n');
//theEventInfo.transparent = false;
} else {
@@ -671,7 +1009,8 @@ namespace G4INCL {
theEventInfo.eventBias = (Double_t) Particle::getTotalBias();
// Forced CN?
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold())){
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType == antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
&& !(projectileSpecies.theType==antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
if(nucleus->getTryCompoundNucleus()) {
INCL_DEBUG("Trying compound nucleus" << '\n');
makeCompoundNucleus();
@@ -684,7 +1023,8 @@ namespace G4INCL {
}
}
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold())){
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType == antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
&& !(projectileSpecies.theType==antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){
theEventInfo.transparent = forceTransparent || nucleus->isEventTransparent();
}
@@ -698,6 +1038,13 @@ namespace G4INCL {
nucleus->getStore()->deleteIncoming();
}
} else {
//Check if the nucleus contains antinucleons
theEventInfo.antinucleonsInside = nucleus->containsAntinucleon();
//Annihilate antiparticles still inside the nucleus & emit the resulting particles
if(nucleus->containsAntinucleon())
theEventInfo.emitAntinucleon = nucleus->emitInsideAnnihilationProducts();
if(nucleus->containsAntilambda())
theEventInfo.emitAntilambda = nucleus->emitInsideAntilambda();
// Check if the nucleus contains strange particles
theEventInfo.sigmasInside = nucleus->containsSigma();
@@ -986,7 +1333,8 @@ namespace G4INCL {
pTransThreshold = 0.1; // MeV/c
}
if(std::abs(theBalance.energy)>EThreshold) {
INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " Emit Lambda=" << theEventInfo.emitLambda << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " Emit Lambda=" << theEventInfo.emitLambda << " afterRecoil = " << afterRecoil << " SRCevent ="
<< nucleus->getStore()->getBook().getAcceptedSrcCollisions()<< " eventNumber=" << theEventInfo.eventNumber << '\n');
}
if(std::abs(pLongBalance)>pLongThreshold) {
INCL_WARN("Violation of longitudinal momentum conservation > " << pLongThreshold << " MeV/c. pLongBalance = " << pLongBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
@@ -1023,6 +1371,12 @@ namespace G4INCL {
<< "), stopping cascade" << '\n');
return false;
}
if((nucleus->getZ() <= 2) && (propagationModel->getCurrentTime() != 0)) {
INCL_DEBUG("Remnant size (" << nucleus->getZ()
<< ") smaller than or equal to minimum (" << "2"
<< "), stopping cascade" << '\n');
return false;
}
// Stop if we have to try and make a compound nucleus or if we have to
// force a transparent
if(nucleus->getTryCompoundNucleus()) {
@@ -1098,19 +1452,29 @@ namespace G4INCL {
}
void INCL::initMaxInteractionDistance(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
if(projectileSpecies.theType != Composite) {
if(projectileSpecies.theType != Composite && projectileSpecies.theType != antiComposite) {
maxInteractionDistance = 0.;
return;
}
const G4double r0 = std::max(ParticleTable::getNuclearRadius(Proton, theA, theZ),
ParticleTable::getNuclearRadius(Neutron, theA, theZ));
if (projectileSpecies.theType == Composite){
const G4double theNNDistance = CrossSections::interactionDistanceNN(projectileSpecies, kineticEnergy);
maxInteractionDistance = r0 + theNNDistance;
INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
<< " theNNDistance = " << theNNDistance << '\n'
<< " maxInteractionDistance = " << maxInteractionDistance << '\n');
}
else if (projectileSpecies.theType == antiComposite){
const G4double theNbarNDistance = CrossSections::interactionDistanceNbarN(projectileSpecies, kineticEnergy);
maxInteractionDistance = r0 + theNbarNDistance;
INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
<< " theNbarNDistance = " << theNbarNDistance << '\n'
<< " maxInteractionDistance = " << maxInteractionDistance << '\n');
}
}
void INCL::initUniverseRadius(ParticleSpecies const &p, const G4double kineticEnergy, const G4int A, const G4int Z) {
@@ -1156,6 +1520,12 @@ namespace G4INCL {
}
else if(p.theType==antiProton) {
maxUniverseRadius = rMax; //check interaction distance!!!
} else if (p.theType==antiNeutron){
const G4double interactionDistancenbarN = CrossSections::interactionDistancenbarN(p,kineticEnergy);
maxUniverseRadius = rMax+ interactionDistancenbarN;
} else if (p.theType==antiComposite){
const G4double interactionDistanceNbarN = CrossSections::interactionDistanceNbarN(p,kineticEnergy);
maxUniverseRadius =rMax + interactionDistanceNbarN;
}
INCL_DEBUG("Initialised universe radius: " << maxUniverseRadius << '\n');
}
@@ -1284,15 +1654,100 @@ namespace G4INCL {
theEventInfo.Zt = 1;
}
void INCL::preCascade_nbarH1(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
// Reset theEventInfo
theEventInfo.reset();
EventInfo::eventNumber++;
// Fill in the event information
theEventInfo.projectileType = projectileSpecies.theType;
theEventInfo.Ap = -1;
theEventInfo.Zp = 0;
theEventInfo.Sp = 0;
theEventInfo.Ep = kineticEnergy;
theEventInfo.St = 0;
theEventInfo.At = 1;
theEventInfo.Zt = 1;
}
void INCL::postCascade_pbarH1(ParticleList const &outgoingParticles) {
theEventInfo.nParticles = 0;
ParticleList outgoingParticles2;
// Reset the remnant counter
theEventInfo.nRemnants = 0;
theEventInfo.history.clear();
// Decay eta and omega
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
if( (*i)->isEta() || (*i)->isOmega() ) {
INCL_DEBUG("Decay outgoing eta/omega particle:" << '\n'
<< (*i)->print() << '\n');
const ThreeVector beta = -(*i)->boostVector();
const G4double pionResonanceMass = (*i)->getMass();
// Set the pionResonance momentum to zero and sample the decay in the CM frame.
// This makes life simpler if we are using real particle masses.
(*i)->setMomentum(ThreeVector());
(*i)->setEnergy((*i)->getMass());
// Use a DecayAvatar
IAvatar *decay = new DecayAvatar((*i), 0.0, NULL);
FinalState *fs = decay->getFinalState();
Particle * const theModifiedParticle = fs->getModifiedParticles().front();
ParticleList const &created = fs->getCreatedParticles();
Particle * const theCreatedParticle1 = created.front();
if (created.size() == 1) {
// Adjust the decay momentum if we are using the real masses
const G4double decayMomentum = KinematicsUtils::momentumInCM(pionResonanceMass,theModifiedParticle->getTableMass(),theCreatedParticle1->getTableMass());
ThreeVector newMomentum = theCreatedParticle1->getMomentum();
newMomentum *= decayMomentum / newMomentum.mag();
theCreatedParticle1->setTableMass();
theCreatedParticle1->setMomentum(newMomentum);
theCreatedParticle1->adjustEnergyFromMomentum();
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theModifiedParticle->setTableMass();
theModifiedParticle->setMomentum(-newMomentum);
theModifiedParticle->adjustEnergyFromMomentum();
theModifiedParticle->boost(beta);
outgoingParticles2.push_back(theCreatedParticle1);
outgoingParticles2.push_back(theModifiedParticle);
}
else if (created.size() == 2) {
Particle * const theCreatedParticle2 = created.back();
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle2->boost(beta);
theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
theModifiedParticle->boost(beta);
outgoingParticles2.push_back(theCreatedParticle1);
outgoingParticles2.push_back(theCreatedParticle2);
outgoingParticles2.push_back(theModifiedParticle);
}
else {
INCL_ERROR("Wrong number (< 2) of created particles during the decay of a pion resonance");
}
delete fs;
delete decay;
}
else {
outgoingParticles2.push_back(*i);
}
}// End of Decay eta and omega
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
for(ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
theEventInfo.A[theEventInfo.nParticles] = (Short_t)(*i)->getA();
theEventInfo.Z[theEventInfo.nParticles] = (Short_t)(*i)->getZ();
theEventInfo.S[theEventInfo.nParticles] = (Short_t)(*i)->getS();
@@ -1334,15 +1789,101 @@ namespace G4INCL {
theEventInfo.Zt = 1;
}
void INCL::preCascade_nbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
// Reset theEventInfo
theEventInfo.reset();
EventInfo::eventNumber++;
// Fill in the event information
theEventInfo.projectileType = projectileSpecies.theType;
theEventInfo.Ap = -1;
theEventInfo.Zp = 0;
theEventInfo.Sp = 0;
theEventInfo.Ep = kineticEnergy;
theEventInfo.St = 0;
theEventInfo.At = 2;
theEventInfo.Zt = 1;
}
void INCL::postCascade_pbarH2(ParticleList const &outgoingParticles, ParticleList const &H2Particles) {
theEventInfo.nParticles = 0;
ParticleList outgoingParticles2;
// Reset the remnant counter
theEventInfo.nRemnants = 0;
theEventInfo.history.clear();
// Decay eta and omega
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
if( (*i)->isEta() || (*i)->isOmega() ) {
INCL_DEBUG("Decay outgoing eta/omega particle:" << '\n'
<< (*i)->print() << '\n');
const ThreeVector beta = -(*i)->boostVector();
const G4double pionResonanceMass = (*i)->getMass();
// Set the pionResonance momentum to zero and sample the decay in the CM frame.
// This makes life simpler if we are using real particle masses.
(*i)->setMomentum(ThreeVector());
(*i)->setEnergy((*i)->getMass());
// Use a DecayAvatar
IAvatar *decay = new DecayAvatar((*i), 0.0, NULL);
FinalState *fs = decay->getFinalState();
Particle * const theModifiedParticle = fs->getModifiedParticles().front();
ParticleList const &created = fs->getCreatedParticles();
Particle * const theCreatedParticle1 = created.front();
if (created.size() == 1) {
// Adjust the decay momentum if we are using the real masses
const G4double decayMomentum = KinematicsUtils::momentumInCM(pionResonanceMass,theModifiedParticle->getTableMass(),theCreatedParticle1->getTableMass());
ThreeVector newMomentum = theCreatedParticle1->getMomentum();
newMomentum *= decayMomentum / newMomentum.mag();
theCreatedParticle1->setTableMass();
theCreatedParticle1->setMomentum(newMomentum);
theCreatedParticle1->adjustEnergyFromMomentum();
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theModifiedParticle->setTableMass();
theModifiedParticle->setMomentum(-newMomentum);
theModifiedParticle->adjustEnergyFromMomentum();
theModifiedParticle->boost(beta);
outgoingParticles2.push_back(theCreatedParticle1);
outgoingParticles2.push_back(theModifiedParticle);
}
else if (created.size() == 2) {
Particle * const theCreatedParticle2 = created.back();
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle2->boost(beta);
theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
theModifiedParticle->boost(beta);
outgoingParticles2.push_back(theCreatedParticle1);
outgoingParticles2.push_back(theCreatedParticle2);
outgoingParticles2.push_back(theModifiedParticle);
}
else {
INCL_ERROR("Wrong number (< 2) of created particles during the decay of a pion resonance");
}
delete fs;
delete decay;
}
else {
outgoingParticles2.push_back(*i);
}
}// End of Decay eta and omega
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
for(ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
theEventInfo.A[theEventInfo.nParticles] = (Short_t)(*i)->getA();
theEventInfo.Z[theEventInfo.nParticles] = (Short_t)(*i)->getZ();
theEventInfo.S[theEventInfo.nParticles] = (Short_t)(*i)->getS();
@@ -41,7 +41,7 @@
namespace G4INCL {
void Cluster::initializeParticles() {
// assert(theA>=2);
// assert(theA>=2 || theA<=-2);
const ThreeVector oldPosition = thePosition;
theParticleSampler->sampleParticlesIntoList(thePosition, particles);
#if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
@@ -57,6 +57,10 @@ namespace G4INCL {
ParticleEntryAvatar *bringToSurface(Particle *p, Nucleus * const n) {
return theCoulomb->bringToSurface(p, n);
}
ParticleEntryAvatar *bringToSurfaceAbar(Particle *p, Nucleus * const n) {
return theCoulomb->bringToSurfaceAbar(p, n);
}
IAvatarList bringToSurface(Cluster * const c, Nucleus * const n) {
return theCoulomb->bringToSurface(c, n);
@@ -59,6 +59,19 @@ namespace G4INCL {
// and actually bring the particle to the surface of the nucleus
return theCoulombNoneSlave.bringToSurface(p,n);
}
ParticleEntryAvatar *CoulombNonRelativistic::bringToSurfaceAbar(Particle * const p, Nucleus * const n) const {
// No distortion for neutral particles
if(p->getZ()!=0) {
const G4bool success = coulombDeviation(p, n);
if(!success) // transparent
return NULL;
}
// Rely on the CoulombNone slave to compute the straight-line intersection
// and actually bring the particle to the surface of the nucleus
return theCoulombNoneSlave.bringToSurfaceAbar(p,n);
}
IAvatarList CoulombNonRelativistic::bringToSurface(Cluster * const c, Nucleus * const n) const {
// Neutral clusters?!
@@ -125,8 +138,12 @@ namespace G4INCL {
Nucleus const * const n) const {
const G4double theMinimumDistance = minimumDistance(p, kinE, n);
G4double rMax = n->getUniverseRadius();
if(p.theType == Composite)
if(p.theType == Composite){
rMax += 2.*ParticleTable::getLargestNuclearRadius(p.theA, p.theZ);
}
if (p.theType == antiComposite){
rMax += 2.*ParticleTable::getLargestNuclearRadius(-(p.theA), -(p.theZ));
}
const G4double theMaxImpactParameterSquared = rMax*(rMax-theMinimumDistance);
if(theMaxImpactParameterSquared<=0.)
return 0.;
@@ -194,12 +211,16 @@ namespace G4INCL {
}
G4double CoulombNonRelativistic::getCoulombRadius(ParticleSpecies const &p, Nucleus const * const n) const {
if(p.theType == Composite) {
const G4int Zp = p.theZ;
const G4int Ap = p.theA;
if(p.theType == Composite || p.theType == antiComposite) {
G4int Zp = p.theZ;
G4int Ap = p.theA;
const G4int Zt = n->getZ();
const G4int At = n->getA();
G4double barr, radius = 0.;
if(p.theType == antiComposite){
Zp = -Zp;
Ap = -Ap;
}
if(Zp==1 && Ap==2) { // d
barr = 0.2565*Math::pow23((G4double)At)-0.78;
radius = PhysicalConstants::eSquared*Zp*Zt/barr - 2.5;
@@ -55,6 +55,15 @@ namespace G4INCL {
} else // If the particle does NOT enter the nucleus
return NULL;
}
ParticleEntryAvatar *CoulombNone::bringToSurfaceAbar(Particle * const p, Nucleus * const n) const {
Intersection intersection = IntersectionFactory::getEarlierTrajectoryIntersection(p->getPosition(), p->getPropagationVelocity(), n->getUniverseRadius());
if(intersection.exists) { // If the particle enters the nucleus
p->setPosition(intersection.position);
return new ParticleEntryAvatar(0.001, n, p);
} else // If the particle does NOT enter the nucleus
return NULL;
}
IAvatarList CoulombNone::bringToSurface(Cluster * const c, Nucleus * const n) const {
// The avatar list that we will return
@@ -101,6 +101,14 @@ namespace G4INCL {
G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2) {
return theCrossSections->etaNToPiPiN(p1,p2);
}
G4double etaNToLK(Particle const * const p1, Particle const * const p2) {
return theCrossSections->etaNToLK(p1,p2);
}
G4double etaNToSK(Particle const * const p1, Particle const * const p2) {
return theCrossSections->etaNToSK(p1,p2);
}
G4double omegaNToPiN(Particle const * const p1, Particle const * const p2) {
return theCrossSections->omegaNToPiN(p1,p2);
@@ -109,6 +117,14 @@ namespace G4INCL {
G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2) {
return theCrossSections->omegaNToPiPiN(p1,p2);
}
G4double omegaNToLK(Particle const * const p1, Particle const * const p2) {
return theCrossSections->omegaNToLK(p1,p2);
}
G4double omegaNToSK(Particle const * const p1, Particle const * const p2) {
return theCrossSections->omegaNToSK(p1,p2);
}
G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2) {
return theCrossSections->etaPrimeNToPiN(p1,p2);
@@ -225,7 +241,7 @@ namespace G4INCL {
return theCrossSections->p_pimToSzKz(p1,p2);
}
G4double p_pizToSzKp(Particle const * const p1, Particle const * const p2) {
G4double p_pizToSzKp(Particle const * const p1, Particle const * const p2) {
return theCrossSections->p_pizToSzKp(p1,p2);
}
@@ -397,6 +413,64 @@ namespace G4INCL {
return interactionDistance;
}
G4double interactionDistanceNbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy) {
// assert(aSpecies.theType==antiComposite);
// assert(aSpecies.theA<0);
ThreeVector nullVector;
ThreeVector unitVector(0.,0.,1.);
const G4double kineticEnergyPerNucleon = kineticEnergy / (-aSpecies.theA);
Particle antiprotonProjectile(antiProton, unitVector, nullVector);
antiprotonProjectile.setEnergy(antiprotonProjectile.getMass()+kineticEnergyPerNucleon);
antiprotonProjectile.adjustMomentumFromEnergy();
Particle antineutronProjectile(antiNeutron, unitVector, nullVector);
antineutronProjectile.setEnergy(antineutronProjectile.getMass()+kineticEnergyPerNucleon);
antineutronProjectile.adjustMomentumFromEnergy();
Particle protonTarget(Proton, nullVector, nullVector);
Particle neutronTarget(Neutron, nullVector, nullVector);
const double sigmapbarp = total(&antiprotonProjectile, &protonTarget);
const double sigmapbarn = total(&antiprotonProjectile, &neutronTarget);
const double sigmanbarn = total(&antineutronProjectile, &neutronTarget);
const double sigmanbarp = total(&antineutronProjectile, &protonTarget);
/* We compute the interaction distance from the largest of the NN cross
* sections. Note that this is different from INCL4.6, which just takes the
* average of the four, and will in general lead to a different geometrical
* cross section.
*/
const G4double largestSigma = std::max(std::max(sigmapbarp,sigmapbarn), std::max(sigmanbarn,sigmanbarp));
const G4double interactionDistance = std::sqrt(largestSigma/Math::tenPi);
return interactionDistance;
}
G4double interactionDistancenbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy) {
// assert(aSpecies.theType==antiNeutron);
// assert(aSpecies.theA<0);
ThreeVector nullVector;
ThreeVector unitVector(0.,0.,1.);
const G4double kineticEnergyPerNucleon = kineticEnergy / (- aSpecies.theA);
Particle antineutronProjectile(antiNeutron, unitVector, nullVector);
antineutronProjectile.setEnergy(antineutronProjectile.getMass()+kineticEnergyPerNucleon);
antineutronProjectile.adjustMomentumFromEnergy();
Particle protonTarget(Proton, nullVector, nullVector);
Particle neutronTarget(Neutron, nullVector, nullVector);
const G4double sigmanbarp = total(&antineutronProjectile, &protonTarget);
const G4double sigmanbarn = total(&antineutronProjectile, &neutronTarget);
/* We compute the interaction distance from the largest of the NN cross
* sections. Note that this is different from INCL4.6, which just takes the
* average of the four, and will in general lead to a different geometrical
* cross section.
*/
const G4double largestSigma = std::max(sigmanbarp, sigmanbarn);
const G4double interactionDistance = std::sqrt(largestSigma/Math::tenPi);
return interactionDistance;
}
G4double interactionDistanceKN(const G4double kineticEnergy) {
ThreeVector nullVector;
@@ -62,6 +62,7 @@ namespace G4INCL {
const G4int CrossSectionsAntiparticles::nMaxPiNN = 4;
const G4int CrossSectionsAntiparticles::nMaxPiPiN = 4;
const G4double nbar_pbarThreshold =1.; //Threshold above which nbar and pbar are considered the same particle
CrossSectionsAntiparticles::CrossSectionsAntiparticles() :
s11pzHC(-2.228000000000294018,8.7560000000005723725,-0.61000000000023239325,-5.4139999999999780324,3.3338333333333348023,-0.75835000000000022049,0.060623611111111114688),
@@ -81,9 +82,32 @@ namespace G4INCL {
G4double CrossSectionsAntiparticles::total(Particle const * const p1, Particle const * const p2) {
G4double inelastic;
if ((p1->isNucleon() && p2->isAntiNucleon()) || (p1->isAntiNucleon() && p2->isNucleon()))
if ((p1->isNucleon() && p2->isAntiNucleon()) || (p1->isAntiNucleon() && p2->isNucleon())){
const G4int iso = ParticleTable::getIsospin(p1->getType()) + ParticleTable::getIsospin(p2->getType());
const Particle *antinucleon;
const Particle *nucleon;
if (p1->isAntiNucleon()) {
antinucleon = p1;
nucleon = p2;
}
else {
antinucleon = p2;
nucleon = p1;
}
const G4double pLab = 0.001*KinematicsUtils::momentumInLab(antinucleon, nucleon); // GeV
const std::vector<G4double> coef_nbarp_total = {1.69447, 5.26254E+08, -5.36346, -0.39766, 0.0243057};//OBELIX data
G4double sigma = KinematicsUtils::compute_xs(coef_nbarp_total,pLab*1000);
if(iso == 2 && pLab < nbar_pbarThreshold){//nbarp low energy
return sigma*1000;
}
else if(antinucleon->getType() == antiNeutron && nucleon->getType() == Neutron && pLab < nbar_pbarThreshold){ //nbarn low energy
return 1000*sigma + NNbarCEX(p1, p2);
}
else {
inelastic = NNbarCEX(p1, p2) + NNbarToNNbarpi(p1, p2) + NNbarToNNbar2pi(p1, p2) + NNbarToNNbar3pi(p1, p2) + NNbarToAnnihilation(p1, p2) + NNbarToLLbar(p1, p2);
else if(p1->isNucleon() && p2->isNucleon()) {
}
} else if(p1->isNucleon() && p2->isNucleon()) {
return CrossSectionsMultiPions::NNTot(p1, p2);
} else if((p1->isNucleon() && p2->isDelta()) ||
(p1->isDelta() && p2->isNucleon())) {
@@ -93,7 +117,7 @@ namespace G4INCL {
return CrossSectionsMultiPions::piNTot(p1,p2);
} else if((p1->isNucleon() && p2->isEta()) ||
(p1->isEta() && p2->isNucleon())) {
inelastic = CrossSectionsMultiPionsAndResonances::etaNToPiN(p1,p2) + CrossSectionsMultiPionsAndResonances::etaNToPiPiN(p1,p2);
inelastic = CrossSectionsMultiPionsAndResonances::etaNToPiN(p1,p2) + CrossSectionsMultiPionsAndResonances::etaNToPiPiN(p1,p2) + CrossSectionsStrangeness::etaNToLK(p1,p2) + CrossSectionsStrangeness::etaNToSK(p1,p2);
} else if((p1->isNucleon() && p2->isOmega()) ||
(p1->isOmega() && p2->isNucleon())) {
inelastic = CrossSectionsMultiPionsAndResonances::omegaNInelastic(p1,p2);
@@ -206,7 +230,7 @@ namespace G4INCL {
// n nbar -> n nbar (same as BFMM 2)
//
//brief pnbar
// p nbar -> p nbar (same as BFMM 472)
// p nbar -> p nbar (same as BFMM 472) --> Total -annihilation
//
// assert((p1->isAntiNucleon() && p2->isNucleon()) || (p1->isNucleon() && p2->isAntiNucleon()));
@@ -235,11 +259,25 @@ namespace G4INCL {
const G4double pLab = 0.001*KinematicsUtils::momentumInLab(antinucleon, nucleon); // GeV
if(iso == 2 || iso == -2){ // npbar or pnbar
sigma = KinematicsUtils::compute_xs(std::move(BFMM472), pLab);
if (iso ==2 && pLab < nbar_pbarThreshold){//nbarp low energy
sigma = total(p1, p2) - NNbarToAnnihilation(p1, p2);// Total minus annihilation
}
else{
sigma = KinematicsUtils::compute_xs(BFMM472, pLab); //pbarn
}
return sigma;
}
else { // ppbar or nnbar
sigma = KinematicsUtils::compute_xs(std::move(BFMM2), pLab);
if(p1->getType()==antiProton || p1->getType()==Proton)
sigma = KinematicsUtils::compute_xs(BFMM2, pLab); // ppbar case
else{
if (pLab < nbar_pbarThreshold){ //nnbar low energy case
sigma = total(p1, p2) - NNbarToAnnihilation(p1, p2) - NNbarCEX(p1, p2);// Total minus annihilation minus CEX
}
else{
sigma = KinematicsUtils::compute_xs(BFMM2, pLab); // nnbar high energy case (same as ppbar)
}
}
return sigma;
}
}
@@ -575,10 +613,33 @@ namespace G4INCL {
}
const G4double pLab = 0.001*KinematicsUtils::momentumInLab(antinucleon, nucleon); // GeV
const G4double mu = (ParticleTable::getRealMass(Proton)*ParticleTable::getRealMass(antiNeutron))/(ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiNeutron));
const G4double hbar_c = 197.326968; // MeV.fm
const G4double Ek_cm = std::sqrt(mu*mu + std::pow(KinematicsUtils::momentumInCM(antinucleon,nucleon),2)) - mu;
const G4double k = std::sqrt(2*mu*Ek_cm)/(hbar_c);
const G4double K = std::sqrt(std::pow(k,2)+2*mu*85/std::pow(hbar_c,2)); //Strong Interaction Potential (MeV)
const G4double x_m = (k*0.97); //Nuclear contact radius (fm)
const G4double X_m = (K*0.97);
const G4double T_0 = 4*K*k/(std::pow(K+k,2));
const G4double v_1 = std::pow(x_m,2)/(1+std::pow(x_m,2));
const G4double v_1_prime = (1/std::pow(x_m,2))+std::pow(1-1/std::pow(x_m,2),2);
const G4double T_1 = (4*x_m*X_m*v_1)/(std::pow(X_m,2)+(2*x_m*X_m+std::pow(x_m,2)*v_1_prime)*v_1);
const G4double v_2 = std::pow(x_m,4)/(9+3*std::pow(x_m,2)+std::pow(x_m,4));
const G4double v_2_prime = std::pow(1-(6/std::pow(x_m,2)),2) + std::pow((6/std::pow(x_m,3))-(3/std::pow(x_m,2)),2);
const G4double T_2 = (4*x_m*X_m*v_2)/(std::pow(X_m,2)+(2*x_m*X_m+std::pow(x_m,2)*v_2_prime)*v_2);
const G4double v_3 = std::pow(x_m,6)/(225+45*std::pow(x_m,2)+6*std::pow(x_m,4)+std::pow(x_m,6));
const G4double v_3_prime = (1 - (21/std::pow(x_m,2)) + (45/std::pow(x_m,4))) + std::pow((45/std::pow(x_m,3))-(6/x_m),2);
const G4double T_3 = (4*x_m*X_m*v_3)/(std::pow(X_m,2)+(2*x_m*X_m+std::pow(x_m,2)*v_3_prime)*v_3);
G4double sigma_nbar_low = (Math::pi/std::pow(k,2)) * (T_0 + 3*T_1 + 5*T_2 + 7*T_3) * 10 ; //GeV
if(iso == 2 || iso == -2){ // pnbar or npbar
sigma = KinematicsUtils::compute_xs(std::move(BFMM6), pLab)*KinematicsUtils::compute_xs(std::move(BFMM471), pLab)/KinematicsUtils::compute_xs(std::move(BFMM1), pLab);
return sigma;
if (iso ==2 && pLab < nbar_pbarThreshold) { //nbarp != pbarn at low momenta
return sigma_nbar_low;
}
else { //pbarn
sigma = KinematicsUtils::compute_xs(std::move(BFMM6), pLab)*KinematicsUtils::compute_xs(std::move(BFMM471), pLab)/KinematicsUtils::compute_xs(std::move(BFMM1), pLab);
return sigma;
}
}
else if(p1->getType()==antiProton || p2->getType()==Proton){ // ppbar case
sigma = KinematicsUtils::compute_xs(std::move(BFMM6), pLab);
@@ -402,12 +402,26 @@ namespace G4INCL {
}
G4double CrossSectionsINCL46::etaNToPiPiN(Particle const * const, Particle const * const) {
G4double CrossSectionsINCL46::etaNToPiPiN(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing Two Pions cross sections
//
return 0.;
}
G4double CrossSectionsINCL46::etaNToLK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsINCL46::etaNToSK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Sigma cross sections
//
return 0.;
}
G4double CrossSectionsINCL46::omegaNToPiN(Particle const * const, Particle const * const) {
//
@@ -422,6 +436,20 @@ namespace G4INCL {
//
return 0.;
}
G4double CrossSectionsINCL46::omegaNToLK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsINCL46::omegaNToSK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Sigma cross sections
//
return 0.;
}
G4double CrossSectionsINCL46::etaPrimeNToPiN(Particle const * const, Particle const * const) {
//
@@ -1253,12 +1253,26 @@ namespace G4INCL {
}
G4double CrossSectionsMultiPions::etaNToPiPiN(Particle const * const, Particle const * const) {
G4double CrossSectionsMultiPions::etaNToPiPiN(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing Two Pions cross sections
//
return 0.;
}
}
G4double CrossSectionsMultiPions::etaNToLK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsMultiPions::etaNToSK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Sigma cross sections
//
return 0.;
}
G4double CrossSectionsMultiPions::omegaNToPiN(Particle const * const, Particle const * const) {
@@ -1274,6 +1288,20 @@ namespace G4INCL {
//
return 0.;
}
G4double CrossSectionsMultiPions::omegaNToLK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsMultiPions::omegaNToSK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Sigma cross sections
//
return 0.;
}
G4double CrossSectionsMultiPions::etaPrimeNToPiN(Particle const * const, Particle const * const) {
//
@@ -335,6 +335,20 @@ namespace G4INCL {
if (sigma < 0.) sigma = 0.;
return sigma; // Parameterization from the ANL-Osaka DCC model [PRC88(2013)035209] - eta p --> "pi+pi0 n" + "pi0 pi0 p" total XS
}
G4double CrossSectionsMultiPionsAndResonances::etaNToLK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsMultiPionsAndResonances::etaNToSK(Particle const * const, Particle const * const) {
//
// Eta-Nucleon producing K Sigma cross sections
//
return 0.;
}
G4double CrossSectionsMultiPionsAndResonances::etaNElastic(Particle const * const particle1, Particle const * const particle2) {
@@ -487,6 +501,20 @@ namespace G4INCL {
return sigma;
}
G4double CrossSectionsMultiPionsAndResonances::omegaNToLK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Lambda cross sections
//
return 0.;
}
G4double CrossSectionsMultiPionsAndResonances::omegaNToSK(Particle const * const, Particle const * const) {
//
// Omega-Nucleon producing K Sigma cross sections
//
return 0.;
}
#if defined(NDEBUG) || defined(INCLXX_IN_GEANT4_MODE)
@@ -45,6 +45,7 @@
#include "G4INCLCrossSectionsStrangeness.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLParticleTable.hh"
#include "G4INCLRandom.hh"
// #include <cassert>
namespace G4INCL {
@@ -91,7 +92,7 @@ namespace G4INCL {
return CrossSectionsMultiPions::piNTot(p1,p2);
} else if((p1->isNucleon() && p2->isEta()) ||
(p1->isEta() && p2->isNucleon())) {
inelastic = CrossSectionsMultiPionsAndResonances::etaNToPiN(p1,p2) + CrossSectionsMultiPionsAndResonances::etaNToPiPiN(p1,p2);
inelastic = CrossSectionsMultiPionsAndResonances::etaNToPiN(p1,p2) + CrossSectionsMultiPionsAndResonances::etaNToPiPiN(p1,p2) + etaNToLK(p1,p2) + etaNToSK(p1,p2);
} else if((p1->isNucleon() && p2->isOmega()) ||
(p1->isOmega() && p2->isNucleon())) {
inelastic = CrossSectionsMultiPionsAndResonances::omegaNInelastic(p1,p2);
@@ -2002,6 +2003,182 @@ namespace G4INCL {
return sigma;
}
G4double CrossSectionsStrangeness::etaNToLK(Particle const * const particle1, Particle const * const particle2) {
//
// Eta-Nucleon producing K Lambda cross sections
//
// assert((particle1->isNucleon() && particle2->isEta()) || (particle1->isEta() && particle2->isNucleon()));
G4double sigma=0.;
const Particle *eta;
const Particle *nucleon;
if (particle1->isEta()) {
eta = particle1;
nucleon = particle2;
}
else {
eta = particle2;
nucleon = particle1;
}
const G4double pLab = KinematicsUtils::momentumInLab(eta, nucleon); // MeV
if (pLab < 550.)
return 0.;
else if (pLab < 700. )
sigma = 1.3288E-7*std::pow(pLab,3.) - 2.6243E-4*std::pow(pLab,2.) + 1.7140E-1*pLab - 3.6408E+1;
else if (pLab < 1400. )
sigma = -3.7606E-17*std::pow(pLab,6.) + 2.5954E-13*std::pow(pLab,5.) - 7.4491E-10*std::pow(pLab,4.) + 1.1391E-6*std::pow(pLab,3.) - 9.8028E-4*std::pow(pLab,2.) + 4.5100E-1*pLab - 8.5862E+1;
else
sigma = 0.9460023; // value at pLab=1400 MeV (fit of XS from Kamano - private communication based on PRC88(2013)035209)
return sigma;
}
G4double CrossSectionsStrangeness::omegaNToLK(Particle const * const particle1, Particle const * const particle2) {
//
// Omega-Nucleon producing K Lambda cross sections
//
// assert((particle1->isNucleon() && particle2->isOmega()) || (particle1->isOmega() && particle2->isNucleon()));
G4double ECM=KinematicsUtils::totalEnergyInCM(particle1, particle2);
G4double massPiZero=ParticleTable::getINCLMass(PiZero);
G4double massomega;
G4double massnucleon;
G4double pCM_omega;
G4double pCM_pion;
G4double pLab_pion;
G4double sigma=0.;
if (particle1->isOmega()) {
massomega=particle1->getMass();
massnucleon=particle2->getMass();
}
else {
massomega=particle2->getMass();
massnucleon=particle1->getMass();
}
pCM_omega=KinematicsUtils::momentumInCM(ECM, massomega, massnucleon);
pCM_pion=KinematicsUtils::momentumInCM(ECM, massPiZero, massnucleon);
pLab_pion=KinematicsUtils::momentumInLab(ECM*ECM, massPiZero, massnucleon);
const ThreeVector mom_pion(0.0, 0.0, pLab_pion);
const ThreeVector pos(0.0, 0.0, 0.0);
Particle *pion = new Particle(PiZero, mom_pion, pos);
if (particle1->isNucleon()) sigma = NpiToLK(pion, particle1) * (pCM_pion/pCM_omega);
if (particle2->isNucleon()) sigma = NpiToLK(pion, particle2) * (pCM_pion/pCM_omega);
//if (sigma > omegaNInelastic(particle1, particle2) || (pLab_omega < 200.)) {
if (sigma > omegaNInelastic(particle1, particle2)) {
//sigma = omegaNInelastic(particle1, particle2);
sigma = 0.;
}
return sigma;
}
G4double CrossSectionsStrangeness::etaNToSK(Particle const * const particle1, Particle const * const particle2) {
//
// Eta-Nucleon producing K Sigma cross sections
//
// assert((particle1->isNucleon() && particle2->isEta()) || (particle1->isEta() && particle2->isNucleon()));
G4double sigma=0.;
const Particle *eta;
const Particle *nucleon;
if (particle1->isEta()) {
eta = particle1;
nucleon = particle2;
}
else {
eta = particle2;
nucleon = particle1;
}
const G4double pLab = KinematicsUtils::momentumInLab(eta, nucleon); // MeV
if (pLab < 730.)
return 0.;
else if (pLab < 1400. )
sigma = -7.9949212022E-18*std::pow(pLab,6.) + 4.8776384248E-14*std::pow(pLab,5.) - 1.2005766956E-10*std::pow(pLab,4.) + 1.5072180697E-7*std::pow(pLab,3.) - 9.9473179699E-5*std::pow(pLab,2.) + 3.1111481306E-2*pLab - 3.0616598048;
else
sigma = 0.02713; // value at pLab=1400 MeV (fit of XS from Kamano - private communication based on PRC88(2013)035209)
sigma=3.*sigma; // Sigma K = (Sigma_0 + K+) + (Sigma_+ + K0) = 3 * (Sigma_0 + K+)
return sigma;
}
G4double CrossSectionsStrangeness::omegaNToSK(Particle const * const particle1, Particle const * const particle2) {
//
// Omega-Nucleon producing K Sigma cross sections
//
// assert((particle1->isNucleon() && particle2->isOmega()) || (particle1->isOmega() && particle2->isNucleon()));
G4double ECM=KinematicsUtils::totalEnergyInCM(particle1, particle2);
G4double massPiZero=ParticleTable::getINCLMass(PiZero);
G4double massomega;
G4double massnucleon;
G4double pCM_omega;
G4double pCM_pion;
G4double pLab_pion;
G4double sigma=0.;
if (particle1->isOmega()) {
massomega=particle1->getMass();
massnucleon=particle2->getMass();
}
else {
massomega=particle2->getMass();
massnucleon=particle1->getMass();
}
pCM_omega=KinematicsUtils::momentumInCM(ECM, massomega, massnucleon);
pCM_pion=KinematicsUtils::momentumInCM(ECM, massPiZero, massnucleon);
pLab_pion=KinematicsUtils::momentumInLab(ECM*ECM, massPiZero, massnucleon);
const ThreeVector mom_pion(0.0, 0.0, pLab_pion);
const ThreeVector pos(0.0, 0.0, 0.0);
Particle *pion = new Particle(PiZero, mom_pion, pos);
if (particle1->isNucleon()) sigma = 2* NpiToSK(pion, particle1) * (pCM_pion/pCM_omega); // "2*" due to "Sigma_0/+ + K+/0" (omega p) AND "Sigma_0/- K0/+" (omega n)
if (particle2->isNucleon()) sigma = 2* NpiToSK(pion, particle2) * (pCM_pion/pCM_omega);
//if (sigma > omegaNInelastic(particle1, particle2) || (pLab_omega < 200.)) {
if (sigma > omegaNInelastic(particle1, particle2)) {
//sigma = omegaNInelastic(particle1, particle2);
sigma = 0.;
}
return sigma;
}
G4double CrossSectionsStrangeness::omegaNToPiPiN(Particle const * const particle1, Particle const * const particle2) {
//
// Omega-Nucleon producing 2 Pions cross sections
//
// assert((particle1->isNucleon() && particle2->isOmega()) || (particle1->isOmega() && particle2->isNucleon()));
G4double sigma=0.;
sigma = omegaNInelastic(particle1,particle2) - omegaNToPiN(particle1,particle2) - omegaNToLK(particle1,particle2) - omegaNToSK(particle1,particle2);
return sigma;
}
} // namespace G4INCL
@@ -36,7 +36,6 @@
#include "globals.hh"
#include "G4INCLDeltaProductionChannel.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLBinaryCollisionAvatar.hh"
#include "G4INCLRandom.hh"
#include "G4INCLGlobals.hh"
@@ -46,17 +45,19 @@ namespace G4INCL {
const G4int DeltaProductionChannel::maxTries = 100000;
DeltaProductionChannel::DeltaProductionChannel(Particle *p1,
Particle *p2)
: particle1(p1), particle2(p2)
{}
DeltaProductionChannel::DeltaProductionChannel(Particle *p1, Particle *p2,
Nucleus *n)
: particle1(p1), particle2(p2), thenucleus(n) {}
DeltaProductionChannel::~DeltaProductionChannel() {}
G4double DeltaProductionChannel::sampleDeltaMass(G4double ecm) {
const G4double maxDeltaMass = ecm - ParticleTable::effectiveNucleonMass - 1.0;
const G4double maxDeltaMassRndm = std::atan((maxDeltaMass-ParticleTable::effectiveDeltaMass)*2./ParticleTable::effectiveDeltaWidth);
const G4double deltaMassRndmRange = maxDeltaMassRndm - ParticleTable::minDeltaMassRndm;
const G4double maxDeltaMassRndm =
std::atan((maxDeltaMass - ParticleTable::effectiveDeltaMass) * 2. /
ParticleTable::effectiveDeltaWidth);
const G4double deltaMassRndmRange =
maxDeltaMassRndm - ParticleTable::minDeltaMassRndm;
// assert(deltaMassRndmRange>0.);
G4double y=ecm*ecm;
@@ -105,6 +106,13 @@ namespace G4INCL {
// ParticleType p1TypeOld = particle1->getType();
// ParticleType p2TypeOld = particle2->getType();
G4double ecm = KinematicsUtils::totalEnergyInCM(particle1, particle2);
// For SRC
ParticleType p1TypeOld = particle1->getType();
ParticleType p2TypeOld = particle2->getType();
// INCL_INFO( particle1->print() << '\n');
// INCL_INFO( particle2->print() << '\n');
const G4int isospin = ParticleTable::getIsospin(particle1->getType()) +
ParticleTable::getIsospin(particle2->getType());
@@ -232,11 +240,22 @@ namespace G4INCL {
} else if(is2 == ParticleTable::getIsospin(Neutron)) {
particle2->setType(Neutron);
}
if (particle1->isDelta())
particle1->setMass(xmdel);
if (particle2->isDelta())
particle2->setMass(xmdel);
if(particle1->isDelta()) particle1->setMass(xmdel);
if(particle2->isDelta()) particle2->setMass(xmdel);
if (thenucleus) {
// std::cout<< "entrando" <<std::endl;
// std::cout<< particle1->print() <<std::endl;
// std::cout<< particle2->print() <<std::endl;
srcChannel = new SrcChannel(particle1, particle2, thenucleus);
srcChannel->fillFinalState(fs, p1TypeOld, p2TypeOld);
delete srcChannel;
} else {
fs->addModifiedParticle(particle1);
fs->addModifiedParticle(particle2);
}
}
}
} // namespace G4INCL
@@ -40,17 +40,16 @@
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLParticleTable.hh"
#include "G4INCLCrossSections.hh"
#include "G4INCLInteractionAvatar.hh"
#include "G4INCLGlobals.hh"
namespace G4INCL {
ElasticChannel::ElasticChannel(Particle *p1, Particle *p2)
:particle1(p1), particle2(p2)
{
}
ElasticChannel::ElasticChannel(Particle *p1, Particle *p2, Nucleus *n)
: particle1(p1), particle2(p2), thenucleus(n) {}
ElasticChannel::~ElasticChannel()
{
ElasticChannel::~ElasticChannel() {
// delete srcChannel;
}
void ElasticChannel::fillFinalState(FinalState *fs)
@@ -154,6 +153,12 @@ namespace G4INCL {
particle1->setMomentum(p1momentum);
particle2->setMomentum(-p1momentum);
}
if (thenucleus) {
srcChannel = new SrcChannel(particle1, particle2, thenucleus);
srcChannel->fillFinalState(fs, particle1->getType(), particle2->getType());
delete srcChannel;
} else {
// Handle backward scattering here.
@@ -177,5 +182,5 @@ namespace G4INCL {
fs->addModifiedParticle(particle2);
}
}
}
} // namespace G4INCL
@@ -0,0 +1,95 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4INCLEtaOrOmegaNToLKChannel.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLBinaryCollisionAvatar.hh"
#include "G4INCLRandom.hh"
#include "G4INCLGlobals.hh"
#include "G4INCLLogger.hh"
namespace G4INCL {
EtaOrOmegaNToLKChannel::EtaOrOmegaNToLKChannel(Particle *p1, Particle *p2)
: particle1(p1), particle2(p2)
{
}
EtaOrOmegaNToLKChannel::~EtaOrOmegaNToLKChannel(){
}
void EtaOrOmegaNToLKChannel::fillFinalState(FinalState *fs) {
Particle * nucleon;
Particle * meson;
if(particle1->isNucleon()) {
nucleon = particle1;
meson = particle2;
} else {
nucleon = particle2;
meson = particle1;
}
if (nucleon->getType() == Neutron) {
nucleon->setType(Lambda);
meson->setType(KZero);
}
else {
nucleon->setType(Lambda);
meson->setType(KPlus);
}
G4double sh=nucleon->getEnergy()+meson->getEnergy();
G4double mn=nucleon->getMass();
G4double me=meson->getMass();
G4double en=(sh*sh+mn*mn-me*me)/(2*sh);
nucleon->setEnergy(en);
G4double ee=std::sqrt(en*en-mn*mn+me*me);
meson->setEnergy(ee);
G4double pn=std::sqrt(en*en-mn*mn);
ThreeVector mom_nucleon = Random::normVector(pn);
nucleon->setMomentum(mom_nucleon);
meson->setMomentum(-mom_nucleon);
fs->addModifiedParticle(nucleon);
fs->addModifiedParticle(meson);
}
}
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4INCLEtaOrOmegaNToSKChannel.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLBinaryCollisionAvatar.hh"
#include "G4INCLRandom.hh"
#include "G4INCLGlobals.hh"
#include "G4INCLLogger.hh"
namespace G4INCL {
EtaOrOmegaNToSKChannel::EtaOrOmegaNToSKChannel(Particle *p1, Particle *p2)
: particle1(p1), particle2(p2)
{
}
EtaOrOmegaNToSKChannel::~EtaOrOmegaNToSKChannel(){
}
void EtaOrOmegaNToSKChannel::fillFinalState(FinalState *fs) {
Particle * nucleon;
Particle * meson;
if(particle1->isNucleon()) {
nucleon = particle1;
meson = particle2;
} else {
nucleon = particle2;
meson = particle1;
}
const G4double r2 = Random::shoot();
if (nucleon->getType() == Neutron) {
if (r2*3. < 2.) {
nucleon->setType(SigmaZero);
meson->setType(KZero);
}
else {
nucleon->setType(SigmaMinus);
meson->setType(KPlus);
}
}
else {
if (r2*3. < 2.) {
nucleon->setType(SigmaPlus);
meson->setType(KZero);
}
else {
nucleon->setType(SigmaZero);
meson->setType(KPlus);
}
}
G4double sh=nucleon->getEnergy()+meson->getEnergy();
G4double mn=nucleon->getMass();
G4double me=meson->getMass();
G4double en=(sh*sh+mn*mn-me*me)/(2*sh);
nucleon->setEnergy(en);
G4double ee=std::sqrt(en*en-mn*mn+me*me);
meson->setEnergy(ee);
G4double pn=std::sqrt(en*en-mn*mn);
ThreeVector mom_nucleon = Random::normVector(pn);
nucleon->setMomentum(mom_nucleon);
meson->setMomentum(-mom_nucleon);
fs->addModifiedParticle(nucleon);
fs->addModifiedParticle(meson);
}
}
@@ -54,6 +54,7 @@
#include "G4INCLLogger.hh"
#include "G4INCLConfigEnums.hh"
#include "G4INCLConfig.hh"
#include "G4INCLEventInfo.hh"
// #include <cassert>
namespace G4INCL {
@@ -62,6 +63,10 @@ namespace G4INCL {
const G4int InteractionAvatar::maxIterLocE = 50;
G4ThreadLocal Particle *InteractionAvatar::backupParticle1 = NULL;
G4ThreadLocal Particle *InteractionAvatar::backupParticle2 = NULL;
G4ThreadLocal Particle *InteractionAvatar::backupPartner = NULL;
ThreeVector InteractionAvatar::mbackupPartner;
G4ThreadLocal InteractionAvatar *InteractionAvatar::interactionAvatar = 0;
InteractionAvatar::InteractionAvatar(G4double time, G4INCL::Nucleus *n, G4INCL::Particle *p1)
: IAvatar(time), theNucleus(n),
@@ -70,6 +75,7 @@ namespace G4INCL {
weight(1.),
violationEFunctor(NULL)
{
interactionAvatar = this;
}
InteractionAvatar::InteractionAvatar(G4double time, G4INCL::Nucleus *n, G4INCL::Particle *p1,
@@ -80,17 +86,35 @@ namespace G4INCL {
weight(1.),
violationEFunctor(NULL)
{
interactionAvatar = this;
}
InteractionAvatar *InteractionAvatar::Instance() { return interactionAvatar; }
InteractionAvatar::~InteractionAvatar() {
}
void InteractionAvatar::setSrcPartner(Particle *p) {
if (backupPartner) {
(*backupPartner) = (*p);
} else {
backupPartner = new Particle(*p);
}
INCL_DEBUG("setSrcPartner:" << backupPartner->print());
return;
}
void InteractionAvatar::deleteBackupParticles() {
delete backupParticle1;
if(backupParticle2)
delete backupParticle2;
if (backupPartner)
delete backupPartner;
backupParticle1 = NULL;
backupParticle2 = NULL;
backupPartner = NULL;
}
void InteractionAvatar::preInteractionBlocking() {
@@ -175,7 +199,14 @@ namespace G4INCL {
ModifiedAndDestroyed.insert(ModifiedAndDestroyed.end(), Destroyed.begin(), Destroyed.end());
// Boost back to lab
modifiedAndCreated.boost(-boostVector);
//modifiedAndCreated.boost(-boostVector);
for (ParticleIter i = modifiedAndCreated.begin(),
e = modifiedAndCreated.end();
i != e; ++i)
if ((*i)->isSrcPartner() == false){
(*i)->boost(-boostVector);
}
// If there is no Nucleus, just return
if(!theNucleus) return;
@@ -192,13 +223,78 @@ namespace G4INCL {
}
// Try to enforce energy conservation
fs->setTotalEnergyBeforeInteraction(oldTotalEnergy);
G4int check = 0;
G4double oldTotalEnergy2 = 0.;
if (modifiedAndCreated.size() == 3 &&
theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 1) {
for (ParticleIter i = modifiedAndCreated.begin(),
e = modifiedAndCreated.end();
i != e; ++i) {
if ((*i)->getSrcPair() > 0.) {
check++;
}
}
}
G4double ediff = 0., partnerE = 0.;
if (check == 2) {
G4double oldTotalEnergy3 = 0.;
partnerE = backupPartner->getEnergy() - backupPartner->getPotentialEnergy();
for (ParticleIter i = modifiedAndCreated.begin(),
e = modifiedAndCreated.end();
i != e; ++i) {
if ((*i)->isNucleon())
oldTotalEnergy3 += (*i)->getEnergy() - (*i)->getPotentialEnergy();
else if ((*i)->isResonance())
oldTotalEnergy3 += (*i)->getEnergy() - (*i)->getPotentialEnergy() -
ParticleTable::effectiveNucleonMass;
}
INCL_DEBUG("check initial energies: "
<< backupParticle1->getEnergy() << " , "
<< backupParticle2->getEnergy() << " , "
<< backupPartner->getEnergy() << '\n');
INCL_DEBUG("check initial energies total: "
<< backupParticle1->getEnergy() -
backupParticle1->getPotentialEnergy() +
backupParticle2->getEnergy() -
backupParticle2->getPotentialEnergy() +
backupPartner->getEnergy() -
backupPartner->getPotentialEnergy()
<< '\n');
ediff =
oldTotalEnergy3 -
(backupParticle1->getEnergy() - backupParticle1->getPotentialEnergy() +
backupParticle2->getEnergy() - backupParticle2->getPotentialEnergy() +
backupPartner->getEnergy() - backupPartner->getPotentialEnergy());
INCL_DEBUG("check diff. src energies: " << oldTotalEnergy3 << " , " << ediff
<< '\n');
}
// Try to enforce energy conservation
fs->setTotalEnergyBeforeInteraction(oldTotalEnergy + ediff + partnerE);
INCL_DEBUG("postInteraction before enforceEnergyConservation final state: "
<< oldTotalEnergy + oldTotalEnergy2 << " \n Einit= "
<< oldTotalEnergy << " \n Ecor= " << oldTotalEnergy2 << '\n'
<< fs->print() << '\n');
G4bool success = enforceEnergyConservation(fs);
INCL_DEBUG("enforceEnergyConservation finish " << success << '\n');
if(!success) {
INCL_DEBUG("Enforcing energy conservation: failed!" << '\n');
// Restore the state of the initial particles
restoreParticles();
if (check == 2) {
INCL_DEBUG("Enforcing energy conservation: failed for SRC"
<< " , eventnb: " << theEventInfo.eventNumber << '\n');
restoreSrcPartner(fs);
}
// Delete newly created particles
for(ParticleIter i=created.begin(), e=created.end(); i!=e; ++i )
@@ -223,6 +319,12 @@ namespace G4INCL {
// Restore the state of the initial particles
restoreParticles();
if (check == 2) {
INCL_DEBUG("Mass of the produced delta below decay threshold for SRC"
<< " , eventnb: " << theEventInfo.eventNumber << '\n');
restoreSrcPartner(fs);
}
// Delete newly created particles
for(ParticleIter j=created.begin(), end=created.end(); j!=end; ++j )
@@ -239,11 +341,17 @@ namespace G4INCL {
// Test Pauli blocking
G4bool isBlocked = Pauli::isBlocked(modifiedAndCreated, theNucleus);
if(isBlocked) {
if (isBlocked && check < 2) {
INCL_DEBUG("Pauli: Blocked!" << '\n');
// Restore the state of the initial particles
restoreParticles();
if (check == 2) {
INCL_DEBUG("Pauli: Blocked SRC!"
<< " , eventnb: " << theEventInfo.eventNumber << '\n');
restoreSrcPartner(fs);
}
// Delete newly created particles
for(ParticleIter i=created.begin(), e=created.end(); i!=e; ++i )
@@ -259,12 +367,25 @@ namespace G4INCL {
// Test CDPP blocking
G4bool isCDPPBlocked = Pauli::isCDPPBlocked(created, theNucleus);
G4int cntB = 0; //Do not pass through CDPP if Nbar annihilation
for(ParticleIter i=modifiedAndCreated.begin(), e=modifiedAndCreated.end(); i!=e; ++i ){
if((*i)->isBaryon())
cntB++;
}
if(cntB==0)
isCDPPBlocked=false;
if(isCDPPBlocked) {
INCL_DEBUG("CDPP: Blocked!" << '\n');
// Restore the state of the initial particles
restoreParticles();
if (check == 2) {
INCL_DEBUG("CDPP: Blocked for SRC"
<< " , eventnb: " << theEventInfo.eventNumber << '\n');
restoreSrcPartner(fs);
}
// Delete newly created particles
for(ParticleIter i=created.begin(), e=created.end(); i!=e; ++i )
@@ -330,25 +451,62 @@ namespace G4INCL {
(*i)->makeParticipant();
}
}
(*i)->resetSrcPartner();
}
ParticleList destroyed = fs->getDestroyedParticles();
for(ParticleIter i=destroyed.begin(), e=destroyed.end(); i!=e; ++i )
if(!(*i)->isTargetSpectator())
theNucleus->getStore()->getBook().decrementCascading();
if (check == 2) {
theNucleus->setSrcInternalEnergy(ediff);
for (ParticleIter i = modifiedAndCreated.begin(),
e = modifiedAndCreated.end();
i != e; ++i) {
(*i)->resetSrcPartner();
}
INCL_DEBUG("postInteraction end, src energy: "
<< ediff << " , eventnb: " << theEventInfo.eventNumber << '\n');
}
return;
}
void InteractionAvatar::restoreParticles() const {
(*particle1) = (*backupParticle1);
if(particle2)
particle1->resetSrcPartner();
if(particle2){
(*particle2) = (*backupParticle2);
particle2->resetSrcPartner();
}
}
void InteractionAvatar::restoreSrcPartner(FinalState *fs) {
theNucleus->getStore()->getBook().setAcceptedSrcCollisions(0);
auto m = fs->getSrcModifiedParticles();
if (backupPartner) {
for (ParticleIter i = m.begin(), e = m.end(); i != e; ++i) {
if ((*i)->getType() == backupPartner->getType() &&
(*i)->getSrcPair() == backupPartner->getSrcPair()) {
(*i)->setPosition(backupPartner->getPosition());
(*i)->setMomentum(backupPartner->getMomentum());
(*i)->adjustEnergyFromMomentum();
(*i)->resetSrcPartner();
theNucleus->updatePotentialEnergy(*i);
}
}
}
theNucleus->setSrcInternalEnergy(0.0);
}
G4bool InteractionAvatar::shouldUseLocalEnergy() const {
if(!theNucleus) return false;
LocalEnergyType theLocalEnergyType;
if(theNucleus->getStore()->getConfig()->getProjectileType()==antiProton ||
theNucleus->getStore()->getConfig()->getProjectileType()==antiNeutron){
theNucleus->getStore()->getConfig()->getProjectileType()==antiNeutron||
theNucleus->getStore()->getConfig()->getProjectileType()==antiComposite){
return false;
}
if(getType()==DecayAvatarType || isPiN)
@@ -414,7 +572,9 @@ namespace G4INCL {
// Store the particle momenta (necessary for the calls to
// scaleParticleMomenta() to work)
for(ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i) {
if ((*i)->isSrcPartner() == false){
(*i)->boost(boostVector);
}
particleMomenta.push_back((*i)->getMomentum());
}
}
@@ -439,8 +599,10 @@ namespace G4INCL {
for(ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i, ++iP) {
(*i)->setMomentum((*iP)*alpha);
(*i)->adjustEnergyFromMomentum();
(*i)->rpCorrelate();
(*i)->boost(-boostVector);
if ((*i)->isSrcPartner() == false) {
(*i)->rpCorrelate();
(*i)->boost(-boostVector);
}
if(theNucleus){
theNucleus->updatePotentialEnergy(*i);
} else {
@@ -448,7 +610,7 @@ namespace G4INCL {
}
if(shouldUseLocalEnergy && !(*i)->isPion() && !(*i)->isEta() && !(*i)->isOmega() &&
!(*i)->isKaon() && !(*i)->isAntiKaon() && !(*i)->isSigma() && !(*i)->isPhoton() && !(*i)->isLambda() && !(*i)->isAntiBaryon()) { // This translates AECSVT's loops 1, 3 and 4
!(*i)->isKaon() && !(*i)->isAntiKaon() && !(*i)->isSigma() && !(*i)->isPhoton() && !(*i)->isLambda() && !(*i)->isAntiBaryon() && !(*i)->isSrcPartner()) { // This translates AECSVT's loops 1, 3 and 4
// assert(theNucleus); // Local energy without a nucleus doesn't make sense
const G4double energy = (*i)->getEnergy(); // Store the energy of the particle
G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, *i); // Initial value of local energy
@@ -467,7 +629,7 @@ namespace G4INCL {
}
//jlrs For lambdas and nuclei with masses higher than 19 also local energy
if(shouldUseLocalEnergy && (*i)->isLambda() && theNucleus->getA()>19) {
if(shouldUseLocalEnergy && (*i)->isLambda() && theNucleus->getA()>19 && !(*i)->isSrcPartner()) {
// assert(theNucleus); // Local energy without a nucleus doesn't make sense
const G4double energy = (*i)->getEnergy(); // Store the energy of the particle
G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, *i); // Initial value of local energy
@@ -196,7 +196,7 @@ namespace G4INCL {
G4double gammaFromKineticEnergy(const ParticleSpecies &p, const G4double EKin) {
G4double mass;
if(p.theType==Composite)
if(p.theType==Composite || p.theType==antiComposite)
mass = ParticleTable::getTableMass(p.theA, p.theZ, p.theS);
else
mass = ParticleTable::getTableParticleMass(p.theType);
@@ -115,11 +115,13 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
const G4double plab = 0.001*KinematicsUtils::momentumInLab(particle1, particle2); //GeV
const G4double sqrtS = KinematicsUtils::totalEnergyInCM(nucleon, antinucleon);
const G4bool IsOnlyPion = (sqrtS < nucleon->getINCLMass() + antinucleon->getINCLMass());
G4double rdm = Random::shoot();
const std::vector<G4double> BFMM6 = {66.098, 0.153, -4.576, -38.319, 6.625}; //ppbar annihilation xs
const std::vector<G4double> BFMM1 = {119.066, 6.251, -0.006, -60.046, 11.958}; //ppbar total xs
const std::vector<G4double> BFMM471 = {108.104, 15.708, 0.832, -54.632, -6.958}; //npbar total xs
const std::vector<G4double> coef_nbarp_total = {1.69447, 5.26254E+08, -5.36346, -0.39766, 0.0243057}; //nbarp total xs (plab <0.5)
//PPbar annihilation xs
const std::vector<G4double> PPbar_pip_pim = {0.637, -0.340, -0.003, -0.439, 0.144};
@@ -163,11 +165,11 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
G4String dataPathnpbar(dataPath0 + "/inflightnpbarFS.dat");
G4String dataPathppbark(dataPath0 + "/inflightppbarFSkaonic.dat");
G4String dataPathnpbark(dataPath0 + "/inflightnpbarFSkaonic.dat");
G4String dataPathpnbar(dataPath0 + "/inflightpnbarFS.dat"); //nbar case
G4String dataPathpnbark(dataPath0 + "/inflightpnbarFSkaonic.dat"); // nbar case
G4String dataPathnbarp(dataPath0 + "/inflightpnbarFS.dat"); //nbar case
G4String dataPathnbarpk(dataPath0 + "/inflightpnbarFSkaonic.dat"); // nbar case
#else
//Config *theConfig = new G4INCL::Config;
//theConfig->setINCLXXDataFilePath(G4INCL::theINCLXXDataFilePath);
//theConfig->setINCLXXDataFilePath(G4INCL::theINCLXXDataFilePath);
Config const *theConfig=theNucleus->getStore()->getConfig();
std::string path;
if(theConfig)
@@ -180,8 +182,10 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
INCL_DEBUG("Reading https://doi.org/10.1016/j.physrep.2005.03.002 ppbar kaonic final states" << dataPathppbark << '\n');
std::string dataPathnpbark(path + "/inflightnpbarFSkaonic.dat");
INCL_DEBUG("Reading https://doi.org/10.1007/BF02818764 and https://link.springer.com/article/10.1007/BF02754930 npbar kaonic final states" << dataPathnpbark << '\n');
std::string dataPathpnbar(path + "/inflightpnbarFS.dat"); // nbar case
std::string dataPathpnbark(path + "/inflightpnbarFSkaonic.dat"); // nbar case
std::string dataPathnbarp(path + "/inflightpnbarFS.dat"); // nbar case
INCL_DEBUG("Reading https://doi.org/10.1016/0375-9474(92)90362-N nnbar final states " << dataPathnbarp << '\n');
std::string dataPathnbarpk(path + "/inflightpnbarFSkaonic.dat");
INCL_DEBUG("Reading https://doi.org/10.1007/BF02818764 and https://link.springer.com/article/10.1007/BF02754930 nbarp kaonic final states" << dataPathnbarpk << '\n');
#endif
/*std::string path = {"/home/zdemid/INCL/inclcode/data"};
std::string dataPathppbar(path + "/inflightppbarFS.dat");
@@ -210,7 +214,119 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
//setting types of new particles and pushing them back to the list
if(nucleon->getType()==Neutron && antinucleon->getType()==antiProton){
//std::cout << "npbar"<< std::endl;
if(IsOnlyPion){
const std::vector<double> channels_Ratio = {0.053, 0.258, 0.531, 0.067, 0.062, 0.007, 0.020, 0.002};//Taken from inflightnpbarFS.dat and renormalised
if(rdm < channels_Ratio.front()){
Particle *p1 = new Particle(PiMinus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1]){
Particle *p1 = new Particle(PiMinus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2]){
Particle *p1 = new Particle(PiMinus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3]){
Particle *p1 = new Particle(PiMinus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4]){
Particle *p1 = new Particle(PiMinus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiMinus, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
Particle *p7 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiPlus, zero, rcol);
Particle *p3 = new Particle(PiMinus, zero, rcol);
Particle *p4 = new Particle(PiMinus, zero, rcol);
Particle *p5 = new Particle(PiMinus, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
Particle *p7 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else if(rdm <= channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6] + channels_Ratio[7]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiPlus, zero, rcol);
Particle *p3 = new Particle(PiPlus, zero, rcol);
Particle *p4 = new Particle(PiMinus, zero, rcol);
Particle *p5 = new Particle(PiMinus, zero, rcol);
Particle *p6 = new Particle(PiMinus, zero, rcol);
Particle *p7 = new Particle(PiMinus, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else{
INCL_ERROR("random draw outside channels for OnlyPion annihilation (low energy)");
}
}
else {
const G4double totalpnbar = KinematicsUtils::compute_xs(BFMM6, plab)*KinematicsUtils::compute_xs(BFMM471, plab)/KinematicsUtils::compute_xs(BFMM1, plab);
// xs is same for npbar, but the fs has different charge
@@ -432,9 +548,208 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
}
} // end of kaonic option
} // end of default annihilation
} //end of else for IsOnlyPion
}
else if(nucleon->getType()==Proton && antinucleon->getType()==antiNeutron){
if(IsOnlyPion){
const std::vector<G4double> channels_Ratio = {0.053, 0.258, 0.531, 0.067, 0.062, 0.007, 0.020, 0.002};//Taken from inflightpnbarFS.dat and renormalised
if(rdm < channels_Ratio.front()){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiPlus, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
Particle *p7 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiPlus, zero, rcol);
Particle *p3 = new Particle(PiMinus, zero, rcol);
Particle *p4 = new Particle(PiMinus, zero, rcol);
Particle *p5 = new Particle(PiPlus, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
Particle *p7 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else if(rdm <= channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6] + channels_Ratio[7]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiPlus, zero, rcol);
Particle *p3 = new Particle(PiPlus, zero, rcol);
Particle *p4 = new Particle(PiMinus, zero, rcol);
Particle *p5 = new Particle(PiMinus, zero, rcol);
Particle *p6 = new Particle(PiMinus, zero, rcol);
Particle *p7 = new Particle(PiPlus, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
}
else {
if (plab < 1.){ //nbar != pbar (< 1. GeV/c)
if(rdm < 1. - kaonicFSprob){
INCL_DEBUG("pionic pnbar final state" << '\n');
sum = read_file(dataPathnbarp, probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.95 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, zero, rcol);
list.push_back(p);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading nbar FS files");
for(G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
}
}
}
else{
INCL_DEBUG("kaonic npbar final state chosen" << '\n');
sum = read_file(dataPathnbarpk, probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//3837 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
for(G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "K-"){
Particle *p = new Particle(KMinus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "K+"){
Particle *p = new Particle(KPlus, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "K0"){
Particle *p = new Particle(KZero, zero, rcol);
list.push_back(p);
}
else if(particle_types[n][j] == "K0b"){
Particle *p = new Particle(KZeroBar, zero, rcol);
list.push_back(p);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading nbar FS files");
for(G4int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
}
}
}
}
else{ //nbar = pbar (>1000 MeV/c)
const G4double totalpnbar = KinematicsUtils::compute_xs(BFMM6, plab)*KinematicsUtils::compute_xs(BFMM471, plab)/KinematicsUtils::compute_xs(BFMM1, plab);
// xs is same for npbar, but the fs has different charge
@@ -570,7 +885,7 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
// Default condition
if(rdm < (1.-kaonicFSprob)){ // pionic/kaonic choice
INCL_DEBUG("pionic pnbar final state chosen" << '\n');
sum = read_file(dataPathpnbar, probabilities, particle_types);
sum = read_file(dataPathnbarp, probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.95 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
@@ -605,7 +920,7 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
} // end of pionic option
else{
INCL_DEBUG("kaonic pnbar final state chosen" << '\n');
sum = read_file(dataPathnpbark, probabilities, particle_types);
sum = read_file(dataPathnbarpk, probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//3837 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
@@ -654,10 +969,143 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
}
} // end of kaonic option
} // end of default annihilation
}//end of nbarp & pbarn ( with Plab < 1 GeV/c)
} //end of else for IsOnlyPion
}
else{ //ppbar or nnbar
//std::cout << "ppbar or nnbar"<< std::endl;
if(IsOnlyPion){
const std::vector<G4double> channels_Ratio = {0.0005, 0.0278, 0.0052, 0.3058, 0.0017, 0.3346, 0.0017, 0.0688, 0.2534, 0.0005};//Taken from inflightppbarFS.dat and renormalised
if(rdm < channels_Ratio.front()){
Particle *p1 = new Particle(PiZero, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1]){
Particle *p1 = new Particle(PiZero, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2]){
Particle *p1 = new Particle(PiZero, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] ){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4]){
Particle *p1 = new Particle(PiZero, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6]){
Particle *p1 = new Particle(PiZero, zero, rcol);
Particle *p2 = new Particle(PiZero, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6] + channels_Ratio[7]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6] + channels_Ratio[7] + channels_Ratio[8]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiPlus, zero, rcol);
Particle *p3 = new Particle(PiMinus, zero, rcol);
Particle *p4 = new Particle(PiMinus, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
}
else if(rdm < channels_Ratio.front() + channels_Ratio[1] + channels_Ratio[2] + channels_Ratio[3] + channels_Ratio[4] + channels_Ratio[5] + channels_Ratio[6] + channels_Ratio[7] + channels_Ratio[8] + channels_Ratio[9]){
Particle *p1 = new Particle(PiPlus, zero, rcol);
Particle *p2 = new Particle(PiMinus, zero, rcol);
Particle *p3 = new Particle(PiZero, zero, rcol);
Particle *p4 = new Particle(PiZero, zero, rcol);
Particle *p5 = new Particle(PiZero, zero, rcol);
Particle *p6 = new Particle(PiZero, zero, rcol);
Particle *p7 = new Particle(PiZero, zero, rcol);
list.push_back(p1);
list.push_back(p2);
list.push_back(p3);
list.push_back(p4);
list.push_back(p5);
list.push_back(p6);
list.push_back(p7);
}
else{
INCL_ERROR("random draw outside channels for OnlyPion annihilation (low energy)");
}
}
else{
const G4double totalppbar = KinematicsUtils::compute_xs(BFMM6, plab);
// same for nnbar
@@ -1044,6 +1492,7 @@ void NNbarToAnnihilationChannel::fillFinalState(FinalState *fs) {
}
} // end of kaonic option
} // end of default condition
} //end of else for IsOnlyPion
} // end of ppbar and nnbar case
@@ -109,8 +109,8 @@ namespace G4INCL {
// ppbar total is same as for nnbar
const G4double totalppbar = KinematicsUtils::compute_xs(BFMM167, plab) +KinematicsUtils::compute_xs(std::move(BFMM198), plab) +2*KinematicsUtils::compute_xs(BFMM490, plab);
const G4double totalpnbar = KinematicsUtils::compute_xs(BFMM492, plab) +KinematicsUtils::compute_xs(std::move(BFMM494), plab) +2*KinematicsUtils::compute_xs(BFMM490, plab);
//totalnnbar == totalppbar;
//totalpnbar == totalnpbar;
const G4double totalnnbar = totalppbar;
const G4double totalnpbar = totalpnbar;
ParticleType Pion1;
ParticleType Pion2;
@@ -179,7 +179,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // n pbar pi+ pi+ case
else if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // n pbar pi+ pi+ case
Pion1 = PiPlus;
Pion2 = PiPlus;
if(rdm<0.5){
@@ -191,7 +191,7 @@ namespace G4INCL {
antinucleon->setType(Neutron);
}
}
else if(rdm*totalppbar < 2*KinematicsUtils::compute_xs(std::move(BFMM490), plab)+KinematicsUtils::compute_xs(std::move(BFMM492), plab)){ // n nbar pi+ pi0 case
else if(rdm*totalpnbar < 2*KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // n nbar pi+ pi0 case
Pion1 = PiZero;
Pion2 = PiPlus;
if(rdm<0.5){
@@ -219,7 +219,7 @@ namespace G4INCL {
}
else{ // neutron
if(antinucleon->getType()==antiProton){ //npbar case
if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM490, plab)){ // p pbar pi- pi0 case
if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM490, plab)){ // p pbar pi- pi0 case
Pion1 = PiZero;
Pion2 = PiMinus;
if(rdm<0.5){
@@ -231,7 +231,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // p nbar pi- pi- case
else if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // p nbar pi- pi- case
Pion1 = PiMinus;
Pion2 = PiMinus;
if(rdm<0.5){
@@ -243,7 +243,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < 2*KinematicsUtils::compute_xs(std::move(BFMM490), plab)+KinematicsUtils::compute_xs(std::move(BFMM492), plab)){ // n nbar pi- pi0 case
else if(rdm*totalnpbar < 2*KinematicsUtils::compute_xs(BFMM490, plab)+KinematicsUtils::compute_xs(BFMM492, plab)){ // n nbar pi- pi0 case
Pion1 = PiZero;
Pion2 = PiMinus;
if(rdm<0.5){
@@ -269,7 +269,7 @@ namespace G4INCL {
}
}
else{ //antiNeutron (nnbar case)
if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM167, plab)){ // nnbarpi-pi+ case
if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM167, plab)){ // nnbarpi-pi+ case
Pion1 = PiMinus;
Pion2 = PiPlus;
if(rdm<0.5){
@@ -281,7 +281,7 @@ namespace G4INCL {
antinucleon->setType(Neutron);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM167, plab)+KinematicsUtils::compute_xs(BFMM490, plab)){ //pnbarpi-pi0 case
else if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM167, plab)+KinematicsUtils::compute_xs(BFMM490, plab)){ //pnbarpi-pi0 case
Pion1 = PiMinus;
Pion2 = PiZero;
if(rdm<0.5){
@@ -293,7 +293,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(std::move(BFMM167), plab)+2*KinematicsUtils::compute_xs(std::move(BFMM490), plab)){ //npbarpi+pi0 case
else if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM167, plab)+2*KinematicsUtils::compute_xs(BFMM490, plab)){ //npbarpi+pi0 case
Pion1 = PiPlus;
Pion2 = PiZero;
if(rdm<0.5){
@@ -113,8 +113,8 @@ namespace G4INCL {
+KinematicsUtils::compute_xs(BFMM197, plab)
+2*KinematicsUtils::compute_xs(BFMM169, plab);
//totalnnbar == totalppbar;
//totalpnbar == totalnpbar;
const G4double totalnnbar = totalppbar;
const G4double totalnpbar = totalpnbar;
ParticleType Pion1;
ParticleType Pion2;
ParticleType Pion3;
@@ -192,7 +192,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM169, plab)
else if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM169, plab)
+KinematicsUtils::compute_xs(BFMM197, plab)){ // n pbar 2pi+ pi0 case
Pion1 = PiPlus;
Pion2 = PiPlus;
@@ -206,7 +206,7 @@ namespace G4INCL {
antinucleon->setType(Neutron);
}
}
else if(rdm*totalppbar < 2*KinematicsUtils::compute_xs(std::move(BFMM169), plab)
else if(rdm*totalpnbar < 2*KinematicsUtils::compute_xs(BFMM169, plab)
+KinematicsUtils::compute_xs(std::move(BFMM197), plab)){ // n nbar 2pi+ pi- case
Pion1 = PiPlus;
Pion2 = PiPlus;
@@ -237,7 +237,7 @@ namespace G4INCL {
}
else{ // neutron
if(antinucleon->getType()==antiProton){ //npbar case
if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM169, plab)){ // p pbar 2pi- pi+ case
if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM169, plab)){ // p pbar 2pi- pi+ case
Pion1 = PiPlus;
Pion2 = PiMinus;
Pion3 = PiMinus;
@@ -250,7 +250,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM169, plab)
else if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM169, plab)
+KinematicsUtils::compute_xs(BFMM197, plab)){ // p nbar 2pi- pi0 case
Pion1 = PiMinus;
Pion2 = PiMinus;
@@ -264,7 +264,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < 2*KinematicsUtils::compute_xs(std::move(BFMM169), plab)
else if(rdm*totalnpbar < 2*KinematicsUtils::compute_xs(BFMM169, plab)
+KinematicsUtils::compute_xs(std::move(BFMM197), plab)){ // n nbar 2pi- pi+ case
Pion1 = PiPlus;
Pion2 = PiMinus;
@@ -293,7 +293,7 @@ namespace G4INCL {
}
}
else{ //antiNeutron (nnbar case)
if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM161, plab)){ // n nbar pi+ pi- pi0 case
if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM161, plab)){ // n nbar pi+ pi- pi0 case
Pion1 = PiMinus;
Pion2 = PiPlus;
Pion3 = PiZero;
@@ -306,7 +306,7 @@ namespace G4INCL {
antinucleon->setType(Neutron);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(BFMM161, plab)
else if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM161, plab)
+KinematicsUtils::compute_xs(BFMM169, plab)){ //p nbar 2pi- pi+ case
Pion1 = PiMinus;
Pion2 = PiMinus;
@@ -320,7 +320,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(std::move(BFMM161), plab)
else if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM161, plab)
+KinematicsUtils::compute_xs(std::move(BFMM169), plab)
+KinematicsUtils::compute_xs(std::move(BFMM201), plab)){ //n pbar 2pi+ pi- case
Pion1 = PiPlus;
@@ -110,8 +110,8 @@ namespace G4INCL {
// ppbar total is same as for nnbar
const G4double totalppbar = KinematicsUtils::compute_xs(std::move(BFMM199), plab) +KinematicsUtils::compute_xs(BFMM185, plab) +KinematicsUtils::compute_xs(BFMM188, plab);
const G4double totalpnbar = KinematicsUtils::compute_xs(BFMM491, plab) +KinematicsUtils::compute_xs(BFMM495, plab) +KinematicsUtils::compute_xs(BFMM188, plab);
//totalnnbar == totalppbar;
//totalpnbar == totalnpbar;
const G4double totalnnbar = totalppbar;
const G4double totalnpbar = totalpnbar;
ParticleType PionType;
//setting types of new particles
@@ -163,7 +163,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(std::move(BFMM491), plab)+KinematicsUtils::compute_xs(std::move(BFMM495), plab)){ //pnbarpi0 case
else if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM491, plab)+KinematicsUtils::compute_xs(BFMM495, plab)){ //pnbarpi0 case
PionType = PiZero;
if(rdm<0.5){
nucleon->setType(Proton);
@@ -189,7 +189,7 @@ namespace G4INCL {
}
else{ // neutron
if(antinucleon->getType()==antiProton){ //npbar case
if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM491, plab)){ // ppbarpi- case
if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM491, plab)){ // ppbarpi- case
PionType = PiMinus;
if(rdm<0.5){
nucleon->setType(Proton);
@@ -200,7 +200,7 @@ namespace G4INCL {
antinucleon->setType(Proton);
}
}
else if(rdm*totalppbar < KinematicsUtils::compute_xs(std::move(BFMM491), plab)+KinematicsUtils::compute_xs(std::move(BFMM495), plab)){ //npbarpi0 case
else if(rdm*totalnpbar < KinematicsUtils::compute_xs(BFMM491, plab)+KinematicsUtils::compute_xs(BFMM495, plab)){ //npbarpi0 case
PionType = PiZero;
if(rdm<0.5){
nucleon->setType(Neutron);
@@ -224,7 +224,7 @@ namespace G4INCL {
}
}
else{ //antiNeutron (nnbar case)
if(rdm*totalpnbar < KinematicsUtils::compute_xs(BFMM185, plab)){ // nnbarpi0 case
if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM185, plab)){ // nnbarpi0 case
PionType = PiZero;
if(rdm<0.5){
nucleon->setType(Neutron);
@@ -235,7 +235,7 @@ namespace G4INCL {
antinucleon->setType(Neutron);
}
}
else if(rdm*totalpnbar < KinematicsUtils::compute_xs(std::move(BFMM185), plab)+KinematicsUtils::compute_xs(std::move(BFMM188), plab)){ //pnbarpi- case
else if(rdm*totalnnbar < KinematicsUtils::compute_xs(BFMM185, plab)+KinematicsUtils::compute_xs(BFMM188, plab)){ //pnbarpi- case
PionType = PiMinus;
if(rdm<0.5){
nucleon->setType(Proton);
@@ -0,0 +1,682 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* G4INCLNbarAtrestEntryChannel.cc
*
* \date Aug 9, 2024
* \author Olivier Lourgo
*/
#ifdef INCLXX_IN_GEANT4_MODE
#include "G4EnvironmentUtils.hh"
#endif
#include "G4INCLNbarAtrestEntryChannel.hh"
#include "G4INCLRootFinder.hh"
#include "G4INCLIntersection.hh"
#include "G4INCLCascade.hh"
#include <algorithm>
#include "G4INCLParticle.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLBinaryCollisionAvatar.hh"
#include "G4INCLRandom.hh"
#include "G4INCLGlobals.hh"
#include "G4INCLLogger.hh"
#include <algorithm>
#include "G4INCLPhaseSpaceGenerator.hh"
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include "G4INCLHFB.hh"
#include "G4INCLParticleEntryAvatar.hh"
#include "G4INCLNuclearDensityFactory.hh"
#include "G4INCLNDFWoodsSaxon.hh"
#include "G4INCLNDFModifiedHarmonicOscillator.hh"
#include "G4INCLNDFGaussian.hh"
#include "G4INCLNDFParis.hh"
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
namespace G4INCL{
NbarAtrestEntryChannel::NbarAtrestEntryChannel(Nucleus *n, Particle *p)
:theNucleus(n), theParticle(p)
{}
NbarAtrestEntryChannel::~NbarAtrestEntryChannel(){}
G4double NbarAtrestEntryChannel::read_file(std::string filename, std::vector<G4double>& probabilities, std::vector<std::vector<std::string>>& particle_types){
std::ifstream file(filename);
G4double sum_probs =0.0;
if (file.is_open()){
std::string line;
while(getline(file,line)){
std::istringstream iss(line);
G4double prob;
iss >> prob;
sum_probs += prob;
probabilities.push_back(prob);
std::vector<std::string> types;
std::string type;
while (iss >>type){
types.push_back(type);
}
particle_types.push_back(types);
}
}
else std::cout << "ERROR no fread_file " << filename << std::endl;
return sum_probs;
}
G4int NbarAtrestEntryChannel::findStringNumber(G4double rdm, std::vector<G4double> yields){
G4int stringNumber =-1;
G4double smallestsum =0.0;
G4double biggestsum = yields[0];
for (G4int i=0; i < static_cast<G4int>(yields.size() -1);i++){
if (rdm >= smallestsum && rdm <= biggestsum){
stringNumber = i+1;
}
smallestsum += yields[i];
biggestsum += yields[i+1];
}
if (stringNumber==-1) stringNumber = static_cast<G4int>(yields.size());
if (stringNumber==-1){
INCL_ERROR("ERROR in findStringNumber (stringNumber=-1)");
std::cout << "ERROR in findStringNumber" << std::endl;
}
return stringNumber;
}
G4double NbarAtrestEntryChannel::Pabs(G4double x, G4double value){
const G4double r = value; // center of the gaussian
const G4double sigma = 1;
return std::exp(-std::pow(x-r,2)/(2*sigma*sigma));
}
G4double NbarAtrestEntryChannel::densityP(){ // return the r at which the gaussian of the interaction Probability(Pabs) is centered
const G4bool isProton = ProtonIsTheVictim();
G4int Z = theNucleus->getZ(); //was modified in Cascade.cc
G4int A = theNucleus->getA(); //was modified in Cascade.cc
G4double threshold_density = 0.10; //the maximum of the interaction probability is taken at 10% of maximum density
//https://doi.org/10.1016/0375-9474(82)90352-9 , Nuclear absorption of stopped antiprotons: Multipion-nucleus interactions, Iljinov, Nazaruk, Chigrinov
A++; //restoration of original A value before annihilation
if(isProton == true){Z++;} //restoration of original Z value before annihilation
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){A++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarNPbarPType){Z++;}
if(A > 19) {
G4double radius = ParticleTable::getRadiusParameter(Proton, A, Z);
G4double diffuseness = ParticleTable::getSurfaceDiffuseness(Proton, A, Z);
G4double r_10 = diffuseness*std::log((1/threshold_density)-1) + radius; //Radius for a Wood-Saxon
return r_10;
}else if(A <= 19 && A > 6) {
G4double radius = ParticleTable::getRadiusParameter(Proton, A, Z);
G4double diffuseness = ParticleTable::getSurfaceDiffuseness(Proton, A, Z);
G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, A, Z);
NuclearDensityFunctions::ModifiedHarmonicOscillator rDensityFunction(radius, maximumRadius, diffuseness);
//double r_10 = 0.01;
//while (rDensityFunction(r_10)/(r_10*r_10) > threshold_density*rDensityFunction(0.01)/(0.01*0.01)) {
// r_10 = r_10 + maximumRadius/100. ;
//}
G4double r_min = 0.01;
G4double r_max = maximumRadius;
G4double r_10 = (r_min + r_max)/2.;
while ((rDensityFunction(r_10)/(r_10*r_10) > 0.11*rDensityFunction(0.01)/(0.01*0.01)) ||
(rDensityFunction(r_10)/(r_10*r_10) < 0.09*rDensityFunction(0.01)/(0.01*0.01))) {
if (rDensityFunction(r_10)/(r_10*r_10) > 0.11*rDensityFunction(0.01)/(0.01*0.01)) {
r_min = r_10;
}
else {
r_max = r_10;
}
r_10 = (r_min + r_max)/2.;
}
return r_10;
}else if(A <= 6 && A > 2) { // Gaussian distribution for light nuclei
G4double radius = ParticleTable::getRadiusParameter(Proton, A, Z);
G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, A, Z);
NuclearDensityFunctions::Gaussian rDensityFunction(maximumRadius, Math::oneOverSqrtThree * radius);
//double r_10=std::sqrt(std::pow(Math::oneOverSqrtThree * radius,2)*std::log(2)); //start when the density is half the maximum
//while (rDensityFunction(r_10)/(r_10*r_10) > threshold_density*rDensityFunction(0.01)/(0.01*0.01)) {
// r_10 = r_10 + maximumRadius/500. ;
//}
G4double r_min = 0.01;
G4double r_max = maximumRadius;
G4double r_10 = (r_min + r_max)/2.;
while ((rDensityFunction(r_10)/(r_10*r_10) > 0.11*rDensityFunction(0.01)/(0.01*0.01)) ||
(rDensityFunction(r_10)/(r_10*r_10) < 0.09*rDensityFunction(0.01)/(0.01*0.01))) {
if (rDensityFunction(r_10)/(r_10*r_10) > 0.11*rDensityFunction(0.01)/(0.01*0.01)) {
r_min = r_10;
}
else {
r_max = r_10;
}
r_10 = (r_min + r_max)/2.;
}
return r_10;
}else {
INCL_ERROR("No nuclear density function for target A = "
<< A << " Z = " << Z << '\n');
return 0.0;
}
}
G4double NbarAtrestEntryChannel::densityN(){
const G4bool isProton = ProtonIsTheVictim();
G4int Z = theNucleus->getZ(); //was modified in Cascade.cc
G4int A = theNucleus->getA(); //was modified in Cascade.cc
G4double threshold_density = 0.10; //the maximum of the interaction probability is taken at 10% of maximum density
//https://doi.org/10.1016/0375-9474(82)90352-9 , Nuclear absorption of stopped antiprotons: Multipion-nucleus interactions, Iljinov, Nazaruk, Chigrinov
A++; //restoration of original A value before annihilation
if(isProton == true){Z++;} //restoration of original Z value before annihilation
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){A++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarNPbarPType){Z++;}
if(A > 19) {
G4double radius = ParticleTable::getRadiusParameter(Neutron, A, Z);
G4double diffuseness = ParticleTable::getSurfaceDiffuseness(Neutron, A, Z);
G4double r_10 = diffuseness*std::log((1/threshold_density)-1) + radius; //Radius for a Wood-Saxon
return r_10;
} else if(A <= 19 && A > 6) {
G4double radius = ParticleTable::getRadiusParameter(Neutron, A, Z);
G4double diffuseness = ParticleTable::getSurfaceDiffuseness(Neutron, A, Z);
G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, A, Z);
NuclearDensityFunctions::ModifiedHarmonicOscillator rDensityFunction(radius, maximumRadius, diffuseness);
G4double r_10 = 0.01;
while (rDensityFunction(r_10)/(r_10*r_10) > threshold_density*rDensityFunction(0.01)/(0.01*0.01)) {
r_10 = r_10 + maximumRadius/100. ;
}
return r_10;
} else if(A <= 6 && A > 2) { // Gaussian distribution for light nuclei
G4double radius = ParticleTable::getRadiusParameter(Neutron, A, Z);
G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, A, Z);
NuclearDensityFunctions::Gaussian rDensityFunction(maximumRadius, Math::oneOverSqrtThree * radius);
G4double r_10=std::sqrt(std::pow(Math::oneOverSqrtThree * radius,2)*std::log(2)); //start when the density is half the maximum
while (rDensityFunction(r_10)/(r_10*r_10) > threshold_density*rDensityFunction(0.01)/(0.01*0.01)) {
r_10 = r_10 + maximumRadius/500. ;
}
return r_10;
} else {
INCL_ERROR("No nuclear density function for target A = "
<< A << " Z = " << Z << '\n');
return 0.0;
}
}
G4double NbarAtrestEntryChannel::overlapN(G4double &x){
return Pabs(x,densityN());
}
G4double NbarAtrestEntryChannel::overlapP(G4double &x){
return Pabs(x,densityP());
}
ParticleList NbarAtrestEntryChannel::makeMesonStar() {//This function creates a set of mesons with momenta
// File names
#ifdef INCLXX_IN_GEANT4_MODE
if(!G4FindDataDir("G4INCLDATA")) {
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4INCLDATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the INCL++ model" << G4endl;
G4Exception("G4INCLDataFile::readData()","rawppbarFS.dat, ...",
FatalException, ed);
}
G4String dataPath0{G4FindDataDir("G4INCLDATA")};
G4String dataPathnbarp(dataPath0 + "/rawnbarpFS.dat");
G4String dataPathnbarn(dataPath0 + "/rawnbarnFS.dat");
G4String dataPathnbarnk(dataPath0 + "/rawppbarFSkaonic.dat");
G4String dataPathnbarpk(dataPath0 + "/rawnbarpFSkaonic.dat");
#else
Config const *theConfig=theNucleus->getStore()->getConfig();
std::string path;
if(theConfig)
path = theConfig->getINCLXXDataFilePath();
std::string dataPathnbarn(path + "/rawnbarnFS.dat");
INCL_DEBUG("Reading nbarn final states" << dataPathnbarn << '\n');
std::string dataPathnbarp(path + "/rawnbarpFS.dat");
INCL_DEBUG("Reading nbarp final states" << dataPathnbarp << '\n');
std::string dataPathnbarnk(path + "/rawppbarFSkaonic.dat");
INCL_DEBUG("Reading nbarn kaonic final states" << dataPathnbarnk << '\n');
std::string dataPathnbarpk(path + "/rawnbarpFSkaonic.dat");
INCL_DEBUG("Reading nbarp kaonic final states" << dataPathnbarpk << '\n');
#endif
//read probabilities and particle types from file
std::vector<G4double> probabilities; //will store each FS yield
std::vector<std::vector<std::string>> particle_types; //will store particle names
G4double sum; //will contain a sum of probabilities of all FS in the file
G4double kaonicFSprob=0.05; //probability to kave kaonic FS
const G4bool isProton = ProtonIsTheVictim();
G4int z = theNucleus->getZ(); //was modified in Cascade.cc
G4int a = theNucleus->getA(); //was modified in Cascade.cc
a++; //restoration of original A value before annihilation
if(isProton == true){z++;} //restoration of original Z value before annihilation
ThreeVector annihilationPosition;
ParticleList starlist;
ThreeVector mommy; //momentum to be assigned later
//LETS GOOOOOOO!!!
G4double rdm = Random::shoot();
if(isProton == true){ //protonic annihilation
INCL_DEBUG("Proton is the victim" << '\n');
if(rdm < (1.-kaonicFSprob)){ // pionic FS was chosen
INCL_DEBUG("pionic pp final state chosen" << '\n');
sum = read_file(dataPathnbarp, probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "rho-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
}
else if(particle_types[n][j] == "rho+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
}
else if(particle_types[n][j] == "rho0"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(pp);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for(G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
}
}
}
else{
INCL_DEBUG("kaonic pp final state chosen" << '\n');
sum = read_file(dataPathnbarpk, probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K-"){
Particle *p = new Particle(KMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K+"){
Particle *p = new Particle(KPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K0"){
Particle *p = new Particle(KZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K0b"){
Particle *p = new Particle(KZeroBar, mommy, annihilationPosition);
starlist.push_back(p);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for(G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
}
}
}
}
else{ //neutronic annihilation
INCL_DEBUG("Neutron is the victim" << '\n');
if(rdm < (1.-kaonicFSprob)){ // pionic/kaonic choice
INCL_DEBUG("pionic np final state chosen" << '\n');
sum = read_file(dataPathnbarn, probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.95 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "rho-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
}
else if(particle_types[n][j] == "rho+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(pp);
}
else if(particle_types[n][j] == "rho0"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
Particle *pp = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(pp);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for(G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
}
}
}
else{
INCL_DEBUG("kaonic np final state chosen" << '\n');
sum = read_file(dataPathnbarnk, probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//3837 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi-"){
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "pi+"){
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "omega"){
Particle *p = new Particle(Omega, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "eta"){
Particle *p = new Particle(Eta, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K-"){
Particle *p = new Particle(KMinus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K+"){
Particle *p = new Particle(KPlus, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K0"){
Particle *p = new Particle(KZero, mommy, annihilationPosition);
starlist.push_back(p);
}
else if(particle_types[n][j] == "K0b"){
Particle *p = new Particle(KZeroBar, mommy, annihilationPosition);
starlist.push_back(p);
}
else{
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for(G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++){
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
}
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
}
}
}
}
// Correction to the Q-value of the entering particle
G4int stra = theNucleus->getS();
G4double energyOfMesonStar;
if(theNucleus->isNucleusNucleusCollision()==false){//antiNeutron
if(isProton == true){
energyOfMesonStar = theParticle->getEnergy() + ParticleTable::getTableMass(a,z,stra)
-ParticleTable::getTableMass(a-1,z,stra);
}
else{
energyOfMesonStar = theParticle->getEnergy() + ParticleTable::getTableMass(a,z,stra)
-ParticleTable::getTableMass(a-1,z,stra);
}
} else if(theNucleus->isNucleusNucleusCollision()==true){//antiComposite : job is done in the Antinuclei file
return starlist;
}
//compute energies of mesons with a phase-space model
if(starlist.size() < 2){
INCL_ERROR("should never happen, at least 2 final state particles!" << '\n');
}
else if(starlist.size() == 2){
ParticleIter first = starlist.begin();
ParticleIter last = std::next(first, 1); //starlist.end() gives an error of segfault, idk why
G4double m1 = (*first)->getMass();
G4double m2 = (*last)->getMass();
G4double s = energyOfMesonStar*energyOfMesonStar;
G4double mom1 = std::sqrt(s/4 - (std::pow(m1,2) + std::pow(m2,2))/2 - std::pow(m1,2)*std::pow(m2,2)/s + (std::pow(m1,4) + 2*std::pow(m1*m2,2) + std::pow(m2,4))/(4*s));
ThreeVector momentello = Random::normVector(mom1); //like raffaello :)
(*first)->setMomentum(momentello);
(*first)->adjustEnergyFromMomentum();
(*last)->setMomentum(-momentello);
(*last)->adjustEnergyFromMomentum();
//std::cout << (*first)->getEnergy() << std::endl;
}
else{
PhaseSpaceGenerator::generate(energyOfMesonStar, starlist);
//ParticleIter first = starlist.begin();
//std::cout << (*first)->getEnergy() << std::endl;
//ParticleIter last = std::next(first, 1);
//std::cout << (*last)->getEnergy() << std::endl;
}
return starlist;
}
G4bool NbarAtrestEntryChannel::ProtonIsTheVictim(){
if(theNucleus->getAnnihilationType() == PType || theNucleus->getAnnihilationType() == DNbarPPbarPType || theNucleus->getAnnihilationType() == DNbarPPbarNType ){
return true; //a proton is annihilated
}
else if(theNucleus->getAnnihilationType() == NType || theNucleus->getAnnihilationType() == DNbarNPbarPType || theNucleus->getAnnihilationType() == DNbarNPbarNType){
return false; // a neutron is annihilated
}
else{
INCL_ERROR("should never happen, n or p is your only choise" << '\n');
G4double rdm3 = Random::shoot();
if(rdm3 >= 0.){
return false;
}
else{
return true;
}
}
}
ThreeVector NbarAtrestEntryChannel::getAnnihilationPosition(){
const G4bool isProton = ProtonIsTheVictim();
G4int z = theNucleus->getZ(); //was modified in Cascade.cc
G4int a = theNucleus->getA(); //was modified in Cascade.cc
a++;
if(isProton == true){z++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){a++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarNPbarPType){z++;}
G4double Rpmax = ParticleTable::getMaximumNuclearRadius(Proton, a, z);
G4double Rnmax = ParticleTable::getMaximumNuclearRadius(Neutron, a, z);
G4double probabilitymax = 0.; //the max value of the probability distribution
G4double probability = 0.0;
G4double radius;
//now we compute the max value of the probability distribution...
if(isProton == true){
for(radius = 0.0; radius < Rpmax; radius = radius + 0.001){
probability = overlapP(radius);
//INCL_WARN("radius, densityP, overlapP: " << radius << " " << densityP(radius) << " " << probability << '\n');
if(probability > probabilitymax)
probabilitymax = probability; //now it should be the max value of overlapP function
}
}
else{ //neutron
for(radius = 0.0; radius < Rnmax; radius = radius + 0.001){
probability = overlapN(radius);
//INCL_WARN("radius, densityN, overlapN: " << radius << " " << densityN(radius) << " " << probability << '\n');
if(probability > probabilitymax)
probabilitymax = probability; //now it should be the max value of overlapP function
}
}
//we know the limits! start rejection algorithm!
G4double x = 0., y = 0.0001, p_for_x = 0.;
G4double distance = 0.;
if(isProton == true){
while(y >= p_for_x){
x = Random::shoot() * Rpmax; // create uniformly random r
y = Random::shoot() * probabilitymax; // create uniformly random prob
p_for_x = overlapP(x); //probability call for comparison
if(y <= p_for_x){ //first cut-off is introduced for computational volume reduction
distance = x;
}
}
}
else{
while(y >= p_for_x){
x = Random::shoot() * Rnmax; // create uniformly random r
y = Random::shoot() * probabilitymax; // create uniformly random prob
p_for_x = overlapN(x); //probability call for comparison
if(y <= p_for_x){ //first cut-off is introduced for computational volume reduction
distance = x;
}
}
}
//FINAL POSITION VECTOR
//ThreeVector annihilationPosition(0., 0., -distance); //3D sphere of distance radius
G4double ctheta = (1.-2.*Random::shoot());
G4double stheta = std::sqrt(1.-ctheta*ctheta);
G4double phi = Math::twoPi*Random::shoot();
ThreeVector annihilationPosition(distance*stheta * std::cos(phi), distance*stheta * std::sin(phi), distance*ctheta); //3D sphere of distance radius
return annihilationPosition;
}
IAvatarList NbarAtrestEntryChannel::bringMesonStar(ParticleList const &pL, Nucleus * const n) {
ThreeVector ann_position = getAnnihilationPosition();
IAvatarList theAvatarList;
for(ParticleIter p = pL.begin(), e = pL.end(); p!=e; ++p){
(*p)->setPosition(ann_position);
theAvatarList.push_back(new ParticleEntryAvatar(0.0, n, *p, ANAR));
}
return theAvatarList;
}
void NbarAtrestEntryChannel::fillFinalState(FinalState *fs) {
//const bool isProton = ProtonIsTheVictim();
//int z = theNucleus->getZ(); //was modified in Cascade.cc
//int a = theNucleus->getA(); //was modified in Cascade.cc
//a++; //restoration of original A value before annihilation
//if(isProton == true){z++;} //restoration of original Z value before annihilation
const G4double energyBefore = theParticle->getEnergy();
fs->addEnteringParticle(theParticle);
INCL_DEBUG("Entering particle added " << '\n');
fs->setTotalEnergyBeforeInteraction(energyBefore);
}
}
@@ -186,6 +186,7 @@ namespace G4INCL {
transmissionRadius[antiSigmaMinus] = theProtonTransmissionRadius;
transmissionRadius[XiMinus] = theProtonTransmissionRadius;
transmissionRadius[antiXiMinus] = theProtonTransmissionRadius;
transmissionRadius[antiComposite] = theProtonNuclearRadius;
// transmission radii for neutral particles intentionally left uninitialised
}
@@ -124,12 +124,15 @@ namespace G4INCL {
}
InterpolationTable *createRCDFTable(const ParticleType t, const G4int A, const G4int Z) {
// assert(t==Proton || t==Neutron || t==Lambda);
// assert(t==Proton || t==Neutron || t==Lambda || t==antiNeutron || t==antiProton);
if(!rCDFTableCache)
rCDFTableCache = new std::map<G4int,InterpolationTable*>;
const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
if (A<0){
nuclideID = ((t==antiProton) ? 1000 : -1000)*(-Z) + (-A);
}
const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rCDFTableCache->find(nuclideID);
if(mapEntry == rCDFTableCache->end()) {
@@ -148,7 +151,7 @@ namespace G4INCL {
G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
rDensityFunction = new NuclearDensityFunctions::Gaussian(maximumRadius, Math::oneOverSqrtThree * radius);
} else if(A == 2 && Z == 1) { // density from the Paris potential for deuterons
} else if((A == 2 && Z == 1) || (A ==-2 && Z==-1)){ // density from the Paris potential for deuterons & antideuterons
rDensityFunction = new NuclearDensityFunctions::ParisR();
} else {
INCL_ERROR("No nuclear density function for target A = "
@@ -169,12 +172,15 @@ namespace G4INCL {
}
InterpolationTable *createPCDFTable(const ParticleType t, const G4int A, const G4int Z) {
// assert(t==Proton || t==Neutron || t==Lambda);
// assert(t==Proton || t==Neutron || t==Lambda || t==antiNeutron || t==antiProton);
if(!pCDFTableCache)
pCDFTableCache = new std::map<G4int,InterpolationTable*>;
const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
if (A<0){
nuclideID = ((t==antiProton) ? 1000 : -1000)*(-Z) + (-A);
}
const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = pCDFTableCache->find(nuclideID);
if(mapEntry == pCDFTableCache->end()) {
IFunction1D *pDensityFunction;
@@ -184,7 +190,7 @@ namespace G4INCL {
} else if(A <= 19 && A > 2) { // Gaussian distribution for light nuclei
const G4double momentumRMS = Math::oneOverSqrtThree * ParticleTable::getMomentumRMS(A, Z);
pDensityFunction = new NuclearDensityFunctions::Gaussian(5.*momentumRMS, momentumRMS);
} else if(A == 2 && Z == 1) { // density from the Paris potential for deuterons
} else if((A == 2 && Z == 1) || (A ==-2 && Z==-1)) { // density from the Paris potential for deuterons & antideuterons
pDensityFunction = new NuclearDensityFunctions::ParisP();
} else {
INCL_ERROR("No nuclear density function for target A = "
@@ -107,6 +107,7 @@ namespace G4INCL {
vLambda = 30.;
vantiProton = 100.;
vantiNeutron = 50.;
const G4double asy = (theA - 2.*theZ)/theA;
// Jose Luis Rodriguez-Sanchez et al., Rapid Communication PRC 98, 021602 (2018)
@@ -114,7 +115,9 @@ namespace G4INCL {
else if (asy > 0.133) vLambda = 56.549 - 678.73*asy + 4905.35*asy*asy - 9789.1*asy*asy*asy;
const G4double theLambdaSeparationEnergy = ParticleTable::getSeparationEnergy(Lambda,theA,theZ);
const G4double theantiLambdaSeparationEnergy = ParticleTable::getSeparationEnergy(antiLambda,theA,theZ);
const G4double theantiProtonSeparationEnergy = ParticleTable::getSeparationEnergy(antiProton,theA,theZ);
const G4double theantiNeutronSeparationEnergy = ParticleTable::getSeparationEnergy(antiNeutron,theA,theZ);
separationEnergy[PiPlus] = theProtonSeparationEnergy - theNeutronSeparationEnergy;
separationEnergy[PiZero] = 0.;
@@ -130,6 +133,11 @@ namespace G4INCL {
separationEnergy[SigmaZero] = theLambdaSeparationEnergy;
separationEnergy[SigmaMinus] = theNeutronSeparationEnergy + theLambdaSeparationEnergy - theProtonSeparationEnergy;
separationEnergy[antiLambda] = theantiLambdaSeparationEnergy;
separationEnergy[antiSigmaPlus] = theantiProtonSeparationEnergy + theantiLambdaSeparationEnergy - theantiNeutronSeparationEnergy;
separationEnergy[antiSigmaZero] = theantiLambdaSeparationEnergy;
separationEnergy[antiSigmaMinus] = theantiNeutronSeparationEnergy + theantiLambdaSeparationEnergy - theantiProtonSeparationEnergy;
separationEnergy[KPlus] = theProtonSeparationEnergy - theLambdaSeparationEnergy;
separationEnergy[KZero] = (theNeutronSeparationEnergy - theLambdaSeparationEnergy);
separationEnergy[KZeroBar] = (theLambdaSeparationEnergy - theNeutronSeparationEnergy);
@@ -139,6 +147,7 @@ namespace G4INCL {
separationEnergy[KLong] = (theNeutronSeparationEnergy - theLambdaSeparationEnergy);
separationEnergy[antiProton] = theantiProtonSeparationEnergy;
separationEnergy[antiNeutron] = theantiNeutronSeparationEnergy;
fermiEnergy[DeltaPlusPlus] = vDeltaPlusPlus - separationEnergy[DeltaPlusPlus];
fermiEnergy[DeltaPlus] = vDeltaPlus - separationEnergy[DeltaPlus];
@@ -156,6 +165,7 @@ namespace G4INCL {
fermiEnergy[SigmaMinus] = vSigmaMinus - separationEnergy[SigmaMinus];
fermiEnergy[antiProton] = vantiProton - separationEnergy[antiProton];
fermiEnergy[antiNeutron] = vantiNeutron - separationEnergy[antiNeutron];
INCL_DEBUG("Table of separation energies [MeV] for A=" << theA << ", Z=" << theZ << ":" << '\n'
<< " proton: " << separationEnergy[Proton] << '\n'
@@ -255,7 +265,7 @@ namespace G4INCL {
return vantiProton;
break;
case antiNeutron:
return vantiProton;
return vantiNeutron;
break;
case antiLambda:
return 0.0;
@@ -297,6 +307,10 @@ namespace G4INCL {
case Composite:
INCL_ERROR("No potential computed for particle of type Cluster.");
return 0.0;
break;
case antiComposite:
INCL_ERROR("No potential computed for particle of type Cluster");
return 0.0;
break;
case UnknownParticle:
INCL_ERROR("Trying to compute potential energy for an unknown particle.");
@@ -72,10 +72,12 @@ namespace G4INCL {
: Cluster(charge,mass,strangess,true),
theInitialZ(charge), theInitialA(mass), theInitialS(strangess),
theNpInitial(0), theNnInitial(0),
theNlInitial(0),
theNSpInitial(0), theNSzInitial(0), theNSmInitial(0),
theNpionplusInitial(0), theNpionminusInitial(0),
theNkaonplusInitial(0), theNkaonminusInitial(0),
theNantiprotonInitial(0),
initialInternalEnergy(0.),
theNantiprotonInitial(0),theNantineutronInitial(0),
initialInternalEnergy(0.), srcInternalEnergy(0.),
incomingAngularMomentum(0.,0.,0.), incomingMomentum(0.,0.,0.),
initialCenterOfMass(0.,0.,0.),
remnant(true),
@@ -106,6 +108,9 @@ namespace G4INCL {
if (theAType==PType) theDensity = NuclearDensityFactory::createDensity(theA+1, theZ+1, theS);
else if (theAType==NType) theDensity = NuclearDensityFactory::createDensity(theA+1, theZ, theS);
else if (theAType==DNbarNPbarNType) theDensity = NuclearDensityFactory::createDensity(theA+2, theZ, theS);
else if (theAType==DNbarPPbarPType) theDensity = NuclearDensityFactory::createDensity(theA+2, theZ+2, theS);
else if (theAType==DNbarPPbarNType || theAType==DNbarNPbarPType) theDensity = NuclearDensityFactory::createDensity(theA+2, theZ+1, theS);
else
theDensity = NuclearDensityFactory::createDensity(theA, theZ, theS);
@@ -241,10 +246,8 @@ namespace G4INCL {
totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() - ParticleTable::effectiveNucleonMass;
else if((*p)->isHyperon())
totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() - ParticleTable::getRealMass((*p)->getType());
else if((*p)->isAntiNucleon())
totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() + ParticleTable::getINCLMass(Proton) - ParticleTable::getProtonSeparationEnergy();
else if((*p)->isAntiLambda())
totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() + ParticleTable::getRealMass((*p)->getType()) - ParticleTable::getSeparationEnergyINCL(Lambda, theA, theZ);
//else if((*p)->isAntiLambda())
// totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() + ParticleTable::getRealMass((*p)->getType()) - ParticleTable::getSeparationEnergyINCL(Lambda, theA, theZ);
//std::cout << ParticleTable::getRealMass((*p)->getType()) << std::endl;}
else
totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy();
@@ -303,25 +306,7 @@ namespace G4INCL {
const G4double totalEnergy = computeTotalEnergy();
const G4double separationEnergies = computeSeparationEnergyBalance();
G4double eSep = 0;
if (getAType() == AnnihilationType::Def) {
} else if (getAType() == AnnihilationType::PType) {
} else if (getAType() == AnnihilationType::NType) {
} else if (getAType() == AnnihilationType::PTypeInFlight) {
eSep = ParticleTable::getProtonSeparationEnergy();
} else if (getAType() == AnnihilationType::NTypeInFlight) {
eSep = ParticleTable::getNeutronSeparationEnergy();
} else if (getAType() == AnnihilationType::NbarPTypeInFlight) {
eSep = ParticleTable::getProtonSeparationEnergy();
} else if (getAType() == AnnihilationType::NbarNTypeInFlight) {
eSep = ParticleTable::getNeutronSeparationEnergy();
}
if (eSep > 0. && (totalEnergy - initialInternalEnergy - separationEnergies - eSep) < 0.) {
INCL_DEBUG("Negative Excitation Energy due to a Nbar Annihilation process (separation energy of the nucleon annihilated...); E* = " << (totalEnergy - initialInternalEnergy - separationEnergies - eSep) << '\n');
}
return totalEnergy - initialInternalEnergy - separationEnergies - eSep;
return totalEnergy - initialInternalEnergy - separationEnergies;
}
@@ -346,6 +331,17 @@ if (getAType() == AnnihilationType::Def) {
return ss.str();
}
void Nucleus::restoreSrcPartner(Particle *particle, ThreeVector m) {
std::cout << "restoreSrcPartner: " << particle->print() << std::endl;
std::cout << "restoreSrcPartner: " << m.print() << std::endl;
particle->setMomentum(m);
particle->adjustEnergyFromMomentum();
std::cout << "restoreSrcPartner bis: " << particle->print() << std::endl;
}
G4bool Nucleus::decayOutgoingDeltas() {
ParticleList const &out = theStore->getOutgoingParticles();
@@ -557,7 +553,7 @@ if (getAType() == AnnihilationType::Def) {
theCreatedParticle1->setTableMass();
theCreatedParticle1->setMomentum(newMomentum);
theCreatedParticle1->adjustEnergyFromMomentum();
//theCreatedParticle1->setEmissionTime(nucleon->getEmissionTime());
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
@@ -573,8 +569,10 @@ if (getAType() == AnnihilationType::Def) {
theCreatedParticle1->boost(beta);
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
theCreatedParticle2->boost(beta);
theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
theModifiedParticle->boost(beta);
theStore->addToOutgoing(theCreatedParticle1);
@@ -834,6 +832,49 @@ if (getAType() == AnnihilationType::Def) {
}
return (G4int)toEject.size();
}
G4int Nucleus::emitInsideAntilambda() {
/* Forcing emissions of all Antilambdas in the nucleus.
* This probably violates energy conservation
* (although the computation of the recoil kinematics
* might sweep this under the carpet).
*/
INCL_DEBUG("Forcing emissions of all antiLambda in the nucleus." << '\n');
// Emit the Lambda with this kinetic energy
const G4double tinyEnergy = 0.1; // MeV
// Push out the emitted Lambda
ParticleList const &inside = theStore->getParticles();
ParticleList toEject;
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
if((*i)->isAntiLambda()) {
Particle * const theAntiLambda = *i;
INCL_DEBUG("Forcing emission of the following particle: "
<< theAntiLambda->print() << '\n');
theAntiLambda->setEmissionTime(theStore->getBook().getCurrentTime());
// Correction for real masses
const G4double theQValueCorrection = theAntiLambda->getEmissionQValueCorrection(theA,theZ,theS); // Does it work for strange particles? Should be check
const G4double kineticEnergyOutside = theAntiLambda->getKineticEnergy() - theAntiLambda->getPotentialEnergy() + theQValueCorrection;
theAntiLambda->setTableMass();
if(kineticEnergyOutside > 0.0)
theAntiLambda->setEnergy(theAntiLambda->getMass()+kineticEnergyOutside);
else
theAntiLambda->setEnergy(theAntiLambda->getMass()+tinyEnergy);
theAntiLambda->adjustMomentumFromEnergy();
theAntiLambda->setPotentialEnergy(0.);
theA -= theAntiLambda->getA();
theS -= theAntiLambda->getS();
toEject.push_back(theAntiLambda);
}
}
for(ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
theStore->particleHasBeenEjected(*i);
theStore->addToOutgoing(*i);
(*i)->setParticleBias(Particle::getTotalBias());
}
return (G4int)toEject.size();
}
G4bool Nucleus::emitInsideKaon() {
/* Forcing emissions of all Kaon (not antiKaons) in the nucleus.
@@ -878,6 +919,77 @@ if (getAType() == AnnihilationType::Def) {
theNKaon -= 1;
return toEject.size() != 0;
}
G4bool Nucleus::emitInsideAnnihilationProducts(){
/* Forcing annihilation of all Antinucleons in the nucleus and emission of the resulting particles.
*/
INCL_DEBUG("Forcing annihilation of all Antinucleons and emission of all produced mesons in the nucleus." << '\n' );
const G4double tinyEnergy = 0.1; // MeV
ParticleList const &inside = theStore->getParticles();
ParticleList antinucleons;
ParticleList toEject; // mesons from antinucleon annihilations to be ejected
G4double theNewZ=theZ;
// Build a list of remaining antinucleons
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
if((*i)->isAntiNucleon()) antinucleons.push_back((*i));
// Loop over the antinucleons, build a list of mesons to be ejected
for(ParticleIter i=antinucleons.begin(), e=antinucleons.end(); i!=e; ++i) {
Particle * theAnnihilated = nullptr;
G4double dist_NbarNuc = 1000.; //just a high random beginning
G4double temp_dist = 0.;
// Nucleon annihilated
for (ParticleIter pnuc=inside.begin(), enuc=inside.end(); pnuc!=enuc;++pnuc){
if ((*pnuc)->isNucleon()){
temp_dist = ((*pnuc)->getPosition() - (*i)->getPosition()).mag(); // calculate distance between the antinucleon and nucleons in the nucleus
if(temp_dist < dist_NbarNuc){ //obtain information of the last nucleon that was close enough
dist_NbarNuc = temp_dist;
theAnnihilated = (*pnuc);
}
}
}
// Annihilation (meson production)
INCL_DEBUG("Forcing collision of the following particle :" <<'\n' << (*i)->print() << '\n' << theAnnihilated->print() << '\n' );
theNewZ = theNewZ - (theAnnihilated->getZ() + ((*i)->getZ()));
BinaryCollisionAvatar *collision = new BinaryCollisionAvatar(0.,9999.,this,theAnnihilated,(*i)); //Binary Collision Avatar to annihilate; XS=9999. means force annihilation
FinalState *fs = collision->getFinalState();
applyFinalState(fs);
INCL_DEBUG("Forcing Emission of the resulting particle of the forced annihilation" << '\n');
ParticleList modifiedparts = fs->getModifiedParticles();
for(ParticleIter outs=modifiedparts.begin(), eouts=modifiedparts.end();outs!=eouts;outs++){
toEject.push_back((*outs));
}
ParticleList const &created = fs->getCreatedParticles();
if(created.size() !=0){
for(ParticleIter out=created.begin(),eout=created.end();out!=eout;out++){
toEject.push_back((*out));
}
}
delete fs;
delete collision;
}
// Loop over the mesons to be ejected
for(ParticleIter iEject=toEject.begin(),eEject=toEject.end();iEject!=eEject;iEject++){ //Eject all produced mesons
(*iEject)->setEmissionTime(theStore->getBook().getCurrentTime());
G4double theQValueCorrection = (*iEject)->getEmissionQValueCorrection(theA,theZ,theS);
G4double kineticEnergyOutside = (*iEject)->getKineticEnergy() - (*iEject)->getPotentialEnergy() + theQValueCorrection;
(*iEject)->setTableMass();
if(kineticEnergyOutside > 0.0)
(*iEject)->setEnergy((*iEject)->getMass() + kineticEnergyOutside);
else
(*iEject)->setEnergy((*iEject)->getMass() + tinyEnergy);
(*iEject)->adjustMomentumFromEnergy();
(*iEject)->setPotentialEnergy(0.);
theStore->particleHasBeenEjected(*iEject);
theStore->addToOutgoing(*iEject);
}
theZ = theNewZ;
return true;
}
G4bool Nucleus::isEventTransparent() const {
@@ -1113,14 +1225,18 @@ if (getAType() == AnnihilationType::Def) {
eventInfo->parentResonanceID[eventInfo->nParticles] = (*i)->getParentResonanceID();
#endif
eventInfo->history.push_back("");
if ((*i)->getType() != Composite) {
if ((*i)->getType() != Composite && (*i)->getType() != antiComposite ) {
ParticleSpecies pt((*i)->getType());
eventInfo->PDGCode[eventInfo->nParticles] = pt.getPDGCode();
}
else {
else if((*i)->getType() == Composite) {
ParticleSpecies pt((*i)->getA(), (*i)->getZ(), (*i)->getS());
eventInfo->PDGCode[eventInfo->nParticles] = pt.getPDGCode();
}
else if((*i)->getType() == antiComposite) {
ParticleSpecies pt(-(*i)->getA(), -(*i)->getZ(), (*i)->getS());
eventInfo->PDGCode[eventInfo->nParticles] = pt.getPDGCode();
}
eventInfo->nParticles++;
}
eventInfo->nucleonAbsorption = isNucleonAbsorption;
@@ -1128,7 +1244,7 @@ if (getAType() == AnnihilationType::Def) {
eventInfo->nCascadeParticles = eventInfo->nParticles;
// Projectile-like remnant characteristics
if(theProjectileRemnant && theProjectileRemnant->getA()>0) {
if(theProjectileRemnant && (theProjectileRemnant->getA()>0 || theProjectileRemnant->getA()<0)) {
#ifdef INCLXX_IN_GEANT4_MODE
eventInfo->ARem[eventInfo->nRemnants] = (G4INCL::Short_t)theProjectileRemnant->getA();
eventInfo->ZRem[eventInfo->nRemnants] = (G4INCL::Short_t)theProjectileRemnant->getZ();
@@ -1213,6 +1329,8 @@ if (getAType() == AnnihilationType::Def) {
eventInfo->nCollisionAvatars = theBook.getAvatars(CollisionAvatarType);
eventInfo->nDecayAvatars = theBook.getAvatars(DecayAvatarType);
eventInfo->nEnergyViolationInteraction = theBook.getEnergyViolationInteraction();
eventInfo->nSrcPairs = theBook.getSrcPairs();
eventInfo->nSrcCollisions = theBook.getAcceptedSrcCollisions();
}
@@ -1225,7 +1343,7 @@ if (getAType() == AnnihilationType::Def) {
theBalance.A = theEventInfo.Ap + theEventInfo.At;
theBalance.S = theEventInfo.Sp + theEventInfo.St;
INCL_DEBUG("theBalance Z and A " << theBalance.Z << " " << theBalance.A << '\n');
theBalance.energy = getInitialEnergy();
theBalance.energy = getInitialEnergy() + getSrcInternalEnergy();
theBalance.momentum = getIncomingMomentum();
// Process outgoing particles
@@ -1241,15 +1359,27 @@ if (getAType() == AnnihilationType::Def) {
}
// Projectile-like remnant contribution, if present
if(theProjectileRemnant && theProjectileRemnant->getA()>0) {
if(theProjectileRemnant && (theProjectileRemnant->getA()>0 || theProjectileRemnant->getA()<0)) {
theBalance.Z -= theProjectileRemnant->getZ();
theBalance.A -= theProjectileRemnant->getA();
theBalance.S -= theProjectileRemnant->getS();
theBalance.energy -= ParticleTable::getTableMass(theProjectileRemnant->getA(),theProjectileRemnant->getZ(),theProjectileRemnant->getS()) +
theProjectileRemnant->getExcitationEnergy();
if(theProjectileRemnant->getA()>0)
theBalance.energy -= ParticleTable::getTableMass(theProjectileRemnant->getA(),theProjectileRemnant->getZ(),theProjectileRemnant->getS()) + theProjectileRemnant->getExcitationEnergy();
else if(theProjectileRemnant->getA()<0)
theBalance.energy -= ParticleTable::getTableMass(-(theProjectileRemnant->getA()),-(theProjectileRemnant->getZ()),theProjectileRemnant->getS()) + theProjectileRemnant->getExcitationEnergy();
theBalance.energy -= theProjectileRemnant->getKineticEnergy();
theBalance.momentum -= theProjectileRemnant->getMomentum();
}
//Missed particle contribution, for anticomposite model B
ParticleList const & missedParticles = theStore->getMissedParticles();
for(ParticleIter i=missedParticles.begin(), e=missedParticles.end(); i!=e;++i){
theBalance.Z -= (*i)->getZ();
theBalance.A -= (*i)->getA();
theBalance.S -= (*i)->getS();
theBalance.energy -= (*i)->getEnergy();
//theBalance.momentum -= (*i)->getMomentum();
}
// Target-like remnant contribution, if present
if(hasRemnant()) {
@@ -1261,6 +1391,25 @@ if (getAType() == AnnihilationType::Def) {
if(afterRecoil)
theBalance.energy -= getKineticEnergy();
theBalance.momentum -= getMomentum();
Book const &theBook = theStore->getBook();
if (getExcitationEnergy() < 0. && theBook.getAcceptedSrcCollisions()) {
INCL_DEBUG("excitation energy negative and afterrecoil "
<< afterRecoil << " " << getExcitationEnergy()
<< " eventNumber=" << theEventInfo.eventNumber << " "
<< getInitialInternalEnergy() << '\n');
INCL_DEBUG("excitation energy negative and afterrecoil "
<< getInitialInternalEnergy() << " " << getSrcInternalEnergy()
<< " " << initialEnergy << '\n');
}
if (theBook.getAcceptedSrcCollisions() && !afterRecoil) {
INCL_DEBUG("excitation energy " << getExcitationEnergy()
<< " and afterrecoil 1 , kinetic energy ="
<< getKineticEnergy() << ", eventNumber="
<< theEventInfo.eventNumber << '\n');
}
}
return theBalance;
@@ -1277,14 +1426,17 @@ if (getAType() == AnnihilationType::Def) {
void Nucleus::finalizeProjectileRemnant(const G4double anEmissionTime) {
// Deal with the projectile remnant
const G4int prA = theProjectileRemnant->getA();
if(prA>=1) {
if(prA>=1 || prA<=-1) {
// Set the mass
const G4double aMass = theProjectileRemnant->getInvariantMass();
theProjectileRemnant->setMass(aMass);
// Compute the excitation energy from the invariant mass
const G4double anExcitationEnergy = aMass
- ParticleTable::getTableMass(prA, theProjectileRemnant->getZ(), theProjectileRemnant->getS());
// Compute the excitation energy from the invariant
G4double anExcitationEnergy;
if(prA>=1)
anExcitationEnergy = aMass - ParticleTable::getTableMass(prA, theProjectileRemnant->getZ(), theProjectileRemnant->getS());
else
anExcitationEnergy = aMass - ParticleTable::getTableMass(-prA, -(theProjectileRemnant->getZ()), theProjectileRemnant->getS());
// Set the excitation energy
theProjectileRemnant->setExcitationEnergy(anExcitationEnergy);
@@ -39,6 +39,8 @@
#include "G4INCLIChannel.hh"
#include "G4INCLParticleEntryChannel.hh"
#include "G4INCLPbarAtrestEntryChannel.hh"
#include "G4INCLNbarAtrestEntryChannel.hh"
#include "G4INCLAntinucleiAtrestEntryChannel.hh"
namespace G4INCL {
@@ -77,6 +79,15 @@ namespace G4INCL {
return new PbarAtrestEntryChannel(theNucleus, theParticle);
INCL_DEBUG("Particle " << theParticle->getID() << " is trying to enter at rest" << '\n');
}
else if(theEType == ANAR){
return new NbarAtrestEntryChannel(theNucleus, theParticle);
INCL_DEBUG("Particle " << theParticle->getID() << "is trying to enter at rest " << '\n');
}
else if(theEType == ADAR){
return new AntinucleiAtrestEntryChannel(theNucleus, theParticle);
INCL_DEBUG("Particle " << theParticle->getID() << "is trying to enter at rest " << '\n');
}
else {
return new ParticleEntryChannel(theNucleus, theParticle);
}
@@ -39,6 +39,9 @@
#include "G4INCLRootFinder.hh"
#include "G4INCLIntersection.hh"
#include <algorithm>
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLPbarAtrestEntryChannel.hh"
#include "G4INCLNbarAtrestEntryChannel.hh"
namespace G4INCL {
@@ -82,7 +85,7 @@ namespace G4INCL {
*/
G4double theCorrection;
if(isNN) {
// assert(theParticle->isNucleonorLambda()); // Possible hypernucleus projectile of inverse kinematic
// assert(theParticle->isNucleonorLambda() || theParticle->isAntiNucleon()); // Possible hypernucleus projectile of inverse kinematic
ProjectileRemnant * const projectileRemnant = theNucleus->getProjectileRemnant();
// assert(projectileRemnant);
@@ -116,20 +119,49 @@ namespace G4INCL {
// Fix the correction in such a way that the quasi-projectile excitation
// energy is given by A. Boudard's INCL4.2-HI model (model 3. above).
const G4double theProjectileExcitationEnergy =
(projectileRemnant->getA()-theParticle->getA()>1) ?
(projectileRemnant->computeExcitationEnergyExcept(theParticle->getID())) :
0.;
G4double theProjectileExcitationEnergy = 0;
G4double theProjectileEffectiveMass =0;
if (theParticle->isNucleonorLambda()){
theProjectileExcitationEnergy = (projectileRemnant->getA()-theParticle->getA()>1) ? (projectileRemnant->computeExcitationEnergyExcept(theParticle->getID())) : 0.;
theProjectileEffectiveMass =
ParticleTable::getTableMass(projectileRemnant->getA() - theParticle->getA(), projectileRemnant->getZ() - theParticle->getZ(), projectileRemnant->getS() - theParticle->getS())
+ theProjectileExcitationEnergy;
}
else if (theParticle->isAntiNucleon()){
theProjectileExcitationEnergy = (projectileRemnant->getA() -theParticle->getA()<-1) ? (projectileRemnant->computeExcitationEnergyExcept(theParticle->getID())) : 0;
theProjectileEffectiveMass =
ParticleTable::getTableMass(-(projectileRemnant->getA() - theParticle->getA()), -(projectileRemnant->getZ() - theParticle->getZ()), projectileRemnant->getS() - theParticle->getS())
+ theProjectileExcitationEnergy;
}
// Set the projectile excitation energy to zero (cold quasi-projectile,
// model 4. above).
// const G4double theProjectileExcitationEnergy = 0.;
// The part that follows is common to model 3. and 4.
const G4double theProjectileEffectiveMass =
ParticleTable::getTableMass(projectileRemnant->getA() - theParticle->getA(), projectileRemnant->getZ() - theParticle->getZ(), projectileRemnant->getS() - theParticle->getS())
+ theProjectileExcitationEnergy;
const ThreeVector &theProjectileMomentum = projectileRemnant->getMomentum() - theParticle->getMomentum();
const G4double theProjectileEnergy = std::sqrt(theProjectileMomentum.mag2() + theProjectileEffectiveMass*theProjectileEffectiveMass);
const G4double theProjectileCorrection = theProjectileEnergy - (projectileRemnant->getEnergy() - theParticle->getEnergy());
/*if(theParticle->isAntiNucleon()){
bool Pvictim=0; //Proton or Neutron is the Victim ?
if(((theNucleus->getZ() - theParticle->getZ())- theNucleus->getZ()) == 1)
Pvictim = 1;
else
Pvictim = 0;
double theCorrection1 = theParticle->getEmissionPbarQvalueCorrection(theNucleus->getA(), theNucleus->getZ(), Pvictim);
double theCorrection2 = theParticle->getEmissionPbarQvalueCorrection(theNucleus->getA(), theNucleus->getZ(), !Pvictim);
theCorrection = theParticle->getEmissionPbarQvalueCorrection(theNucleus->getA() - theParticle->getA(), theNucleus->getZ() - theParticle->getZ(),Pvictim)
+ theParticle->getTableMass() - theParticle->getINCLMass() + theProjectileCorrection;
if(Pvictim == 1 && theParticle->getType() == antiNeutron)
theCorrection += theCorrection2 - theCorrection1;
else if(Pvictim == 0 && theParticle->getType()==antiProton)
theCorrection += theCorrection2 - theCorrection1;
theCorrection = theParticle->getEmissionQValueCorrection(
theNucleus->getA() + theParticle->getA(),
theNucleus->getZ() + theParticle->getZ(),
theNucleus->getS() + theParticle->getS())
+ theParticle->getTableMass() - theParticle->getINCLMass()
+ theProjectileCorrection << std::endl;
}*/
//else
theCorrection = theParticle->getEmissionQValueCorrection(
theNucleus->getA() + theParticle->getA(),
theNucleus->getZ() + theParticle->getZ(),
@@ -145,14 +177,24 @@ namespace G4INCL {
const G4int ZCN = theNucleus->getZ() + theParticle->getZ();
const G4int SCN = theNucleus->getS() + theParticle->getS();
// Correction to the Q-value of the entering particle
if(theParticle->isKaon()) theCorrection = theParticle->getEmissionQValueCorrection(ACN,ZCN,theNucleus->getS());
else theCorrection = theParticle->getEmissionQValueCorrection(ACN,ZCN,SCN);
theCorrection = theParticle->getEmissionQValueCorrection(ACN,ZCN,SCN);
INCL_DEBUG("The following Particle enters with correction " << theCorrection << '\n'
<< theParticle->print() << '\n');
}
const G4double energyBefore = theParticle->getEnergy() - theCorrection;
G4bool success = particleEnters(theCorrection);
G4bool success;
if(isNN && theParticle->isAntiNucleon() && (theParticle->getEnergy() - theCorrection <=theParticle->getINCLMass()) ){
success =true;
G4double energyInside = theParticle->getEnergy() + theNucleus->getPotential()->computePotentialEnergy(theParticle) - theCorrection;
theParticle->setEnergy(energyInside);
theParticle->setPotentialEnergy(theNucleus->getPotential()->computePotentialEnergy(theParticle));
theParticle->setMomentum(theParticle->getMomentum());
theParticle->adjustMomentumFromEnergy();
}
else{
success = particleEnters(theCorrection);
}
fs->addEnteringParticle(theParticle);
if(!success) {
@@ -112,10 +112,14 @@ namespace G4INCL {
thePCDFTable[Neutron] = NuclearDensityFactory::createPCDFTable(Neutron, theA, theZ);
theRCDFTable[Lambda] = NuclearDensityFactory::createRCDFTable(Lambda, theA, theZ);
thePCDFTable[Lambda] = NuclearDensityFactory::createPCDFTable(Lambda, theA, theZ);
theRCDFTable[antiProton] = NuclearDensityFactory::createRCDFTable(antiProton, theA, theZ);
thePCDFTable[antiProton] = NuclearDensityFactory::createPCDFTable(antiProton, theA, theZ);
theRCDFTable[antiNeutron] = NuclearDensityFactory::createRCDFTable(antiNeutron, theA, theZ);
thePCDFTable[antiNeutron] = NuclearDensityFactory::createPCDFTable(antiNeutron, theA, theZ);
}
theList.resize(theA);
if(theA > 2) {
theList.resize(theA);
ParticleType type = Proton;
ParticleSamplerMethod sampleOneParticle = sampleOneProton;
for(G4int i = 0; i < theA; ++i) {
@@ -128,7 +132,15 @@ namespace G4INCL {
p->setPosition(position + p->getPosition());
theList[i] = p;
}
} else {
}else if(theA == -2) {//antideuteron
theList.resize(-theA);
Particle *anantiProton = (this->*(this->sampleOneProton))(antiProton);
Particle *anantiNeutron = new Particle(antiNeutron, -anantiProton->getMomentum(), position - anantiProton->getPosition());
anantiProton->setPosition(position + anantiProton->getPosition());
theList[0] = anantiProton;
theList[1] = anantiNeutron;
}else { //deuteron
theList.resize(theA);
// For deuterons, only sample the proton position and momentum. The
// neutron position and momenta are determined by the conditions of
// vanishing CM position and total momentum.
@@ -161,6 +161,9 @@ namespace G4INCL {
G4int A = theNucleus->getA(); //was modified in Cascade.cc
A++; //restoration of original A value before annihilation
if(isProton == true){Z++;} //restoration of original Z value before annihilation
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){A++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarPPbarNType){Z++;}
if(A > 19) {
G4double radius = ParticleTable::getRadiusParameter(Proton, A, Z);
@@ -202,6 +205,9 @@ namespace G4INCL {
G4int A = theNucleus->getA(); //was modified in Cascade.cc
A++; //restoration of original A value before annihilation
if(isProton == true){Z++;} //restoration of original Z value before annihilation
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){A++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarPPbarNType){Z++;}
if(A > 19) {
G4double radius = ParticleTable::getRadiusParameter(Neutron, A, Z);
@@ -522,16 +528,19 @@ namespace G4INCL {
}
// Correction to the Q-value of the entering particle
G4double theCorrection1 = theParticle->getEmissionPbarQvalueCorrection(a, z, isProton);
G4double theCorrection2 = theParticle->getEmissionPbarQvalueCorrection(a, z, !isProton);
G4int stra = theNucleus->getS();
G4double energyOfMesonStar;
if(theNucleus->isNucleusNucleusCollision()==false){//antiProton
if(isProton == true){
energyOfMesonStar = theParticle->getTableMass() + ParticleTable::getTableMass(a,z,0)
-ParticleTable::getTableMass(a-1,z-1,0);
energyOfMesonStar = theParticle->getEnergy() + ParticleTable::getTableMass(a,z,stra)
-ParticleTable::getTableMass(a-1,z-1,stra);
}
else{
energyOfMesonStar = theParticle->getTableMass() + ParticleTable::getTableMass(a,z,0)
-ParticleTable::getTableMass(a-1,z,0) + theCorrection2 - theCorrection1;
energyOfMesonStar = theParticle->getEnergy() + ParticleTable::getTableMass(a,z,stra)
-ParticleTable::getTableMass(a-1,z-1,stra);
}
} else if(theNucleus->isNucleusNucleusCollision()==true){//antiComposite : job is done in the Antinuclei file
return starlist;
}
//compute energies of mesons with a phase-space model
@@ -564,12 +573,10 @@ namespace G4INCL {
}
G4bool PbarAtrestEntryChannel::ProtonIsTheVictim(){
if(theNucleus->getAnnihilationType() == PType){
INCL_DEBUG("isProton" << '\n');
if(theNucleus->getAnnihilationType() == PType || theNucleus->getAnnihilationType() == DNbarNPbarPType || theNucleus->getAnnihilationType() == DNbarPPbarPType){
return true; //proton is annihilated
}
else if(theNucleus->getAnnihilationType() == NType){
INCL_DEBUG("isNeutron" << '\n');
else if(theNucleus->getAnnihilationType() == NType || theNucleus->getAnnihilationType() == DNbarNPbarNType || theNucleus->getAnnihilationType() == DNbarPPbarNType){
return false; //neutron is annihilated
}
else{
@@ -604,6 +611,9 @@ namespace G4INCL {
a++; //not before the n_ann!
if(isProton == true){z++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){a++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarPPbarNType){z++;}
G4double Rpmax = ParticleTable::getMaximumNuclearRadius(Proton, a, z);
G4double Rnmax = ParticleTable::getMaximumNuclearRadius(Neutron, a, z);
G4double probabilitymax = 0.; //the max value of the probability distribution
@@ -655,7 +665,11 @@ namespace G4INCL {
}
//FINAL POSITION VECTOR
ThreeVector annihilationPosition(0., 0., -distance); //3D sphere of distance radius
//ThreeVector annihilationPosition(0., 0., -distance); //3D sphere of distance radius
G4double ctheta = (1.-2.*Random::shoot());
G4double stheta = std::sqrt(1.-ctheta*ctheta);
G4double phi = Math::twoPi*Random::shoot();
ThreeVector annihilationPosition(distance*stheta * std::cos(phi), distance*stheta * std::sin(phi), distance*ctheta); //3D sphere of distance radius
return annihilationPosition;
@@ -670,6 +684,9 @@ namespace G4INCL {
if(isProton == true){
z++;
}
if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType ||
theNucleus->getAnnihilationType()==DNbarNPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){a++;}
if(theNucleus->getAnnihilationType()==DNbarPPbarPType || theNucleus->getAnnihilationType()==DNbarPPbarNType){z++;}
INCL_DEBUG("the original Z value is " << z << '\n');
INCL_DEBUG("the original A value is " << a << '\n');
G4double n_ann; //annihilation principal quantum number(interpolation from data H.Poth)
@@ -69,12 +69,14 @@ namespace G4INCL {
}
if(theA>0)
thePosition /= theA;
else if(theA<0)
thePosition/= -theA;
setTableMass();
INCL_DEBUG("ProjectileRemnant object was reset:" << '\n' << print());
}
void ProjectileRemnant::removeParticle(Particle * const p, const G4double theProjectileCorrection) {
// assert(p->isNucleon() || p->isLambda());
// assert(p->isNucleon() || p->isLambda() || p->isAntiNucleon());
INCL_DEBUG("The following Particle is about to be removed from the ProjectileRemnant:"
<< '\n' << p->print()
@@ -94,8 +96,8 @@ namespace G4INCL {
const G4double theThreshold = 0.1;
#endif
if(getA()>0) { // if there are any particles left
// assert((unsigned int)getA()==particles.size());
if(getA()>0 || getA()<0) { // if there are any particles left
// assert((unsigned int)getA()==particles.size() || -getA()==(particles.size()));
const G4double theProjectileCorrectionPerNucleon = theProjectileCorrection / particles.size();
@@ -150,7 +152,7 @@ namespace G4INCL {
G4int theNewZ = theZ;
G4int theNewS = theS;
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
// assert((*p)->isNucleonorLambda());
// assert((*p)->isNucleonorLambda() || (*p)->isAntiNucleon());
// Add the initial (off-shell) momentum and energy to the projectile remnant
theNewMomentum += getStoredMomentum(*p);
theNewEnergy += (*p)->getEnergy();
@@ -160,7 +162,11 @@ namespace G4INCL {
}
// Check that the excitation energy of the new projectile remnant is non-negative
const G4double theNewMass = ParticleTable::getTableMass(theNewA,theNewZ,theNewS);
G4double theNewMass;
if(theA < 0)
theNewMass = ParticleTable::getTableMass(-theNewA,-theNewZ,theNewS);
else
theNewMass = ParticleTable::getTableMass(theNewA,theNewZ,theNewS);
const G4double theNewExcitationEnergy = computeExcitationEnergyWith(pL);
const G4double theNewEffectiveMass = theNewMass + theNewExcitationEnergy;
@@ -205,7 +211,7 @@ namespace G4INCL {
G4int theNewZ = theZ;
G4int theNewS = theS;
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
// assert((*p)->isNucleonorLambda());
// assert((*p)->isNucleonorLambda()|| (*p)->isAntiNucleon());
// Add the initial (off-shell) momentum and energy to the projectile remnant
theNewMomentum += getStoredMomentum(*p);
theNewEnergy += (*p)->getEnergy();
@@ -215,7 +221,11 @@ namespace G4INCL {
}
// Check that the excitation energy of the new projectile remnant is non-negative
const G4double theNewMass = ParticleTable::getTableMass(theNewA,theNewZ,theNewS);
G4double theNewMass;
if(theA < 0)
theNewMass = ParticleTable::getTableMass(-theNewA,-theNewZ,theNewS);
else
theNewMass = ParticleTable::getTableMass(theNewA,theNewZ,theNewS);
const G4double theNewInvariantMassSquared = theNewEnergy*theNewEnergy-theNewMomentum.mag2();
G4bool positiveExcitationEnergy = false;
@@ -241,8 +251,12 @@ namespace G4INCL {
const G4int theNewerA = theNewA - (*p)->getA();
const G4int theNewerZ = theNewZ - (*p)->getZ();
const G4int theNewerS = theNewS - (*p)->getS();
const G4double theNewerMass = ParticleTable::getTableMass(theNewerA,theNewerZ,theNewerS);
G4double theNewerMass;
if(theA < 0)
theNewerMass = ParticleTable::getTableMass(-theNewerA,-theNewerZ,theNewerS);
else
theNewerMass = ParticleTable::getTableMass(theNewerA,theNewerZ,theNewerS);
const G4double theNewerInvariantMassSquared = theNewerEnergy*theNewerEnergy-theNewerMomentum.mag2();
if(theNewerInvariantMassSquared>=-1.e-5) {
@@ -294,7 +308,7 @@ namespace G4INCL {
}
G4bool ProjectileRemnant::addDynamicalSpectator(Particle * const p) {
// assert(p->isNucleon());
// assert(p->isNucleon() || p->isAntiNucleon());
// Add the initial (off-shell) momentum and energy to the projectile remnant
ThreeVector const &oldMomentum = getStoredMomentum(p);
@@ -303,7 +317,11 @@ namespace G4INCL {
const G4double theNewEnergy = theEnergy + oldEnergy;
// Check that the excitation energy of the new projectile remnant is non-negative
const G4double theNewMass = ParticleTable::getTableMass(theA+p->getA(),theZ+p->getZ(),theS+p->getS());
G4double theNewMass;
if(theA < 0)
theNewMass = ParticleTable::getTableMass(-(theA)+ (-(p->getA())),-(theZ)+(-(p->getZ())),theS+p->getS());
else
theNewMass = ParticleTable::getTableMass(theA+p->getA(),theZ+p->getZ(),theS+p->getS());
const G4double theNewInvariantMassSquared = theNewEnergy*theNewEnergy-theNewMomentum.mag2();
if(theNewInvariantMassSquared<0.)
@@ -0,0 +1,178 @@
// ********************************************************************
// * 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. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Alain Boudard, CEA-Saclay, France
// Joseph Cugnon, University of Liege, Belgium
// Jean-Christophe David, CEA-Saclay, France
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
// Sylvie Leray, CEA-Saclay, France
// Davide Mancusi, CEA-Saclay, France
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* \file G4INCLSrcChannel.cc
*
* \date Feb 24, 2022
* \author Jose Luis Rodriguez-Sanchez
*/
#include "G4INCLSrcChannel.hh"
#include "G4INCLCrossSections.hh"
#include "G4INCLGlobals.hh"
#include "G4INCLInteractionAvatar.hh"
#include "G4INCLKinematicsUtils.hh"
#include "G4INCLParticleTable.hh"
#include "G4INCLRandom.hh"
namespace G4INCL {
SrcChannel::SrcChannel(Particle *p1, Particle *p2, Nucleus *n)
: particle1(p1), particle2(p2), thenucleus(n) {
fDistSrc = ParticleTable::getsrcPairDistance();
srcpartner = nullptr;
ftype1 = UnknownParticle;
ftype2 = UnknownParticle;
}
SrcChannel::~SrcChannel() {}
Particle *SrcChannel::findpairpartner(Particle *pt) {
const auto pair = pt->getSrcPair();
const ParticleType t = pt->getType();
ParticleList const &inside = thenucleus->getStore()->getParticles();
for (ParticleIter p = inside.begin(), e = inside.end(); p != e; ++p) {
if ((*p)->getSrcPair() == pair &&
(t != (*p)->getType() ||
(t == (*p)->getType() && pt->getID() != (*p)->getID())))
{
return (*p);
}
}
INCL_ERROR("SrcChannel: pair not found" << '\n');
return NULL;
}
void SrcChannel::fillFinalState(FinalState *fs, ParticleType type1,
ParticleType type2) {
ftype1 = type1;
ftype2 = type2;
fillFinalState(fs);
}
void SrcChannel::fillFinalState(FinalState *fs) {
auto fSource = InteractionAvatar::Instance();
G4double psrcmax = 2.0 * PhysicalConstants::Pf; // Fermi momentum in MeV/c
if (particle1->getSrcPair() > 0) {
if (particle2->getSrcPair() > 0)
{
INCL_ERROR(particle2->print() << " \n");
}
srcpartner = findpairpartner(particle1);
if (srcpartner)
{
srcpartner->setSrcPartner();
fSource->setSrcPartner(srcpartner);
ThreeVector d1 = particle1->getPosition();
ThreeVector d2 = srcpartner->getPosition();
auto d = d1 - d2;
if (d.mag() > fDistSrc) {
INCL_DEBUG("Distance src > " << fDistSrc << " fm : " << d.mag()
<< " \n");
}
auto x = (fDistSrc - d.mag()) / fDistSrc;
auto srcp = x * x * psrcmax;
INCL_DEBUG("Src momentum = " << srcp << " , eventnb: "
<< theEventInfo.eventNumber << " \n");
auto pmomentum =
particle1->getMomentum() / particle1->getMomentum().mag() * srcp;
particle1->setMomentum(particle1->getMomentum() + pmomentum);
srcpartner->setMomentum(srcpartner->getMomentum() - pmomentum);
particle1->adjustEnergyFromMomentum();
srcpartner->adjustEnergyFromMomentum();
thenucleus->updatePotentialEnergy(srcpartner);
fs->addModifiedParticle(particle1);
fs->addModifiedParticle(particle2);
fs->addModifiedParticle(srcpartner);
}
} else {
if (particle1->getSrcPair() > 0)
{
INCL_ERROR(particle1->print() << " \n");
}
srcpartner = findpairpartner(particle2);
if (srcpartner)
{
srcpartner->setSrcPartner();
fSource->setSrcPartner(srcpartner);
ThreeVector d1 = particle2->getPosition();
ThreeVector d2 = srcpartner->getPosition();
auto d = d1 - d2;
if (d.mag() > fDistSrc) {
INCL_DEBUG("Distance src > " << fDistSrc << " fm : " << d.mag()
<< " \n");
}
auto x = (fDistSrc - d.mag()) / fDistSrc;
auto srcp = x * x * psrcmax;
INCL_DEBUG("Src momentum = " << srcp << " , eventnb: "
<< theEventInfo.eventNumber << " \n");
auto pmomentum =
particle2->getMomentum() / particle2->getMomentum().mag() * srcp;
particle2->setMomentum(particle2->getMomentum() + pmomentum);
srcpartner->setMomentum(srcpartner->getMomentum() - pmomentum);
particle2->adjustEnergyFromMomentum();
srcpartner->adjustEnergyFromMomentum();
thenucleus->updatePotentialEnergy(srcpartner);
fs->addModifiedParticle(particle1);
fs->addModifiedParticle(particle2);
fs->addModifiedParticle(srcpartner);
}
}
thenucleus->getStore()->getBook().incrementAcceptedSrcCollisions();
}
} // namespace G4INCL
@@ -44,6 +44,8 @@
#include "G4INCLStandardPropagationModel.hh"
#include "G4INCLPbarAtrestEntryChannel.hh"
#include "G4INCLNbarAtrestEntryChannel.hh"
#include "G4INCLAntinucleiAtrestEntryChannel.hh"
#include "G4INCLSurfaceAvatar.hh"
#include "G4INCLBinaryCollisionAvatar.hh"
#include "G4INCLDecayAvatar.hh"
@@ -86,10 +88,13 @@ namespace G4INCL {
//D
G4double StandardPropagationModel::shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) {
if(projectileSpecies.theType==Composite){
return shootComposite(projectileSpecies, kineticEnergy, impactParameter, phi);
if(projectileSpecies.theType==Composite || projectileSpecies.theType==antiComposite){
if(theNucleus->getAnnihilationType()!=Def)
return shootCompositeAtrest(projectileSpecies,kineticEnergy);
else
return shootComposite(projectileSpecies, kineticEnergy, impactParameter, phi);
}
else if(projectileSpecies.theType==antiProton && theNucleus->getAnnihilationType()!=Def){
else if((projectileSpecies.theType==antiProton || projectileSpecies.theType==antiNeutron) && theNucleus->getAnnihilationType()!=Def){
return shootAtrest(projectileSpecies.theType, kineticEnergy);
}
else{
@@ -109,6 +114,7 @@ namespace G4INCL {
G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
ThreeVector momentum(0.0, 0.0, momentumZ);
Particle *pb = new G4INCL::Particle(t, energy, momentum, ThreeVector());
if (t == antiProton){
PbarAtrestEntryChannel *obj = new PbarAtrestEntryChannel(theNucleus, pb);
ParticleList fslist = obj->makeMesonStar();
const G4bool isProton = obj->ProtonIsTheVictim();
@@ -151,11 +157,11 @@ namespace G4INCL {
theNucleus->setIncomingAngularMomentum(G4INCL::ThreeVector(0., 0., 0.));
theNucleus->setIncomingMomentum(G4INCL::ThreeVector(0., 0., 0.));
if(isProton){
theNucleus->setInitialEnergy(pb->getMass()
theNucleus->setInitialEnergy(pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ() + 1,theNucleus->getS()));
}
else{
theNucleus->setInitialEnergy(pb->getMass()
theNucleus->setInitialEnergy(pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ(),theNucleus->getS()));
}
//kinetic energy excluded from the balance
@@ -172,6 +178,73 @@ namespace G4INCL {
delete obj;
theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
INCL_DEBUG("Avatars added" << '\n');
} //end (t == antiProton)
else if (t == antiNeutron){
NbarAtrestEntryChannel *obj = new NbarAtrestEntryChannel(theNucleus, pb);
ParticleList fslist = obj->makeMesonStar();
const bool isProton = obj->ProtonIsTheVictim();
delete pb;
//set Stopping time according to highest meson energy of the star
G4double temfin;
G4double TLab;
std::vector<double> energies;
std::vector<double> projections;
ThreeVector ab, cd;
for(ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
energies.push_back((*pit)->getKineticEnergy());
ab = (*pit)->boostVector();
cd = (*pit)->getPosition();
projections.push_back(ab.dot(cd)); //projection length
}// make vector of energies
temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
TLab = *max_element(energies.begin(), energies.end()); //choose max energy
// energy-dependent stopping time above 2 AGeV
if(TLab>2000.)
temfin *= (5.8E4-TLab)/5.6E4;
maximumTime = temfin;
// If the incoming particle is slow, use a larger stopping time
const G4double rMax = theNucleus->getUniverseRadius();
const G4double distance = 2.*rMax;
const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
const G4double traversalTime = distance / maxMesonVelocityProjection;
if(maximumTime < traversalTime)
maximumTime = traversalTime;
INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
// Fill in the relevant kinematic variables
theNucleus->setIncomingAngularMomentum(G4INCL::ThreeVector(0., 0., 0.));
theNucleus->setIncomingMomentum(G4INCL::ThreeVector(0., 0., 0.));
if(isProton){
theNucleus->setInitialEnergy(pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ() + 1,theNucleus->getS()));
}
else{
theNucleus->setInitialEnergy(pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ(),theNucleus->getS()));
}
//kinetic energy excluded from the balance
for(ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
(*p)->makeProjectileSpectator();
}
generateAllAvatars();
firstAvatar = false;
// Get the entry avatars for mesons
IAvatarList theAvatarList = obj->bringMesonStar(fslist, theNucleus);
delete obj;
theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
INCL_DEBUG("Avatars added" << '\n');
}
return 99.;
}
@@ -213,6 +286,9 @@ namespace G4INCL {
if(maximumTime < traversalTime)
maximumTime = traversalTime;
INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
// If the incoming particle is an antinucleon use a larger stopping time
if( p->isAntiNucleon()) maximumTime *= 2.;
// If Coulomb is activated, do not process events with impact
// parameter larger than the maximum impact parameter, taking into
@@ -265,8 +341,17 @@ namespace G4INCL {
// Same stopping time as for nucleon-nucleus
maximumTime = 29.8 * std::pow(theNucleus->getA(), 0.16);
// If the incoming cluster is slow, use a larger stopping time
const G4double rms = ParticleTable::getLargestNuclearRadius(pr->getA(), pr->getZ());
// If the incoming cluster is slow, use a larger stopping
G4double rms=0.;
if(species.theType == Composite){
rms = ParticleTable::getLargestNuclearRadius(pr->getA(), pr->getZ());
}
else if(species.theType == antiComposite){
rms = ParticleTable::getLargestNuclearRadius(-(pr->getA()), -(pr->getZ()));
}
else {
INCL_ERROR("a non-composite try to go through shootComposite : " << species.theType << '\n');
}
const G4double rMax = theNucleus->getUniverseRadius();
const G4double distance = 2.*rMax + 2.725*rms;
const G4double projectileVelocity = pr->boostVector().mag();
@@ -328,6 +413,254 @@ namespace G4INCL {
return pr->getTransversePosition().mag();
}
G4double StandardPropagationModel::shootCompositeAtrest(ParticleSpecies const &species, const G4double kineticEnergy){
if(theNucleus->getAnnihilationType()==PType || theNucleus->getAnnihilationType()==NType){
INCL_DEBUG("Antideuteron annihilation Model B chosen, Annihilation of one antinucleon " << '\n');
theNucleus->setParticleNucleusCollision();
currentTime = 0.0;
//Dummy Cluster to intialise the anticomposite and distribute the energy and positio
Cluster *DummyC = new Cluster(-1,-2,0);
DummyC->setTableMass();
DummyC->initializeParticles();
DummyC->internalBoostToCM();
const G4double projectileMass = DummyC->getMass();
const G4double energy = kineticEnergy + projectileMass;
const G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
const ThreeVector aBoostVector = ThreeVector(0.0, 0.0, momentumZ / energy);
DummyC->boost(-aBoostVector);
DummyC->makeProjectileSpectator();
Particle *pb = new Particle(antiProton, 1, ThreeVector(), ThreeVector());
Particle *nb= new Particle(antiNeutron, 1, ThreeVector(), ThreeVector());
ParticleList Antis = DummyC->getParticles();
for(ParticleIter i = Antis.begin(), e=Antis.end();i!=e;++i){
if((*i)->getType()==antiProton){
pb = (*i);
DummyC->removeParticle((*i));
}
else if((*i)->getType()==antiNeutron){
nb = (*i);
DummyC->removeParticle((*i));
}
}
delete DummyC;
Config const *theConfig=theNucleus->getStore()->getConfig();
if(nb->getKineticEnergy() <= theConfig->getnbAtrestThreshold() && (pb->getEnergy() >= pb->getMass())){
INCL_DEBUG("Annihilation of the Antineutron " << '\n');
NbarAtrestEntryChannel *obj = new NbarAtrestEntryChannel(theNucleus, nb);
ParticleList fslist = obj->makeMesonStar();
const G4bool isProton = obj->ProtonIsTheVictim();
//delete nb;
//set Stopping time according to highest meson energy of the star
G4double temfin;
G4double TLab;
std::vector<G4double> energies;
std::vector<G4double> projections;
ThreeVector ab, cd;
for(ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
energies.push_back((*pit)->getKineticEnergy());
ab = (*pit)->boostVector();
cd = (*pit)->getPosition();
projections.push_back(ab.dot(cd)); //projection length
}// make vector of energies
temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
TLab = *max_element(energies.begin(), energies.end()); //choose max energy
if(TLab>2000.)
temfin *= (5.8E4-TLab)/5.6E4;
maximumTime = temfin;
// If the incoming particle is slow, use a larger stopping time
const G4double rMax = theNucleus->getUniverseRadius();
const G4double distance = 2.*rMax;
const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
const G4double traversalTime = distance / maxMesonVelocityProjection;
if(maximumTime < traversalTime)
maximumTime = traversalTime;
INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
// Fill in the relevant kinematic variables
theNucleus->setIncomingAngularMomentum(pb->getAngularMomentum());
theNucleus->setIncomingMomentum(pb->getMomentum());
if(isProton){
theNucleus->setInitialEnergy(nb->getMass() + pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ() + 1,theNucleus->getS()));
}
else{
theNucleus->setInitialEnergy(nb->getMass() + pb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ(),theNucleus->getS()));
}
// Reset the particle kinematics to the INCL values
for(ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
(*p)->makeProjectileSpectator();
}
pb->makeProjectileSpectator();
generateAllAvatars();
firstAvatar = false;
// Get the entry avatars for mesons
IAvatarList theAvatarList = obj->bringMesonStar(fslist, theNucleus);
delete obj;
theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
// Get the entry avatars from Coulomb and put them in the Store
ParticleEntryAvatar *theEntryAvatar = CoulombDistortion::bringToSurfaceAbar(pb, theNucleus);
if(theEntryAvatar) {
theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
INCL_DEBUG("Avatars added" << '\n');
return pb->getTransversePosition().mag();
} else {
INCL_DEBUG("Antiproton is transparent, not entering the nucleus " << '\n');
//Transparent event
theNucleus->getStore()->addToMissed(pb);
delete nb;
return 99.;
}
}
else{
INCL_DEBUG("Annihilation of the Antiproton " << '\n');
PbarAtrestEntryChannel *obj = new PbarAtrestEntryChannel(theNucleus, pb);
ParticleList fslist = obj->makeMesonStar();
const G4bool isProton = obj->ProtonIsTheVictim();
//delete pb;
//set Stopping time according to highest meson energy of the star
G4double temfin;
G4double TLab;
std::vector<G4double> energies;
std::vector<G4double> projections;
ThreeVector ab, cd;
for(ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
energies.push_back((*pit)->getKineticEnergy());
ab = (*pit)->boostVector();
cd = (*pit)->getPosition();
projections.push_back(ab.dot(cd)); //projection length
}// make vector of energies
temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
TLab = *max_element(energies.begin(), energies.end()); //choose max energy
if(TLab>2000.)
temfin *= (5.8E4-TLab)/5.6E4;
maximumTime = temfin;
// If the incoming particle is slow, use a larger stopping time
const G4double rMax = theNucleus->getUniverseRadius();
const G4double distance = 2.*rMax;
const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
const G4double traversalTime = distance / maxMesonVelocityProjection;
if(maximumTime < traversalTime)
maximumTime = traversalTime;
INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
// Fill in the relevant kinematic variables
theNucleus->setIncomingAngularMomentum(nb->getAngularMomentum());
theNucleus->setIncomingMomentum(nb->getMomentum());
if(isProton){
theNucleus->setInitialEnergy(pb->getMass() + nb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ() + 1,theNucleus->getS()));
}
else{
theNucleus->setInitialEnergy(pb->getMass() + nb->getEnergy()
+ ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ(),theNucleus->getS()));
}
// Reset the particle kinematics to the INCL values
for(ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
(*p)->makeProjectileSpectator();
}
nb->makeProjectileSpectator();
generateAllAvatars();
firstAvatar = false;
// Get the entry avatars for mesons
IAvatarList theAvatarList = obj->bringMesonStar(fslist, theNucleus);
delete obj;
theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
// Get the entry avatars from Coulomb and put them in the Store
ParticleEntryAvatar *theEntryAvatar = CoulombDistortion::bringToSurfaceAbar(nb, theNucleus);
if(theEntryAvatar) {
theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
INCL_DEBUG("Avatars added" << '\n');
return nb->getTransversePosition().mag();
} else {
INCL_DEBUG("Antineutron is transparent, not entering the nucleus " << '\n');
theNucleus->setIncomingAngularMomentum(ThreeVector(0.,0.,0.));
theNucleus->setIncomingMomentum(ThreeVector(0.,0.,0.));
//Transparent event
theNucleus->getStore()->addToMissed(nb);
delete pb;
return 99.;
}
delete theConfig;
}
} else{
theNucleus->setNucleusNucleusCollision();
currentTime =0.0;
maximumTime = 29.8 * std::pow(theNucleus->getA(), 0.16);
ProjectileRemnant *pr = new ProjectileRemnant(species, kineticEnergy);
INCL_DEBUG("Antideuteron annihilation Model A chosen, Annihilation of Antideuteron as a whole" << '\n');
AntinucleiAtrestEntryChannel *obj = new AntinucleiAtrestEntryChannel(theNucleus, pr, ThreeVector(), ThreeVector());
ParticleList fslist = obj->makeMesonStar();
//set Stopping time according to highest meson energy of the star
G4double temfin;
G4double TLab;
std::vector<G4double> energies;
std::vector<G4double> projections;
ThreeVector ab, cd;
for(ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
energies.push_back((*pit)->getKineticEnergy());
ab = (*pit)->boostVector();
cd = (*pit)->getPosition();
projections.push_back(ab.dot(cd)); //projection length
}// make vector of energies
temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
TLab = *max_element(energies.begin(), energies.end()); //choose max energy
// energy-dependent stopping time above 2 AGeV
if(TLab>2000.)
temfin *= (5.8E4-TLab)/5.6E4;
maximumTime = temfin;
// If the incoming particle is slow, use a larger stopping time
const G4double rMax = theNucleus->getUniverseRadius();
const G4double distance = 2.*rMax;
const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
const G4double traversalTime = distance / maxMesonVelocityProjection;
if(maximumTime < traversalTime)
maximumTime = traversalTime;
INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
// Fill in the relevant kinematic variables
theNucleus->setIncomingAngularMomentum(G4INCL::ThreeVector(0., 0., 0.));
theNucleus->setIncomingMomentum(G4INCL::ThreeVector(0.,0.,0.));
if(theNucleus->getAnnihilationType()==DNbarNPbarNType)
theNucleus->setInitialEnergy(pr->getMass() + ParticleTable::getTableMass(theNucleus->getA() + 2, theNucleus->getZ(), theNucleus->getS()));
else if(theNucleus->getAnnihilationType()==DNbarPPbarPType)
theNucleus->setInitialEnergy(pr->getMass() + ParticleTable::getTableMass(theNucleus->getA() + 2, theNucleus->getZ() + 2,theNucleus->getS()));
else if(theNucleus->getAnnihilationType() == DNbarNPbarPType || theNucleus->getAnnihilationType()==DNbarPPbarNType)
theNucleus->setInitialEnergy(pr->getMass() + ParticleTable::getTableMass(theNucleus->getA() + 2, theNucleus->getZ() +1, theNucleus->getS()));
for(ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
(*p)->makeProjectileSpectator();
}
generateAllAvatars();
firstAvatar = false;
IAvatarList theAvatarList = obj->bringMesonStar(fslist, theNucleus);
delete pr;
delete obj;
theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
INCL_DEBUG("Avatars added" << '\n');
return 99.;
}
}
G4double StandardPropagationModel::getStoppingTime() {
return maximumTime;
@@ -453,6 +786,20 @@ namespace G4INCL {
G4INCL::Particle const * const particleB, G4double *minDistOfApproach) const
{
G4double time;
// When annihilation is forced for antinucleons below the threshold energy, set the time step at 0.001 (when to have the smallest avatar time)
Config const *theConfig=theNucleus->getStore()->getConfig();
if (((particleA->getType()==antiProton) && (particleA->getKineticEnergy() <= theConfig->getAtrestThreshold())) ||
((particleB->getType()==antiProton) && (particleB->getKineticEnergy() <= theConfig->getAtrestThreshold())) ||
((particleA->getType()==antiNeutron) && (particleA->getKineticEnergy() <= particleA->getPotentialEnergy())) ||
((particleB->getType()==antiNeutron) && (particleB->getKineticEnergy() <= particleB->getPotentialEnergy())) ||
((particleA->getType()==antiProton && particleA->getEnergy() <= particleA->getINCLMass())) ||
((particleB->getType()==antiProton && particleB->getEnergy() <= particleB->getINCLMass())) ||
((particleA->getType()==antiNeutron && particleA->getEnergy() <= particleA->getINCLMass())) ||
((particleB->getType()==antiNeutron && particleB->getEnergy() <= particleB->getINCLMass())))
{
return currentTime + 0.001;
}
G4INCL::ThreeVector t13 = particleA->getPropagationVelocity();
t13 -= particleB->getPropagationVelocity();
G4INCL::ThreeVector distance = particleA->getPosition();
@@ -58,6 +58,8 @@
#include "G4CompetitiveFission.hh"
#include "G4FissionLevelDensityParameterINCLXX.hh"
#include "G4PhysicsModelCatalog.hh"
#include "G4INCLConfig.hh"
#include "G4INCLRandom.hh"
#include "G4HyperNucleiProperties.hh"
#include "G4HyperTriton.hh"
@@ -179,6 +181,7 @@ G4HadFinalState* G4INCLXXInterface::ApplyYourself(const G4HadProjectile& aTrack,
const G4bool isIonTrack = trackDefinition->GetParticleType()==G4GenericIon::GenericIon()->GetParticleType();
const G4int trackA = trackDefinition->GetAtomicMass();
const G4int trackZ = (G4int) trackDefinition->GetPDGCharge();
const G4int trackPDG = (G4int) trackDefinition->GetPDGEncoding();
const G4int trackL = trackDefinition->GetNumberOfLambdasInHypernucleus();
const G4int nucleusA = theNucleus.GetA_asInt();
const G4int nucleusZ = theNucleus.GetZ_asInt();
@@ -194,8 +197,8 @@ G4HadFinalState* G4INCLXXInterface::ApplyYourself(const G4HadProjectile& aTrack,
}
// For reactions on nucleons, use the backup model (without complaining),
// except for anti_proton projectile (in this case, INCLXX is used).
if(trackA<=1 && nucleusA<=1 && (trackZ>=0 || trackA==0)) {
// except for anti_proton and anti_neutron projectile (in this case, INCLXX is used).
if(trackA<=1 && nucleusA<=1 && (trackPDG!=-2212 && trackPDG!=-2112)) {
return theBackupModelNucleon->ApplyYourself(aTrack, theNucleus);
}
@@ -411,6 +414,7 @@ G4HadFinalState* G4INCLXXInterface::ApplyYourself(const G4HadProjectile& aTrack,
);
const G4double excitationE = eventInfo.EStarRem[i];
G4double nuclearMass = excitationE;
if ( S == 0 ) {
nuclearMass += G4NucleiProperties::GetNuclearMass(A, Z);
} else {
@@ -461,7 +465,23 @@ G4HadFinalState* G4INCLXXInterface::ApplyYourself(const G4HadProjectile& aTrack,
theResult.SetStatusChange(stopAndKill);
remnants.clear();
} else {
// Check four-momentum conservation
/* // Check four-momentum conservation
G4INCL::Config *theConfig;
theConfig=&theInterfaceStore->GetINCLConfig();
G4double nbatrestThreshold=theConfig->getnbAtrestThreshold();
G4double pbatrestThreshold=theConfig->getAtrestThreshold();
if (((trackDefinition->GetParticleName() == "anti_neutron") && // in INCL antinucleon at rest is considered with 0 kinetic energy
(aTrack.GetKineticEnergy() <= nbatrestThreshold)) ||
((trackDefinition->GetParticleName() == "anti_proton") &&
(aTrack.GetKineticEnergy() <= pbatrestThreshold)) ||
((trackDefinition->GetParticleName() == "anti_neutron") &&
((theTargetNucleus->GetA_asInt()==1 || theTargetNucleus->GetA_asInt()==2) && theTargetNucleus->GetZ_asInt()==1)) ||
((trackDefinition->GetParticleName() == "anti_proton") &&
((theTargetNucleus->GetA_asInt()==1 || theTargetNucleus->GetA_asInt()==2) && theTargetNucleus->GetZ_asInt()==1)))
{
fourMomentumIn.setE(theNucleusMass + theTrackMass);
fourMomentumIn.setVect(theTrackMomentum-theTrackMomentum);
}*/
const G4LorentzVector violation4Momentum = fourMomentumOut - fourMomentumIn;
const G4double energyViolation = std::abs(violation4Momentum.e());
const G4double momentumViolation = violation4Momentum.rho();
@@ -573,6 +593,7 @@ G4INCL::ParticleType G4INCLXXInterface::toINCLParticleType(G4ParticleDefinition
else if(pdef == G4He3::He3()) return G4INCL::Composite;
else if(pdef == G4Alpha::Alpha()) return G4INCL::Composite;
else if(pdef == G4AntiProton::AntiProton()) return G4INCL::antiProton;
else if(pdef == G4AntiNeutron::AntiNeutron()) return G4INCL::antiNeutron;
else if(pdef->GetParticleType() == G4GenericIon::GenericIon()->GetParticleType()) return G4INCL::Composite;
else return G4INCL::UnknownParticle;
}
@@ -613,13 +634,17 @@ G4ParticleDefinition *G4INCLXXInterface::toG4ParticleDefinition(G4int A, G4int Z
} else if(PDGCode == -321) { return G4KaonMinus::KaonMinus();
} else if(PDGCode == 130) { return G4KaonZeroLong::KaonZeroLong();
} else if(PDGCode == 310) { return G4KaonZeroShort::KaonZeroShort();
} else if(PDGCode == 311 || PDGCode == -311) {
if (G4INCL::Random::shoot() < 0.5) return G4KaonZeroShort::KaonZeroShort();
else return G4KaonZeroLong::KaonZeroLong();
} else if(PDGCode == 1002) { return G4Deuteron::Deuteron();
} else if(PDGCode == 1003) { return G4Triton::Triton();
} else if(PDGCode == 2003) { return G4He3::He3();
} else if(PDGCode == 2004) { return G4Alpha::Alpha();
} else if(PDGCode == -2212) { return G4AntiProton::AntiProton();
} else if(PDGCode == -2112) { return G4AntiNeutron::AntiNeutron();
} else if(S != 0) { // Assumed that -S gives the number of Lambdas
if (A == 3 && Z == 1 && S == -1 ) return G4HyperTriton::Definition();
if (A == 4 && Z == 1 && S == -1 ) return G4HyperH4::Definition();
@@ -663,15 +688,15 @@ G4double G4INCLXXInterface::remnant4MomentumScaling(G4double mass,
void G4INCLXXInterface::ModelDescription(std::ostream& outFile) const {
outFile
<< "The Liège Intranuclear Cascade (INCL++) is a model for reactions induced\n"
<< "by nucleons, pions and light ion on any nucleus. The reaction is\n"
<< "described as an avalanche of binary nucleon-nucleon collisions, which can\n"
<< "lead to the emission of energetic particles and to the formation of an\n"
<< "by nucleons, antinucleons, pions, kaons, Lambda, Sigma and light ion on any nucleus.\n"
<< "The reaction is described as an avalanche of binary nucleon-nucleon collisions,\n"
<< "which can lead to the emission of energetic particles and to the formation of an\n"
<< "excited thermalised nucleus (remnant). The de-excitation of the remnant is\n"
<< "outside the scope of INCL++ and is typically described by another model.\n\n"
<< "INCL++ has been reasonably well tested for nucleon (~50 MeV to ~15 GeV),\n"
<< "pion (idem) and light-ion projectiles (up to A=18, ~10A MeV to 1A GeV).\n"
<< "Most tests involved target nuclei close to the stability valley, with\n"
<< "numbers between 4 and 250.\n\n"
<< "numbers between 4 and 300.\n\n"
<< "Reference: D. Mancusi et al., Phys. Rev. C90 (2014) 054602\n\n";
}
@@ -54,6 +54,8 @@ namespace G4INCL {
nBlockedCollisions = 0;
nAcceptedDecays = 0;
nBlockedDecays = 0;
nAcceptedSrc=0;
nSrcPairs = 0;
currentTime = 0.0;
firstCollisionTime = 0.0;
firstCollisionXSec = 0.0;
@@ -68,10 +70,12 @@ namespace G4INCL {
nEmittedClusters = 0;
nEnergyViolationInteraction = 0;
};
void incrementAcceptedSrcCollisions() { nAcceptedSrc++; };
void incrementAcceptedCollisions() { nAcceptedCollisions++; };
void incrementBlockedCollisions() { nBlockedCollisions++; };
void incrementAcceptedDecays() { nAcceptedDecays++; };
void incrementSrcPairs() { nSrcPairs++; };
void incrementBlockedDecays() { nBlockedDecays++; };
void incrementAvatars(AvatarType type) { nAvatars[type]++; };
void incrementCascading() { nCascading++; }
@@ -96,6 +100,12 @@ namespace G4INCL {
void setCurrentTime(G4double t) { currentTime = t; };
G4double getCurrentTime() const { return currentTime; };
void setSrcPairs(G4int n) { nSrcPairs=n; };
G4int getSrcPairs() const { return nSrcPairs; };
void setAcceptedSrcCollisions(G4int n) { nAcceptedSrc=n; };
G4int getAcceptedSrcCollisions() const { return nAcceptedSrc; };
G4int getAcceptedCollisions() const { return nAcceptedCollisions; };
G4int getBlockedCollisions() const {return nBlockedCollisions; };
@@ -107,10 +117,12 @@ namespace G4INCL {
G4int getEnergyViolationInteraction() const { return nEnergyViolationInteraction; };
private:
G4int nAcceptedSrc;
G4int nAcceptedCollisions;
G4int nBlockedCollisions;
G4int nAcceptedDecays;
G4int nBlockedDecays;
G4int nSrcPairs;
G4double currentTime;
G4double firstCollisionTime;
G4double firstCollisionXSec;
@@ -219,6 +219,16 @@ namespace G4INCL {
/// \brief Set the ABLAXX datafile path
#ifdef INCL_DEEXCITATION_ABLAXX
void setABLAXXDataFilePath(std::string const &path) { ablaxxDataFilePath=path; }
G4double getFissionDispCoeff() const { return fissdisscoeff; }
G4double getLevDensAv() const { return levdensav; }
G4double getLevDensAs() const { return levdensas; }
G4double getLevDensAk() const { return levdensak; }
G4double getTempFreezeOut() const { return tfreezeout; }
G4float getEmissionBarrierFactorH2() const { return barrierfactorh2; }
G4float getEmissionBarrierFactorH3() const { return barrierfactorh3; }
G4float getEmissionBarrierFactorHe3() const { return barrierfactorhe3; }
G4float getEmissionBarrierFactorHe4() const { return barrierfactorhe4; }
G4float getEmissionBarrierFactorHe6() const { return barrierfactorhe6; }
#endif
std::string const &getINCLXXDataFilePath() const {
@@ -382,6 +392,19 @@ namespace G4INCL {
/// \brief Set the pbar at rest annihilation threshold
void setAtrestThreshold(const G4double t) { atrestThreshold=t; }
/// \brief Get the nbar at rest annihilation threshold
G4double getnbAtrestThreshold() const {return nbatrestThreshold;}
/// \brief Set the nbar at rest annihilation threshold
void setnbAtrestThreshold(const G4double t){ nbatrestThreshold=t;}
/// \brief Get the dbar at rest annihilation threshold
G4double getdbAtrestThreshold() const {return dbatrestThreshold;}
/// \brief Set the dbar at rest annihilation threshold
void setdbAtrestThreshold(const G4double t){ dbatrestThreshold=t;}
private:
@@ -430,6 +453,16 @@ namespace G4INCL {
DeExcitationType deExcitationType;
#ifdef INCL_DEEXCITATION_ABLAXX
std::string ablaxxDataFilePath;
G4double fissdisscoeff;
G4double levdensav;
G4double levdensas;
G4double levdensak;
G4double tfreezeout;
G4float barrierfactorh2;
G4float barrierfactorh3;
G4float barrierfactorhe3;
G4float barrierfactorhe4;
G4float barrierfactorhe6;
#endif
#ifdef INCL_DEEXCITATION_ABLA07
std::string abla07DataFilePath;
@@ -460,11 +493,15 @@ namespace G4INCL {
G4double cutNN;
G4bool ann;
//G4bool ann;
G4double bias;
G4double atrestThreshold;
G4double nbatrestThreshold;
G4double dbatrestThreshold;
#ifdef INCL_ROOT_USE
std::string rootSelectionString;
@@ -93,6 +93,11 @@ namespace G4INCL {
nucleonAbsorption(false),
pionAbsorption(false),
nDecays(0),
fission(false),
fissmode(0),
EStarFis((Float_t)0.0),
ASad(0),
ZSad(0),
nSrcCollisions(0),
nSrcPairs(0),
nBlockedCollisions(0),
@@ -101,6 +106,7 @@ namespace G4INCL {
deltasInside(false),
sigmasInside(false),
kaonsInside(false),
antinucleonsInside(false),
antikaonsInside(false),
lambdasInside(false),
forcedDeltasInside(false),
@@ -110,7 +116,9 @@ namespace G4INCL {
forcedSigmaOutside(false),
forcedStrangeInside(false),
emitLambda(0),
emitAntilambda(0),
emitKaon(false),
emitAntinucleon(false),
clusterDecay(false),
firstCollisionTime((Float_t)0.0),
firstCollisionXSec((Float_t)0.0),
@@ -274,6 +282,20 @@ namespace G4INCL {
Bool_t pionAbsorption;
/** \brief Number of accepted Delta decays */
Int_t nDecays;
/** \brief True if the event is fission */
Bool_t fission;
/** \brief Fission mode */
Short_t fissmode;
/** \brief Excitation energy above fission barrier [MeV] */
Float_t EStarFis;
/** \brief Mass number at saddle */
Short_t ASad;
/** \brief Charge number at saddle */
Short_t ZSad;
/** \brief Mass number at scission */
std::vector<Int_t> ASci;
/** \brief Charge number at scission */
std::vector<Int_t> ZSci;
/** \brief Number of accepted SRC collisions */
Int_t nSrcCollisions;
/** \brief Number of src pairs */
@@ -290,6 +312,8 @@ namespace G4INCL {
Bool_t sigmasInside;
/** \brief Event involved kaons in the nucleus at the end of the cascade */
Bool_t kaonsInside;
/** \brief Event involved antinucleons in the nucleus at the end of the cascade */
Bool_t antinucleonsInside;
/** \brief Event involved antikaons in the nucleus at the end of the cascade */
Bool_t antikaonsInside;
/** \brief Event involved lambdas in the nucleus at the end of the cascade */
@@ -308,8 +332,12 @@ namespace G4INCL {
Bool_t forcedStrangeInside;
/** \brief Number of forced Lambda emit out of the nucleus */
Int_t emitLambda;
/** \brief Number of forced Antilambda emit out of the nucleus */
Int_t emitAntilambda;
/** \brief Event involved forced Kaon emission */
Bool_t emitKaon;
/** \brief Event involved forced Antinucleon emission */
Bool_t emitAntinucleon;
/** \brief Event involved cluster decay */
Bool_t clusterDecay;
/** \brief Time of the first collision [fm/c] */
@@ -399,6 +427,13 @@ namespace G4INCL {
nucleonAbsorption = false;
pionAbsorption = false;
nDecays = 0;
fission = false;
fissmode = 0;
EStarFis = (Float_t)0.0;
ASad = 0;
ZSad = 0;
ASci.clear();
ZSci.clear();
nSrcCollisions = 0;
nSrcPairs = 0;
nBlockedCollisions = 0;
@@ -407,6 +442,7 @@ namespace G4INCL {
deltasInside = false;
sigmasInside = false;
kaonsInside = false;
antinucleonsInside = false;
antikaonsInside = false;
lambdasInside = false;
forcedDeltasInside = false;
@@ -416,7 +452,9 @@ namespace G4INCL {
forcedSigmaOutside = false;
forcedStrangeInside = false;
emitLambda = 0;
emitAntilambda = 0;
emitKaon = false;
emitAntinucleon = false;
clusterDecay = false;
firstCollisionTime = (Float_t)0.0;
firstCollisionXSec = (Float_t)0.0;
@@ -82,6 +82,8 @@ namespace G4INCL {
ParticleList const &getDestroyedParticles() const;
ParticleList const &getCreatedParticles() const;
ParticleList const &getEnteringParticles() const;
ParticleList &getSrcModifiedParticles();
FinalStateValidity getValidity() const { return validity; }
void makeValid() { validity = ValidFS; }
@@ -42,6 +42,7 @@
#include <string>
#include <vector>
#include "G4INCLParticleType.hh"
#include <iostream>
namespace G4INCL {
class Particle;
@@ -45,9 +45,9 @@
#include "G4INCLParticleType.hh"
namespace G4INCL {
const G4int TableZSize = 120;
const G4int TableASize = 290;
const G4int TableZSize = 128;
const G4int TableASize = 300;
namespace HFB {
#ifdef INCLXX_IN_GEANT4_MODE
@@ -82,6 +82,7 @@ namespace G4INCL {
virtual void postInteraction(FinalState *) = 0;
G4double getTime() const { return theTime; };
G4double setTime(G4double t) const { return t; };
virtual ParticleList getParticles() const = 0;
@@ -96,6 +96,7 @@ namespace G4INCL {
thePosition(rhs.thePosition),
nCollisions(rhs.nCollisions),
nDecays(rhs.nDecays),
nSrcPair(rhs.nSrcPair),
thePotentialEnergy(rhs.thePotentialEnergy),
rpCorrelated(rhs.rpCorrelated),
uncorrelatedMomentum(rhs.uncorrelatedMomentum),
@@ -108,6 +109,7 @@ namespace G4INCL {
theHelicity(rhs.theHelicity),
emissionTime(rhs.emissionTime),
outOfWell(rhs.outOfWell),
theSrcPartner(rhs.theSrcPartner),
theMass(rhs.theMass)
{
if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
@@ -147,6 +149,7 @@ namespace G4INCL {
std::swap(thePosition, rhs.thePosition);
std::swap(nCollisions, rhs.nCollisions);
std::swap(nDecays, rhs.nDecays);
std::swap(nSrcPair, rhs.nSrcPair),
std::swap(thePotentialEnergy, rhs.thePotentialEnergy);
// ID intentionally not swapped
@@ -158,6 +161,7 @@ namespace G4INCL {
std::swap(theHelicity, rhs.theHelicity);
std::swap(emissionTime, rhs.emissionTime);
std::swap(outOfWell, rhs.outOfWell);
std::swap(theSrcPartner, rhs.theSrcPartner);
std::swap(theMass, rhs.theMass);
std::swap(rpCorrelated, rhs.rpCorrelated);
@@ -344,6 +348,11 @@ namespace G4INCL {
theZ = 0;
theS = 0;
break;
case antiComposite:
theA = 0;
theZ = 0;
theS = 0;
break;
case UnknownParticle:
theA = 0;
theZ = 0;
@@ -352,7 +361,7 @@ namespace G4INCL {
break;
}
if( !isResonance() && t!=Composite )
if( !isResonance() && t!=Composite && t!=antiComposite )
setINCLMass();
}
@@ -480,6 +489,9 @@ namespace G4INCL {
/** \brief Returns the strangeness number. */
G4int getS() const { return theS; }
/** \brief Returns the strangeness number. */
G4int getSrcPair() const { return nSrcPair; }
G4double getBeta() const {
const G4double P = theMomentum.mag();
@@ -578,6 +590,9 @@ namespace G4INCL {
case Composite:
return ParticleTable::getINCLMass(theA,theZ,theS);
break;
case antiComposite:
return ParticleTable::getINCLMass(-theA,-theZ,theS);
break;
default:
INCL_ERROR("Particle::getINCLMass: Unknown particle type." << '\n');
@@ -631,6 +646,9 @@ namespace G4INCL {
case Composite:
return ParticleTable::getTableMass(theA,theZ,theS);
break;
case antiComposite:
return ParticleTable::getTableMass(-theA,-theZ,theS);
break;
default:
INCL_ERROR("Particle::getTableMass: Unknown particle type." << '\n');
@@ -684,6 +702,9 @@ namespace G4INCL {
case Composite:
return ParticleTable::getRealMass(theA,theZ,theS);
break;
case antiComposite:
return ParticleTable::getRealMass(-theA,-theZ,theS);
break;
default:
INCL_ERROR("Particle::getRealMass: Unknown particle type." << '\n');
@@ -737,33 +758,6 @@ namespace G4INCL {
return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
}
G4double getEmissionPbarQvalueCorrection(const G4int AParent, const G4int ZParent, const G4bool Victim) const {
G4int SParent = 0;
G4int SDaughter = 0;
G4int ADaughter = AParent - 1;
G4int ZDaughter;
G4bool isProton = Victim;
if(isProton){ //proton is annihilated
ZDaughter = ZParent - 1;
}
else { //neutron is annihilated
ZDaughter = ZParent;
}
G4double theQValue; //same procedure as for normal case
const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent,SParent);
const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter,SDaughter);
const G4double massTableParticle = getTableMass();
theQValue = massTableParent - massTableDaughter - massTableParticle;
const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent,SParent);
const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter,SDaughter);
const G4double massINCLParticle = getINCLMass();
return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
}
/**\brief Computes correction on the transfer Q-value
*
* Computes the correction that must be applied to INCL particles in
@@ -987,6 +981,9 @@ namespace G4INCL {
/** \brief Increment the number of decays undergone by the particle. **/
void incrementNumberOfDecays() { nDecays++; }
/** \brief Set the number of srcpairs. **/
void setNumberOfSrcPair(int n) { nSrcPair = n; }
/** \brief Mark the particle as out of its potential well
*
@@ -1000,6 +997,13 @@ namespace G4INCL {
/// \brief Check if the particle is out of its potential well
G4bool isOutOfWell() const { return outOfWell; }
/// \brief Set and reset src partner
void setSrcPartner() { theSrcPartner = true; }
void resetSrcPartner() { theSrcPartner = false; nSrcPair=0; }
/// \brief Check if the particle is a src partner
G4bool isSrcPartner() const { return theSrcPartner; }
void setEmissionTime(G4double t) { emissionTime = t; }
G4double getEmissionTime() { return emissionTime; };
@@ -1021,7 +1025,7 @@ namespace G4INCL {
G4double adjustEnergyFromMomentum();
G4bool isCluster() const {
return (theType == Composite);
return ((theType == Composite || theType == antiComposite));
}
/// \brief Set the frozen particle momentum
@@ -1094,6 +1098,8 @@ namespace G4INCL {
std::stringstream ss;
ss << "Particle (ID = " << ID << ") type = ";
ss << ParticleTable::getName(theType);
ss << ", SRC pair = " << nSrcPair;
ss << ", Potential energy = " << thePotentialEnergy;
ss << '\n'
<< " energy = " << theEnergy << '\n'
<< " momentum = "
@@ -1109,6 +1115,7 @@ namespace G4INCL {
std::stringstream ss;
ss << "(particle " << ID << " ";
ss << ParticleTable::getName(theType);
ss << nSrcPair << " ";
ss << '\n'
<< thePosition.dump()
<< '\n'
@@ -1236,6 +1243,7 @@ namespace G4INCL {
G4INCL::ThreeVector thePosition;
G4int nCollisions;
G4int nDecays;
G4int nSrcPair;
G4double thePotentialEnergy;
long ID;
@@ -1255,6 +1263,7 @@ namespace G4INCL {
G4double theHelicity;
G4double emissionTime;
G4bool outOfWell;
G4bool theSrcPartner;
/// \brief Time ordered vector of all biased vertices on the particle path
std::vector<G4int> theBiasCollisionVector;
@@ -188,12 +188,30 @@ namespace G4INCL {
/// \brief Getter for neutronSeparationEnergy
G4double getNeutronSeparationEnergy();
/// \brief Getter for antiprotonSeparationEnergy
G4double getantiProtonSeparationEnergy();
/// \brief Getter for antineutronSeparationEnergy
G4double getantiNeutronSeparationEnergy();
/// \brief Getter for antilambdaSeparationEnergy
G4double getantiLambdaSeparationEnergy();
/// \brief Getter for lambdaSeparationEnergy
G4double getLambdaSeparationEnergy();
/// \brief Setter for protonSeparationEnergy
void setProtonSeparationEnergy(const G4double s);
/// \brief Setter for protonSeparationEnergy
void setNeutronSeparationEnergy(const G4double s);
/// \brief Setter for lambdaSeparationEnergy
void setLambdaSeparationEnergy(const G4double s);
/// \brief Setter for antilambdaSeparationEnergy
void setantiLambdaSeparationEnergy(const G4double s);
/// \brief Get the name of the element from the atomic number
std::string getElementName(const G4int Z);
@@ -268,6 +286,12 @@ namespace G4INCL {
* \return the value of the r-p correlation coefficient
*/
G4double getRPCorrelationCoefficient(const ParticleType t);
/// \brief Get the configuration of src-pair correlations
G4bool getsrcPairConfig();
/// \brief Get the distance between src nucleons
G4float getsrcPairDistance();
/// \brief Get the thickness of the neutron skin
G4double getNeutronSkin();
@@ -82,6 +82,7 @@ namespace G4INCL {
KMinus,
KShort,
KLong,
antiComposite,
// WARNING: if you add more particle types, you MUST add them BEFORE the
// UnknownParticle type! This is because UnknownParticle is used as a
// counter of the number of available particle types.
@@ -110,6 +110,7 @@ namespace G4INCL {
crossSectionsString = "antiparticles";
crossSectionsType = AntiparticlesCrossSections;
hadronizationTime = 0.;
srcPairCorrelations = false;
#ifdef INCL_ROOT_USE
conciseROOTTree = false;
#endif
@@ -117,6 +118,8 @@ namespace G4INCL {
decayTimeThreshold = 1.e-20;
bias = 1.;
atrestThreshold = 200.;
nbatrestThreshold = 14;
dbatrestThreshold = 200.;
}
std::string Config::summary() {
@@ -86,6 +86,11 @@ namespace G4INCL {
{
return modified;
}
ParticleList &FinalState::getSrcModifiedParticles()
{
return modified;
}
ParticleList const &FinalState::getOutgoingParticles() const
{
@@ -69,6 +69,7 @@ namespace G4INCL {
thePosition(ThreeVector(0.,0.,0.)),
nCollisions(0),
nDecays(0),
nSrcPair(0),
thePotentialEnergy(0.0),
rpCorrelated(false),
uncorrelatedMomentum(0.),
@@ -81,6 +82,7 @@ namespace G4INCL {
theHelicity(0.0),
emissionTime(0.0),
outOfWell(false),
theSrcPartner(false),
theMass(0.)
{
ID = nextID;
@@ -96,7 +98,7 @@ namespace G4INCL {
thePropagationMomentum(&theMomentum),
theFrozenMomentum(theMomentum),
thePosition(position),
nCollisions(0), nDecays(0),
nCollisions(0), nDecays(0), nSrcPair(0),
thePotentialEnergy(0.),
rpCorrelated(false),
uncorrelatedMomentum(theMomentum.mag()),
@@ -107,7 +109,7 @@ namespace G4INCL {
theParentResonanceID(0),
#endif
theHelicity(0.0),
emissionTime(0.0), outOfWell(false)
emissionTime(0.0), outOfWell(false), theSrcPartner(false)
{
theParticipantType = TargetSpectator;
ID = nextID;
@@ -127,6 +129,7 @@ namespace G4INCL {
theFrozenMomentum(theMomentum),
thePosition(position),
nCollisions(0), nDecays(0),
nSrcPair(0),
thePotentialEnergy(0.),
rpCorrelated(false),
uncorrelatedMomentum(theMomentum.mag()),
@@ -137,7 +140,7 @@ namespace G4INCL {
theParentResonanceID(0),
#endif
theHelicity(0.0),
emissionTime(0.0), outOfWell(false)
emissionTime(0.0), outOfWell(false), theSrcPartner(false)
{
theParticipantType = TargetSpectator;
ID = nextID;
@@ -128,12 +128,12 @@ namespace G4INCL {
theZ = 0;
theS = -2;
theType = G4INCL::XiZero;
} else if(pS=="pb" || pS=="antiproton") {
} else if(pS=="pb" || pS=="pbar" || pS=="antiproton") {
theA = -1;
theZ = -1;
theS = 0;
theType = G4INCL::antiProton;
} else if(pS=="nb" || pS=="antineutron") {
} else if(pS=="nb" || pS=="nbar" || pS=="antineutron") {
theA = -1;
theZ = 0;
theS = 0;
@@ -233,6 +233,11 @@ namespace G4INCL {
theZ = 0;
theS = 0;
theType = G4INCL::Photon;
} else if (pS=="db" || pS=="dbar" || pS=="antideuteron"){
theA = -2;
theZ = -1;
theS = 0;
theType = G4INCL::antiComposite;
} else
parseNuclide(pS);
}
@@ -244,19 +249,33 @@ namespace G4INCL {
theS(ParticleTable::getStrangenessNumber(theType))
{}
ParticleSpecies::ParticleSpecies(const G4int A, const G4int Z) :
theType(Composite),
theA(A),
theZ(Z),
theS(0)
{}
ParticleSpecies::ParticleSpecies(const int A, const int Z){
if (A>=0){
theType = Composite;
theA = A;
theZ = Z;
theS = 0;
} else {
theType = antiComposite;
theA = A;
theZ = Z;
theS = 0;
}
}
ParticleSpecies::ParticleSpecies(const G4int A, const G4int Z, const G4int S) :
theType(Composite),
theA(A),
theZ(Z),
theS(S)
{}
ParticleSpecies::ParticleSpecies(const int A, const int Z, const int S){
if (A>=0){
theType = Composite;
theA = A;
theZ = Z;
theS = S;
} else {
theType = antiComposite;
theA = A;
theZ = Z;
theS = S;
}
}
void ParticleSpecies::parseNuclide(std::string const &pS) {
theType = Composite;
@@ -519,6 +538,12 @@ namespace G4INCL {
else if(theA == 1 && theZ == 0 && theS == -1) return 3122;
else return theA+theZ*1000-theS*1e6; // Here -theS because hyper-nucleus -> theS < 0
break;
case antiComposite:
if(theA == 1 && theZ == 1 && theS == 0) return -2212;
else if(theA == 1 && theZ == 0 && theS == 0) return -2112;
else if(theA == 1 && theZ == 0 && theS == -1) return -3122;
else return -(theA + theZ*1000 - theS*1e6);
break;
default:
INCL_ERROR("ParticleSpecies::getPDGCode: Unknown particle type." << '\n');
return 0;
@@ -208,7 +208,7 @@ namespace G4INCL {
/* Z=8 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100.}
};
const G4int elementTableSize = 113; // up to Cn
const G4int elementTableSize = 123; // up to Unbibio (Ubb)
/// \brief Table of chemical element names
const std::string elementTable[elementTableSize] = {
@@ -324,7 +324,17 @@ namespace G4INCL {
"Mt",
"Ds",
"Rg",
"Cn"
"Cn",
"Nh",
"Fl",
"Mc",
"Lv",
"Ts",
"Og",
"Uue",
"Ubn",
"Ubu",
"Ubb"
};
/// \brief Digit names to compose IUPAC element names
@@ -334,16 +344,21 @@ namespace G4INCL {
const G4double theINCLProtonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
const G4double theINCLNeutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
const G4double theINCLLambdaSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
//const G4double theINCLantiProtonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
const G4double theINCLantiProtonSeparationEnergy = 0.;
const G4double theINCLantiNeutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
const G4double theINCLantiProtonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
const G4double theINCLantiLambdaSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
G4ThreadLocal G4double protonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
G4ThreadLocal G4double neutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
G4ThreadLocal G4double lambdaSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
//G4ThreadLocal G4double antiprotonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
//G4ThreadLocal G4double antiprotonSeparationEnergy = 0.;
G4ThreadLocal G4double antineutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
G4ThreadLocal G4double antiprotonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
G4ThreadLocal G4double antilambdaSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
#undef INCL_DEFAULT_SEPARATION_ENERGY
G4ThreadLocal G4double rpCorrelationCoefficient[UnknownParticle];
G4ThreadLocal bool srcPairConfig = false;
G4ThreadLocal float srcPairDist = 0.0;
G4ThreadLocal G4double neutronSkin = 0.0;
G4ThreadLocal G4double neutronHalo = 0.0;
@@ -353,7 +368,7 @@ namespace G4INCL {
#endif
/// \brief Default value for constant Fermi momentum
G4ThreadLocal G4double constantFermiMomentum = 0.0;
G4ThreadLocal double constantFermiMomentum = PhysicalConstants::Pf;
/// \brief Transform a IUPAC char to an char representing an integer digit
char iupacToInt(char c) {
@@ -516,12 +531,14 @@ namespace G4INCL {
// Initialise the r-p correlation coefficients
std::fill(rpCorrelationCoefficient, rpCorrelationCoefficient + UnknownParticle, 1.);
if(theConfig) {
// Initialise the rp correlations
rpCorrelationCoefficient[Proton] = theConfig->getRPCorrelationCoefficient(Proton);
rpCorrelationCoefficient[Neutron] = theConfig->getRPCorrelationCoefficient(Neutron);
}
// Initialise the SRC parameters
srcPairConfig = theConfig->getsrcPairConfig();
srcPairDist = theConfig->getsrcPairDist();
// Initialise the neutron-skin parameters
if(theConfig) {
// Initialise the neutron-skin parameters
neutronSkin = theConfig->getNeutronSkin();
neutronHalo = theConfig->getNeutronHalo();
}
@@ -606,6 +623,8 @@ namespace G4INCL {
return getShortName(sp.theA,sp.theZ);
else if(sp.theType==Composite)
return getName(sp.theA,sp.theZ,sp.theS);
else if (sp.theType==antiComposite)
return getShortName(sp.theA,sp.theZ);
else
return getShortName(sp.theType);
}
@@ -615,13 +634,18 @@ namespace G4INCL {
return getName(sp.theA,sp.theZ);
else if(sp.theType==Composite)
return getName(sp.theA,sp.theZ,sp.theS);
else if(sp.theType==antiComposite)
return getName(sp.theA,sp.theZ);
else
return getName(sp.theType);
}
std::string getName(const G4int A, const G4int Z) {
std::stringstream stream;
stream << getElementName(Z) << "-" << A;
if(A<0)
stream << getElementName(-Z) << "b" << -A;
else
stream << getElementName(Z) << "-" << A;
return stream.str();
}
@@ -632,15 +656,18 @@ namespace G4INCL {
else if(S == -1)
stream << getElementName(Z) << "-" << A << "_" << "Lambda";
else
stream << getElementName(Z) << "-" << A << "_" << S << "-Lambda";
stream << getElementName(Z) << "-" << A << "_" << -S << "-Lambda";
return stream.str();
}
std::string getShortName(const G4int A, const G4int Z) {
std::stringstream stream;
stream << getElementName(Z);
if(A>0)
stream << A;
stream << getElementName(Z) << A;
else if(A<0)
stream << getElementName(-Z) << "b" << -A;
else
stream << getElementName(Z);
return stream.str();
}
@@ -713,6 +740,8 @@ namespace G4INCL {
return std::string("etaprime");
} else if(p == G4INCL::Photon) {
return std::string("photon");
} else if(p == G4INCL::antiComposite){
return std::string("anticomposite");
}
return std::string("unknown");
}
@@ -786,6 +815,8 @@ namespace G4INCL {
return std::string("etap");
} else if(p == G4INCL::Photon) {
return std::string("photon");
} else if(p == G4INCL::antiComposite) {
return std::string("anticomp");
}
return std::string("unknown");
}
@@ -1006,6 +1037,8 @@ namespace G4INCL {
G4double getTableSpeciesMass(const ParticleSpecies &p) {
if(p.theType == Composite)
return (*getTableMass)(p.theA, p.theZ, p.theS);
else if (p.theType == antiComposite)
return (*getTableMass)(-p.theA,-p.theZ,p.theS);
else
return (*getTableParticleMass)(p.theType);
}
@@ -1306,8 +1339,12 @@ namespace G4INCL {
return theINCLNeutronSeparationEnergy;
else if(t==Lambda)
return theINCLLambdaSeparationEnergy;
else if(t==antiLambda)
return theINCLantiLambdaSeparationEnergy;
else if(t==antiProton)
return theINCLantiProtonSeparationEnergy;
else if(t==antiNeutron)
return theINCLantiNeutronSeparationEnergy;
else {
INCL_ERROR("ParticleTable::getSeparationEnergyINCL : Unknown particle type." << '\n');
return 0.0;
@@ -1322,6 +1359,12 @@ namespace G4INCL {
return (*getTableParticleMass)(Neutron) + (*getTableMass)(A-1,Z,0) - (*getTableMass)(A,Z,0);
else if(t==Lambda)
return (*getTableParticleMass)(Lambda) + (*getTableMass)(A-1,Z,0) - (*getTableMass)(A,Z,-1);
else if(t==antiLambda)
return (*getTableParticleMass)(antiLambda) + (*getTableMass)(A+1,Z,0) - (*getTableMass)(A,Z,+1);
else if(t==antiProton)
return (*getTableParticleMass)(antiProton) + (*getTableMass)(A+1,Z+1,0) - (*getTableMass)(A,Z,0);
else if(t==antiNeutron)
return (*getTableParticleMass)(antiNeutron) + (*getTableMass)(A+1,Z,0) - (*getTableMass)(A,Z,0);
else {
INCL_ERROR("ParticleTable::getSeparationEnergyReal : Unknown particle type." << '\n');
return 0.0;
@@ -1335,18 +1378,30 @@ namespace G4INCL {
else
return getSeparationEnergyINCL(t, A, Z);
}
G4bool getsrcPairConfig() { return srcPairConfig; }
G4float getsrcPairDistance() { return srcPairDist; }
G4double getProtonSeparationEnergy() { return protonSeparationEnergy; }
G4double getNeutronSeparationEnergy() { return neutronSeparationEnergy; }
G4double getLambdaSeparationEnergy() { return lambdaSeparationEnergy; }
G4double getantiLambdaSeparationEnergy() { return antilambdaSeparationEnergy; }
G4double getantiProtonSeparationEnergy() { return antiprotonSeparationEnergy; }
G4double getantiNeutronSeparationEnergy() { return antineutronSeparationEnergy; }
void setProtonSeparationEnergy(const G4double sen) { protonSeparationEnergy = sen; }
void setNeutronSeparationEnergy(const G4double sen) { neutronSeparationEnergy = sen; }
void setLambdaSeparationEnergy(const G4double sen) { lambdaSeparationEnergy = sen; }
void setantiLambdaSeparationEnergy(const G4double sen) { antilambdaSeparationEnergy = sen; }
std::string getElementName(const G4int Z) {
if(Z<1) {