34 #define INCLXX_IN_GEANT4_MODE 1
79 :propagationModel(0), theA(208), theZ(82),
80 targetInitSuccess(false),
82 maxUniverseRadius(0.),
83 maxInteractionDistance(0.),
84 fixedImpactParameter(0.),
87 forceTransparent(false),
91 #ifdef INCLXX_IN_GEANT4_MODE
93 #else // INCLXX_IN_GEANT4_MODE
95 #endif // INCLXX_IN_GEANT4_MODE
135 cascadeAction->beforeRunAction(theConfig);
140 theGlobalInfo.rootSelection = theConfig->getROOTSelectionString();
143 #ifndef INCLXX_IN_GEANT4_MODE
148 theGlobalInfo.
Ap = theSpecies.
theA;
149 theGlobalInfo.
Zp = theSpecies.
theZ;
158 #ifndef INCLXX_IN_GEANT4_MODE
159 NuclearMassTable::deleteTable();
167 #ifndef INCLXX_IN_GEANT4_MODE
168 Logger::deleteLoggerSlave();
172 cascadeAction->afterRunAction();
173 delete cascadeAction;
174 delete propagationModel;
179 if(A < 0 || A > 300 || Z < 1 || Z > 200) {
180 INCL_ERROR(
"Unsupported target: A = " << A <<
" Z = " << Z <<
'\n'
181 <<
"Target configuration rejected." <<
'\n');
185 (projectileSpecies.
theZ==projectileSpecies.
theA || projectileSpecies.
theZ==0)) {
186 INCL_ERROR(
"Unsupported projectile: A = " << projectileSpecies.
theA <<
" Z = " << projectileSpecies.
theZ <<
'\n'
187 <<
"Projectile configuration rejected." <<
'\n');
192 forceTransparent =
false;
195 initUniverseRadius(projectileSpecies, kineticEnergy, A, Z);
207 INCL_DEBUG(
"Maximum impact parameter initialised: " << maxImpactParameter <<
'\n');
210 initMaxInteractionDistance(projectileSpecies, kineticEnergy);
217 if(projectileSpecies.
theA > 0)
220 minRemnantSize =
std::min(theA-1, 4);
228 nucleus =
new Nucleus(A, Z, theConfig, maxUniverseRadius);
243 targetInitSuccess =
prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ);
245 if(!targetInitSuccess) {
246 INCL_WARN(
"Target initialisation failed for A=" << targetA <<
", Z=" << targetZ <<
'\n');
251 cascadeAction->beforeCascadeAction(propagationModel);
253 const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
257 cascadeAction->afterCascadeAction(nucleus);
265 theEventInfo.
reset();
271 theEventInfo.
Ap = projectileSpecies.
theA;
272 theEventInfo.
Zp = projectileSpecies.
theZ;
273 theEventInfo.
Ep = kineticEnergy;
274 theEventInfo.
At = nucleus->
getA();
275 theEventInfo.
Zt = nucleus->
getZ();
278 if(maxImpactParameter<=0.) {
288 if(fixedImpactParameter<0.) {
289 impactParameter = maxImpactParameter * std::sqrt(
Random::shoot0());
292 impactParameter = fixedImpactParameter;
295 INCL_DEBUG(
"Selected impact parameter: " << impactParameter <<
'\n');
300 const G4double effectiveImpactParameter = propagationModel->
shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
301 if(effectiveImpactParameter < 0.) {
315 void INCL::cascade() {
316 FinalState *finalState =
new FinalState;
318 unsigned long loopCounter = 0;
319 const unsigned long maxLoopCounter = 10000000;
322 cascadeAction->beforePropagationAction(propagationModel);
326 IAvatar *avatar = propagationModel->
propagate(finalState);
331 cascadeAction->afterPropagationAction(propagationModel, avatar);
333 if(avatar == 0)
break;
336 cascadeAction->beforeAvatarAction(avatar, nucleus);
345 avatar->fillFinalState(finalState);
348 cascadeAction->afterAvatarAction(avatar, nucleus, finalState);
357 }
while(continueCascade() && loopCounter<maxLoopCounter);
362 void INCL::postCascade() {
368 INCL_DEBUG(
"Trying compound nucleus" <<
'\n');
369 makeCompoundNucleus();
372 #ifndef INCLXX_IN_GEANT4_MODE
373 if(!theEventInfo.
transparent) globalConservationChecks(
true);
382 if(projectileRemnant) {
417 INCL_DEBUG(
"Cascade resulted in complete fusion, using realistic fusion kinematics" <<
'\n');
423 INCL_WARN(
"Complete-fusion kinematics yields negative excitation energy, returning a transparent!" <<
'\n');
438 if(nucleus->
getA()==1 && minRemnantSize>1) {
439 INCL_ERROR(
"Computing one-nucleon recoil kinematics. We should never be here nowadays, cascade should stop earlier than this." <<
'\n');
443 #ifndef INCLXX_IN_GEANT4_MODE
445 globalConservationChecks(
false);
450 if(nucleus->
hasRemnant()) rescaleOutgoingForRecoil();
457 #ifndef INCLXX_IN_GEANT4_MODE
459 globalConservationChecks(
true);
468 void INCL::makeCompoundNucleus() {
475 forceTransparent =
true;
483 nucleus->
setA(theEventInfo.
At);
484 nucleus->
setZ(theEventInfo.
Zt);
492 G4int theCNA=theEventInfo.
At, theCNZ=theEventInfo.
Zt;
497 ParticleList
const &initialProjectileComponents = theProjectileRemnant->getParticles();
498 std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
500 std::random_shuffle(shuffledComponents.begin(), shuffledComponents.end(),
Random::getAdapter());
503 G4bool atLeastOneNucleonEntering =
false;
504 for(std::vector<Particle*>::const_iterator
p=shuffledComponents.begin(), e=shuffledComponents.end();
p!=e; ++
p) {
508 (*p)->getPropagationVelocity(),
509 maxInteractionDistance));
510 if(!intersectionInteractionDistance.exists)
514 atLeastOneNucleonEntering =
true;
515 ParticleEntryAvatar *theAvatar =
new ParticleEntryAvatar(0.0, nucleus, *
p);
517 FinalState *fs = theAvatar->getFinalState();
527 theCNZ += (*p)->getZ();
537 if(!success || !atLeastOneNucleonEntering) {
538 INCL_DEBUG(
"No nucleon entering in forced CN, forcing a transparent" <<
'\n');
539 forceTransparent =
true;
548 theCNEnergy -= theProjectileRemnant->getEnergy();
549 theCNMomentum -= theProjectileRemnant->getMomentum();
556 theCNSpin -= theProjectileRemnant->getAngularMomentum();
560 const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
561 if(theCNInvariantMassSquared<0.) {
563 forceTransparent =
true;
566 const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
567 if(theCNExcitationEnergy<0.) {
569 INCL_DEBUG(
"CN excitation energy is negative, forcing a transparent" <<
'\n'
570 <<
" theCNA = " << theCNA <<
'\n'
571 <<
" theCNZ = " << theCNZ <<
'\n'
572 <<
" theCNEnergy = " << theCNEnergy <<
'\n'
573 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" <<
'\n'
574 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy <<
'\n'
575 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" <<
'\n'
577 forceTransparent =
true;
581 INCL_DEBUG(
"CN excitation energy is positive, forcing a CN" <<
'\n'
582 <<
" theCNA = " << theCNA <<
'\n'
583 <<
" theCNZ = " << theCNZ <<
'\n'
584 <<
" theCNEnergy = " << theCNEnergy <<
'\n'
585 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" <<
'\n'
586 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy <<
'\n'
587 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" <<
'\n'
589 nucleus->
setA(theCNA);
590 nucleus->
setZ(theCNZ);
594 nucleus->
setMass(theCNMass+theCNExcitationEnergy);
612 void INCL::rescaleOutgoingForRecoil() {
613 RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
616 const RootFinder::Solution theSolution =
RootFinder::solve(&theRecoilFunctor, 1.0);
617 if(theSolution.success) {
618 theRecoilFunctor(theSolution.x);
620 INCL_WARN(
"Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." <<
'\n');
625 #ifndef INCLXX_IN_GEANT4_MODE
626 void INCL::globalConservationChecks(
G4bool afterRecoil) {
631 const G4double pTransBalance = theBalance.momentum.perp();
632 if(theBalance.Z != 0) {
633 INCL_ERROR(
"Violation of charge conservation! ZBalance = " << theBalance.Z <<
'\n');
635 if(theBalance.A != 0) {
636 INCL_ERROR(
"Violation of baryon-number conservation! ABalance = " << theBalance.A <<
'\n');
638 G4double EThreshold, pLongThreshold, pTransThreshold;
643 pTransThreshold = 1.;
647 pLongThreshold = 0.1;
648 pTransThreshold = 0.1;
650 if(std::abs(theBalance.energy)>EThreshold) {
651 INCL_WARN(
"Violation of energy conservation > " << EThreshold <<
" MeV. EBalance = " << theBalance.energy <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber <<
'\n');
653 if(std::abs(pLongBalance)>pLongThreshold) {
654 INCL_WARN(
"Violation of longitudinal momentum conservation > " << pLongThreshold <<
" MeV/c. pLongBalance = " << pLongBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber <<
'\n');
656 if(std::abs(pTransBalance)>pTransThreshold) {
657 INCL_WARN(
"Violation of transverse momentum conservation > " << pTransThreshold <<
" MeV/c. pTransBalance = " << pTransBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber <<
'\n');
661 theEventInfo.
EBalance = theBalance.energy;
667 G4bool INCL::continueCascade() {
672 <<
"), stopping cascade" <<
'\n');
678 INCL_DEBUG(
"No participants in the nucleus and no incoming particles left, stopping cascade" <<
'\n');
682 if(nucleus->
getA() <= minRemnantSize) {
684 <<
") smaller than or equal to minimum (" << minRemnantSize
685 <<
"), stopping cascade" <<
'\n');
691 INCL_DEBUG(
"Trying to make a compound nucleus, stopping cascade" <<
'\n');
726 G4int INCL::makeProjectileRemnant() {
735 G4int nUnmergedSpectators = 0;
738 if(dynSpectators.empty() && geomSpectators.empty()) {
740 }
else if(dynSpectators.size()==1 && geomSpectators.empty()) {
751 nUnmergedSpectators = rejected.size();
759 return nUnmergedSpectators;
762 void INCL::initMaxInteractionDistance(ParticleSpecies
const &projectileSpecies,
const G4double kineticEnergy) {
763 if(projectileSpecies.theType !=
Composite) {
764 maxInteractionDistance = 0.;
772 maxInteractionDistance = r0 + theNNDistance;
773 INCL_DEBUG(
"Initialised interaction distance: r0 = " << r0 <<
'\n'
774 <<
" theNNDistance = " << theNNDistance <<
'\n'
775 <<
" maxInteractionDistance = " << maxInteractionDistance <<
'\n');
778 void INCL::initUniverseRadius(ParticleSpecies
const &
p,
const G4double kineticEnergy,
const G4int A,
const G4int Z) {
781 IsotopicDistribution
const &anIsotopicDistribution =
783 IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
784 for(
IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
788 rMax =
std::max(maximumRadius, rMax);
793 rMax =
std::min(pMaximumRadius, nMaximumRadius);
798 }
else if(p.theType==
PiPlus
804 INCL_DEBUG(
"Initialised universe radius: " << maxUniverseRadius <<
'\n');
807 void INCL::updateGlobalInfo() {
Short_t Ap
Projectile mass number given as input.
Short_t Zp
Charge number of the projectile nucleus.
G4int getA() const
Returns the baryon number.
Float_t effectiveImpactParameter
Effective (Coulomb-distorted) impact parameter [fm].
CascadeActionType getCascadeActionType() const
Get the cascade-action type.
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const
Compute charge, mass, energy and momentum balance.
void initializeParticles()
Float_t nucleonAbsorptionCrossSection
Nucleon absorption cross section.
Bool_t nucleonAbsorption
True if the event is a nucleon absorption.
G4bool containsDeltas()
Returns true if the nucleus contains any deltas.
IsotopeVector::iterator IsotopeIter
void setMass(G4double mass)
static void setCutNN(const G4double c)
void deleteCrossSections()
G4bool prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z)
Float_t pLongBalance
Longitudinal momentum-conservation balance [MeV/c].
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
G4int getTargetZ() const
Get the target charge number.
Int_t nForcedCompoundNucleus
Number of forced compound-nucleus events.
const ThreeVector & getIncomingMomentum() const
Get the incoming momentum vector.
std::string cascadeModel
Name of the cascade model.
ParticleList const & getParticles() const
G4bool decayOutgoingClusters()
Force the decay of unstable outgoing clusters.
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
Abstract interface to the nuclear potential.
virtual G4INCL::IAvatar * propagate(FinalState const *const fs)=0
Float_t errorReactionCrossSection
Error on the calculated reaction cross section.
void applyFinalState(FinalState *)
void setZ(const G4int Z)
Set the charge number of the cluster.
void initialize(Config const *const)
Initialize generator according to a Config object.
const ThreeVector & getIncomingAngularMomentum() const
Get the incoming angular-momentum vector.
G4double interactionDistanceNN(const ParticleSpecies &aSpecies, const G4double kineticEnergy)
Compute the "interaction distance".
Float_t forcedCNCrossSection
Calculated forced-compound-nucleus cross section.
Float_t pionAbsorptionCrossSection
Pion absorption cross section.
std::vector< Int_t > finalRandomSeeds
Final seeds for the pseudo-random-number generator.
Bool_t forcedDeltasOutside
Event involved forced delta decays outside the nucleus.
G4double getEnergy() const
void deletePhaseSpaceGenerator()
Bool_t pionAbsorption
True if the event is a pion absorption.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4bool isNaturalTarget() const
Natural targets.
Bool_t clusterDecay
Event involved cluster decay.
G4bool hasRemnant() const
Does the nucleus give a cascade remnant?
void deleteIncoming()
Clear the incoming list and delete the particles.
ParticleList const & getIncomingParticles() const
Float_t Ep
Projectile kinetic energy given as input.
Short_t At
Target mass number given as input.
Int_t nTransparents
Number of transparent shots.
void reset()
Reset the projectile remnant to the state at the beginning of the cascade.
std::vector< Int_t > initialRandomSeeds
Initial seeds for the pseudo-random-number generator.
Float_t stoppingTime
Cascade stopping time [fm/c].
Class containing default actions to be performed at intermediate cascade steps.
Float_t Ep
Projectile kinetic energy given as input.
Short_t At
Mass number of the target nucleus.
G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
void setEnergy(G4double energy)
static G4ThreadLocal Int_t eventNumber
Number of the event.
void clearCache()
Clear the INuclearPotential cache.
G4double getImpactParameter() const
void finalizeGlobalInfo(Random::SeedVector const &initialSeeds)
Short_t Zt
Charge number of the target nucleus.
Float_t impactParameter
Impact parameter [fm].
void useFusionKinematics()
Adjust the kinematics for complete-fusion events.
void deleteCoulomb()
Delete the Coulomb-distortion object.
Static class for selecting Coulomb distortion.
INCL(Config const *const config)
static std::string const getVersionString()
Get the INCL version string.
Simple container for output of calculation-wide results.
double A(double temperature)
Float_t pTransBalance
Transverse momentum-conservation balance [MeV/c].
void deleteBlockers()
Delete blockers.
Float_t EBalance
Energy-conservation balance [MeV].
G4bool decayOutgoingDeltas()
Force the decay of outgoing deltas.
ParticleList const & getOutgoingParticles() const
static void deleteBackupParticles()
Release the memory allocated for the backup particles.
G4int getCascading() const
virtual G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)=0
Bool_t deltasInside
Event involved deltas in the nucleus at the end of the cascade.
ParticleList extractDynamicalSpectators()
Returns a list of dynamical spectators.
Int_t nForcedTransparents
Number of forced transparents.
std::string deexcitationModel
Name of the de-excitation model.
void initialize(Config const *const theConfig)
G4double getDecayTimeThreshold() const
Get the hadronization time.
G4int getTargetA() const
Get the target mass number.
Intersection getEarlierTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the first intersection of a straight particle trajectory with a sphere.
const EventInfo & processEvent()
G4int getZ() const
Returns the charge number.
Alternative CascadeAction for dumping avatars.
G4double getExcitationEnergy() const
Get the excitation energy of the nucleus.
G4double computeExcitationEnergy() const
Compute the current excitation energy.
Float_t completeFusionCrossSection
Calculated complete-fusion cross section (nParticles==0)
Int_t nShots
Number of shots.
Int_t nUnmergedSpectators
Number of dynamical spectators that were merged back into the projectile remnant. ...
G4bool decayMe()
Force the phase-space decay of the Nucleus.
void initialize(Config const *const theConfig)
Initialize the clustering model based on the Config object.
std::vector< Isotope > IsotopeVector
G4double getHadronizationTime() const
Get the hadronization time.
Functions that encapsulate a mass table.
Float_t reactionCrossSection
Calculated reaction cross section.
G4bool getTryCompoundNucleus()
Float_t geometricCrossSection
Geometric cross section.
G4bool initializeTarget(const G4int A, const G4int Z)
Short_t Zp
Projectile charge number given as input.
Adapter const & getAdapter()
void initVerbosityLevelFromEnvvar()
Bool_t forcedPionResonancesOutside
Event involved forced eta/omega decays outside the nucleus.
void addParticleEntryAvatar(IAvatar *a)
Add one ParticleEntry avatar.
Float_t errorCompleteFusionCrossSection
Error on the calculated complete-fusion cross section (nParticles==0)
void setA(const G4int A)
Set the mass number of the cluster.
ParticleList addAllDynamicalSpectators(ParticleList const &pL)
Add back all dynamical spectators to the projectile remnant.
G4bool decayInsideDeltas()
Force the decay of deltas inside the nucleus.
void finalizeProjectileRemnant(const G4double emissionTime)
Finalise the projectile remnant.
G4double getMaximumNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
Static class for cluster formation.
void deleteClusteringModel()
Delete the clustering model.
std::string getDeExcitationString() const
Get the de-excitation string.
ParticleSpecies getProjectileSpecies() const
Get the projectile species.
T max(const T t1, const T t2)
brief Return the largest of the two arguments
virtual void setNucleus(G4INCL::Nucleus *nucleus)=0
Int_t nPionAbsorptions
Number of nucleon absorptions (no outcoming pions)
G4double interactionDistancePiN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
LocalEnergyType getLocalEnergyPiType() const
Get the type of local energy for pi-N and decay avatars.
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
LocalEnergyType getLocalEnergyBBType() const
Get the type of local energy for N-N avatars.
void initialize(Config const *const theConfig)
void reset()
Reset the EventInfo members.
virtual G4double getStoppingTime()=0
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4bool isEventTransparent() const
Is the event transparent?
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
Solution solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
void fillEventInfo(EventInfo *eventInfo)
G4int drawRandomNaturalIsotope(const G4int Z)
ProjectileRemnant * getProjectileRemnant() const
Get the projectile remnant.
void initialize(Config const *const aConfig)
Initialise blockers according to a Config object.
Short_t Zt
Target charge number given as input.
Bool_t transparent
True if the event is transparent.
IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
void computeRecoilKinematics()
Compute the recoil momentum and spin of the nucleus.
virtual G4double getCurrentTime()=0
G4double getProjectileKineticEnergy() const
Get the projectile kinetic energy.
Int_t nNucleonAbsorptions
Number of nucleon absorptions (no outcoming particles)
Float_t energyViolationInteractionCrossSection
Cross section for attempted collisions/decays for which the energy-conservation algorithm failed to f...
void addToOutgoing(Particle *p)
add the particle to the outgoing particle list.
Bool_t forcedDeltasInside
Event involved forced delta decays inside the nucleus.
Short_t Ap
Mass number of the projectile nucleus.
Short_t nCascadeParticles
Number of cascade particles.
G4bool decayOutgoingPionResonances(G4double timeThreshold)
Force the decay of outgoing PionResonances (eta/omega).
void setExcitationEnergy(const G4double e)
Set the excitation energy of the cluster.
void initialize(Config const *const theConfig=0)
Initialize the particle table.
void setSpin(const ThreeVector &j)
Set the spin of the nucleus.
Float_t errorForcedCNCrossSection
Error on the calculated forced-compound-nucleus cross section.
G4double getCutNN() const
void distortOut(ParticleList const &pL, Nucleus const *const n)
Modify the momentum of an outgoing particle.
Simple class for computing intersections between a straight line and a sphere.
void initialize(Config const *const theConfig)
Initialize the Coulomb-distortion algorithm.
void clearIncoming()
Clear the incoming list.
Int_t nCompleteFusion
Number of complete-fusion events (nParticles==0)
Int_t projectileType
Projectile particle type.
virtual void setMomentum(const G4INCL::ThreeVector &momentum)