34#define INCLXX_IN_GEANT4_MODE 1
73 thePreCompoundModel(aPreCompound),
76 complainedAboutBackupModel(false),
77 complainedAboutPreCompound(false),
79 theINCLXXLevelDensity(NULL),
80 theINCLXXFissionProbability(NULL),
83 if(!thePreCompoundModel) {
91 if(std::getenv(
"G4INCLXX_NO_DE_EXCITATION")) {
92 G4String message =
"de-excitation is completely disabled!";
105 if(theFissionChannelCast) {
111 theInterfaceStore->
EmitBigWarning(
"INCL++/G4ExcitationHandler uses its own level-density parameter for fission");
113 theInterfaceStore->
EmitBigWarning(
"INCL++/G4ExcitationHandler could not use its own level-density parameter for fission");
119 if(std::getenv(
"G4INCLXX_DUMP_REMNANT"))
120 dumpRemnantInfo =
true;
122 dumpRemnantInfo =
false;
131 delete theINCLXXLevelDensity;
132 delete theINCLXXFissionProbability;
144 std::stringstream ss;
145 ss <<
"the model does not know how to handle a collision between a "
167 if(pA > theMaxProjMassINCL)
169 else if(tA > theMaxProjMassINCL)
187 if((isIonTrack && ((trackZ<=0 && trackL==0) || trackA<=trackZ)) ||
188 (nucleusA>1 && (nucleusZ<=0 || nucleusA<=nucleusZ))) {
197 if(trackA<=1 && nucleusA<=1) {
198 return theBackupModelNucleon->
ApplyYourself(aTrack, theNucleus);
204 if(trackA > theMaxProjMassINCL && nucleusA > theMaxProjMassINCL) {
205 if(!complainedAboutBackupModel) {
206 complainedAboutBackupModel =
true;
207 std::stringstream ss;
208 ss <<
"INCL++ refuses to handle reactions between nuclei with A>"
209 << theMaxProjMassINCL
210 <<
". A backup model ("
212 <<
") will be used instead.";
222 && trackKinE < cascadeMinEnergyPerNucleon) {
223 if(!complainedAboutPreCompound) {
224 complainedAboutPreCompound =
true;
225 std::stringstream ss;
226 ss <<
"INCL++ refuses to handle nucleon-induced reactions below "
227 << cascadeMinEnergyPerNucleon / MeV
228 <<
" MeV. A PreCoumpound model ("
230 <<
") will be used instead.";
233 return thePreCompoundModel->
ApplyYourself(aTrack, theNucleus);
239 const G4double theTrackEnergy = trackKinE + theTrackMass;
240 const G4double theTrackMomentumAbs2 = theTrackEnergy*theTrackEnergy - theTrackMass*theTrackMass;
241 const G4double theTrackMomentumAbs = ((theTrackMomentumAbs2>0.0) ? std::sqrt(theTrackMomentumAbs2) : 0.0);
246 fourMomentumIn.
setE(theTrackEnergy + theNucleusMass);
247 fourMomentumIn.
setVect(theTrackMomentum);
250 const G4bool inverseKinematics = AccurateProjectile(aTrack, theNucleus);
256 G4Nucleus *theTargetNucleus = &theNucleus;
257 if(inverseKinematics) {
261 if(oldProjectileDef != 0 && oldTargetDef != 0) {
265 if(newTargetA > 0 && newTargetZ > 0) {
267 theTargetNucleus =
new G4Nucleus(newTargetA, newTargetZ, newTargetL);
270 G4DynamicParticle swappedProjectileParticle(oldTargetDef, (*toInverseKinematics) * theProjectile4Momentum);
273 G4String message =
"badly defined target after swapping. Falling back to normal (non-swapped) mode.";
278 G4String message =
"oldProjectileDef or oldTargetDef was null";
314 std::list<G4Fragment> remnants;
316 const G4int maxTries = 200;
324 const G4double kineticEnergy = toINCLKineticEnergy(*aProjectileTrack);
332 -theTargetNucleus->
GetL());
339 if(inverseKinematics) {
360 momentum *= toLabFrame;
362 if(inverseKinematics) {
363 momentum *= *toDirectKinematics;
369 fourMomentumOut += momentum;
383 G4String message =
"the model produced a particle that couldn't be converted to Geant4 particle.";
394 if((
Z == 0 &&
S == 0 &&
A > 1 ) ||
395 (
Z == 0 &&
S != 0 &&
A < 4 ) ||
396 (
Z != 0 &&
S != 0 &&
A ==
Z + std::abs(
S) )) {
397 std::stringstream ss;
398 ss <<
"unphysical residual fragment : Z=" <<
Z <<
" S=" <<
S <<
" A=" <<
A
399 <<
" skipping it and resampling the collision";
409 eventInfo.
jxRem[i]*hbar_Planck,
410 eventInfo.
jyRem[i]*hbar_Planck,
411 eventInfo.
jzRem[i]*hbar_Planck
421 const G4double scaling = remnant4MomentumScaling(nuclearMass, kinE, px, py, pz);
424 if(std::abs(scaling - 1.0) > 0.01) {
425 std::stringstream ss;
426 ss <<
"momentum scaling = " << scaling
427 <<
"\n Lorentz vector = " << fourMomentum
428 <<
")\n A = " <<
A <<
", Z = " <<
Z <<
", S = " <<
S
429 <<
"\n E* = " << excitationE <<
", nuclearMass = " << nuclearMass
430 <<
"\n remnant i=" << i <<
", nRemnants=" << eventInfo.
nRemnants
434 <<
", in " << (inverseKinematics ?
"inverse" :
"direct") <<
" kinematics.";
439 fourMomentum *= toLabFrame;
442 if(inverseKinematics) {
443 fourMomentum *= *toDirectKinematics;
447 fourMomentumOut += fourMomentum;
451 if(dumpRemnantInfo) {
452 G4cerr <<
"G4INCLXX_DUMP_REMNANT: " << remnant <<
" spin: " << spin <<
G4endl;
454 remnants.push_back(remnant);
466 const G4LorentzVector violation4Momentum = fourMomentumOut - fourMomentumIn;
467 const G4double energyViolation = std::abs(violation4Momentum.
e());
468 const G4double momentumViolation = violation4Momentum.
rho();
470 std::stringstream ss;
471 ss <<
"energy conservation violated by " << energyViolation/MeV <<
" MeV in "
474 <<
" inelastic reaction, in " << (inverseKinematics ?
"inverse" :
"direct") <<
" kinematics. Will resample.";
483 std::stringstream ss;
484 ss <<
"momentum conservation violated by " << momentumViolation/MeV <<
" MeV in "
487 <<
" inelastic reaction, in " << (inverseKinematics ?
"inverse" :
"direct") <<
" kinematics. Will resample.";
499 }
while(!eventIsOK && nTries < maxTries);
502 if(inverseKinematics) {
503 delete aProjectileTrack;
504 delete theTargetNucleus;
505 delete toInverseKinematics;
506 delete toDirectKinematics;
510 std::stringstream ss;
511 ss <<
"maximum number of tries exceeded for the proposed "
513 <<
" + " << theIonTable->
GetIonName(nucleusZ, nucleusA, 0)
514 <<
" inelastic reaction, in " << (inverseKinematics ?
"inverse" :
"direct") <<
" kinematics.";
525 for(std::list<G4Fragment>::iterator i = remnants.begin();
526 i != remnants.end(); ++i) {
529 for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
530 fragment != deExcitationResult->end(); ++fragment) {
534 theResult.
AddSecondary(theFragment, (*fragment)->GetCreatorModelID());
538 for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
539 fragment != deExcitationResult->end(); ++fragment) {
542 deExcitationResult->clear();
543 delete deExcitationResult;
549 if((theTally = theInterfaceStore->
GetTally()))
550 theTally->
Tally(aTrack, theNucleus, theResult);
605 }
else if(PDGCode == 221) {
return G4Eta::Eta();
619 }
else if(PDGCode == 2003) {
return G4He3::He3();
628 }
else if(
A > 0 &&
Z > 0 &&
A >
Z) {
629 return theIonTable->
GetIon(
Z,
A, 0);
652 const G4double p2 = px*px + py*py + pz*pz;
654 const G4double pnew2 = kineticE*kineticE + 2.0*kineticE*mass;
655 return std::sqrt(pnew2)/std::sqrt(p2);
663 <<
"The Liège Intranuclear Cascade (INCL++) is a model for reactions induced\n"
664 <<
"by nucleons, pions and light ion on any nucleus. The reaction is\n"
665 <<
"described as an avalanche of binary nucleon-nucleon collisions, which can\n"
666 <<
"lead to the emission of energetic particles and to the formation of an\n"
667 <<
"excited thermalised nucleus (remnant). The de-excitation of the remnant is\n"
668 <<
"outside the scope of INCL++ and is typically described by another model.\n\n"
669 <<
"INCL++ has been reasonably well tested for nucleon (~50 MeV to ~15 GeV),\n"
670 <<
"pion (idem) and light-ion projectiles (up to A=18, ~10A MeV to 1A GeV).\n"
671 <<
"Most tests involved target nuclei close to the stability valley, with\n"
672 <<
"numbers between 4 and 250.\n\n"
673 <<
"Reference: D. Mancusi et al., Phys. Rev. C90 (2014) 054602\n\n";
G4double S(G4double temp)
Header file for the G4INCLXXInterfaceStore class.
CLHEP::HepLorentzRotation G4LorentzRotation
std::vector< G4ReactionProduct * > G4ReactionProductVector
G4GLOB_DLL std::ostream G4cerr
HepLorentzRotation inverse() const
Hep3Vector boostVector() const
void setVect(const Hep3Vector &)
HepRotation inverse() const
HepRotation & rotateZ(double delta)
HepRotation & rotateY(double delta)
static G4AntiKaonZero * AntiKaonZero()
void SetEmissionStrategy(G4VEmissionProbability *aFissionProb)
void SetLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
static G4Deuteron * Deuteron()
static G4DoubleHyperDoubleNeutron * Definition()
static G4DoubleHyperH4 * Definition()
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
G4VEvaporation * GetEvaporation()
Revised level-density parameter for fission after INCL++.
void SetFissionLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
void SetCreatorModelID(G4int value)
void SetAngularMomentum(const G4ThreeVector &)
static G4GenericIon * GenericIon()
void SetStatusChange(G4HadFinalStateStatus aS)
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
std::size_t GetNumberOfSecondaries() const
void SetEnergyChange(G4double anEnergy)
G4HadSecondary * GetSecondary(size_t i)
void SetMomentumChange(const G4ThreeVector &aV)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4DynamicParticle * GetParticle()
void SetParentResonanceDef(const G4ParticleDefinition *parentDef)
void SetParentResonanceID(const G4int parentID)
G4HadronicInteraction * FindModel(const G4String &name)
static G4HadronicInteractionRegistry * Instance()
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
const G4String & GetModelName() const
static G4HyperAlpha * Definition()
static G4HyperH4 * Definition()
static G4HyperHe5 * Definition()
static G4double GetNuclearMass(G4int A, G4int Z, G4int L)
static G4HyperTriton * Definition()
Singleton class for configuring the INCL++ Geant4 interface.
void EmitWarning(const G4String &message)
Emit a warning to G4cout.
static G4INCLXXInterfaceStore * GetInstance()
Get the singleton instance.
G4int GetMaxProjMassINCL() const
Getter for theMaxProjMassINCL.
G4INCL::INCL * GetINCLModel()
Get the cached INCL model engine.
G4double GetConservationTolerance() const
Getter for conservationTolerance.
void EmitBigWarning(const G4String &message) const
Emit a BIG warning to G4cout.
G4double GetCascadeMinEnergyPerNucleon() const
Getter for cascadeMinEnergyPerNucleon.
G4INCLXXVInterfaceTally * GetTally() const
Getter for the interface tally.
G4bool GetAccurateProjectile() const
Getter for accurateProjectile.
virtual void ModelDescription(std::ostream &outFile) const
G4ReactionProductVector * Propagate(G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus)
G4INCLXXInterface(G4VPreCompoundModel *const aPreCompound=0)
G4String const & GetDeExcitationModelName() const
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &theNucleus)
virtual void Tally(G4HadProjectile const &aTrack, G4Nucleus const &theNucleus, G4HadFinalState const &result)=0
const EventInfo & processEvent()
const G4String & GetIonName(G4int Z, G4int A, G4int lvl=0) const
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
G4double GetIonMass(G4int Z, G4int A, G4int nL=0, G4int lvl=0) const
static G4KaonMinus * KaonMinus()
static G4KaonPlus * KaonPlus()
static G4KaonZeroLong * KaonZeroLong()
static G4KaonZeroShort * KaonZeroShort()
static G4KaonZero * KaonZero()
static G4Lambda * Lambda()
static G4Neutron * NeutronDefinition()
static G4Neutron * Neutron()
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4int GetAtomicNumber() const
const G4String & GetParticleType() const
G4double GetPDGMass() const
G4int GetAtomicMass() const
G4double GetPDGCharge() const
G4int GetNumberOfLambdasInHypernucleus() const
G4int GetBaryonNumber() const
const G4String & GetParticleName() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
static G4int GetModelID(const G4int modelIndex)
static G4PionMinus * PionMinus()
static G4PionPlus * PionPlus()
static G4PionZero * PionZero()
static G4Proton * ProtonDefinition()
static G4Proton * Proton()
static G4SigmaMinus * SigmaMinus()
static G4SigmaPlus * SigmaPlus()
static G4SigmaZero * SigmaZero()
static G4Triton * Triton()
G4VEvaporationChannel * GetFissionChannel()
G4VPreCompoundModel * theDeExcitation
virtual G4ReactionProductVector * DeExcite(G4Fragment &aFragment)=0
G4ExcitationHandler * GetExcitationHandler() const
G4double energy(const ThreeVector &p, const G4double m)
Short_t S[maxSizeParticles]
Particle strangeness number.
Int_t parentResonancePDGCode[maxSizeParticles]
Particle's parent resonance PDG code.
Short_t nRemnants
Number of remnants.
Bool_t transparent
True if the event is transparent.
Short_t A[maxSizeParticles]
Particle mass number.
Float_t EKinRem[maxSizeRemnants]
Remnant kinetic energy [MeV].
Int_t parentResonanceID[maxSizeParticles]
Particle's parent resonance unique ID identifier.
Float_t jzRem[maxSizeRemnants]
Remnant angular momentum, z component [ ].
Float_t EStarRem[maxSizeRemnants]
Remnant excitation energy [MeV].
Short_t Z[maxSizeParticles]
Particle charge number.
Float_t EKin[maxSizeParticles]
Particle kinetic energy [MeV].
Short_t nParticles
Number of particles in the final state.
Float_t jxRem[maxSizeRemnants]
Remnant angular momentum, x component [ ].
Float_t px[maxSizeParticles]
Particle momentum, x component [MeV/c].
Short_t SRem[maxSizeRemnants]
Remnant strangeness number.
Float_t pxRem[maxSizeRemnants]
Remnant momentum, x component [MeV/c].
Float_t pyRem[maxSizeRemnants]
Remnant momentum, y component [MeV/c].
Float_t pzRem[maxSizeRemnants]
Remnant momentum, z component [MeV/c].
Float_t pz[maxSizeParticles]
Particle momentum, z component [MeV/c].
Int_t PDGCode[maxSizeParticles]
PDG numbering of the particles.
Float_t jyRem[maxSizeRemnants]
Remnant angular momentum, y component [ ].
Float_t py[maxSizeParticles]
Particle momentum, y component [MeV/c].
Short_t ARem[maxSizeRemnants]
Remnant mass number.
Short_t ZRem[maxSizeRemnants]
Remnant charge number.