33 #define INCLXX_IN_GEANT4_MODE 1
88 :propagationModel(0), theA(208), theZ(82),
89 targetInitSuccess(false),
90 maxImpactParameter(0.),
91 maxUniverseRadius(0.),
92 maxInteractionDistance(0.),
93 fixedImpactParameter(0.),
96 forceTransparent(false),
100 #ifdef INCLXX_IN_GEANT4_MODE
102 #else // INCLXX_IN_GEANT4_MODE
103 G4INCL::Logger::setLoggerSlave(
new G4INCL::LoggerSlave(theConfig->
getLogFileName()));
104 G4INCL::Logger::setVerbosityLevel(theConfig->
getVerbosity());
105 #endif // INCLXX_IN_GEANT4_MODE
110 #ifdef INCLXX_IN_GEANT4_MODE
112 #else // INCLXX_IN_GEANT4_MODE
114 #endif // INCLXX_IN_GEANT4_MODE
166 cascadeAction->beforeRunAction(theConfig);
171 theGlobalInfo.rootSelection = theConfig->getROOTSelectionString();
174 #ifndef INCLXX_IN_GEANT4_MODE
179 theGlobalInfo.
Ap = theSpecies.
theA;
180 theGlobalInfo.
Zp = theSpecies.
theZ;
183 INCL_INFO(theConfig->echo() << std::endl);
191 #ifndef INCLXX_IN_GEANT4_MODE
192 G4INCL::NuclearMassTable::deleteTable();
199 #ifndef INCLXX_IN_GEANT4_MODE
200 G4INCL::Logger::deleteLoggerSlave();
204 cascadeAction->afterRunAction();
205 delete cascadeAction;
206 delete propagationModel;
211 if(A < 0 || A > 300 || Z < 1 || Z > 200) {
212 INCL_ERROR(
"Unsupported target: A = " << A <<
" Z = " << Z << std::endl
213 <<
"Target configuration rejected." << std::endl);
217 (projectileSpecies.
theZ==projectileSpecies.
theA || projectileSpecies.
theZ==0)) {
218 INCL_ERROR(
"Unsupported projectile: A = " << projectileSpecies.
theA <<
" Z = " << projectileSpecies.
theZ << std::endl
219 <<
"Projectile configuration rejected." << std::endl);
224 forceTransparent =
false;
227 initUniverseRadius(projectileSpecies, kineticEnergy, A, Z);
239 INCL_DEBUG(
"Maximum impact parameter initialised: " << maxImpactParameter << std::endl);
242 initMaxInteractionDistance(projectileSpecies, kineticEnergy);
249 if(projectileSpecies.
theA > 0)
252 minRemnantSize =
std::min(theA-1, 4);
260 nucleus =
new Nucleus(A, Z, theConfig, maxUniverseRadius);
275 targetInitSuccess =
prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ);
277 if(!targetInitSuccess) {
278 INCL_WARN(
"Target initialisation failed for A=" << targetA <<
", Z=" << targetZ << std::endl);
283 cascadeAction->beforeCascadeAction(propagationModel);
285 const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
289 cascadeAction->afterCascadeAction(nucleus);
297 theEventInfo.
reset();
303 theEventInfo.
Ap = projectileSpecies.
theA;
304 theEventInfo.
Zp = projectileSpecies.
theZ;
305 theEventInfo.
Ep = kineticEnergy;
306 theEventInfo.
At = nucleus->
getA();
307 theEventInfo.
Zt = nucleus->
getZ();
310 if(maxImpactParameter<=0.) {
320 if(fixedImpactParameter<0.) {
321 impactParameter = maxImpactParameter * std::sqrt(
Random::shoot0());
324 impactParameter = fixedImpactParameter;
327 INCL_DEBUG(
"Selected impact parameter: " << impactParameter << std::endl);
332 const G4double effectiveImpactParameter = propagationModel->
shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
333 if(effectiveImpactParameter < 0.) {
347 void INCL::cascade() {
350 cascadeAction->beforePropagationAction(propagationModel);
357 cascadeAction->afterPropagationAction(propagationModel, avatar);
359 if(avatar == 0)
break;
362 cascadeAction->beforeAvatarAction(avatar, nucleus);
374 cascadeAction->afterAvatarAction(avatar, nucleus, finalState);
382 }
while(continueCascade());
386 void INCL::postCascade() {
392 INCL_DEBUG(
"Trying compound nucleus" << std::endl);
393 makeCompoundNucleus();
396 #ifndef INCLXX_IN_GEANT4_MODE
397 if(!theEventInfo.
transparent) globalConservationChecks(
true);
406 if(projectileRemnant) {
434 INCL_DEBUG(
"Cascade resulted in complete fusion, using realistic fusion kinematics" << std::endl);
440 INCL_WARN(
"Complete-fusion kinematics yields negative excitation energy, returning a transparent!" << std::endl);
457 #ifndef INCLXX_IN_GEANT4_MODE
459 globalConservationChecks(
false);
464 if(nucleus->
hasRemnant()) rescaleOutgoingForRecoil();
471 #ifndef INCLXX_IN_GEANT4_MODE
473 globalConservationChecks(
true);
482 void INCL::makeCompoundNucleus() {
489 forceTransparent =
true;
497 nucleus->
setA(theEventInfo.
At);
498 nucleus->
setZ(theEventInfo.
Zt);
506 G4int theCNA=theEventInfo.
At, theCNZ=theEventInfo.
Zt;
511 ParticleList initialProjectileComponents = theProjectileRemnant->getParticles();
512 std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
517 G4bool atLeastOneNucleonEntering =
false;
518 for(std::vector<Particle*>::const_iterator
p=shuffledComponents.begin(), e=shuffledComponents.end();
p!=e; ++
p) {
522 (*p)->getPropagationVelocity(),
523 maxInteractionDistance));
524 if(!intersectionInteractionDistance.exists)
528 atLeastOneNucleonEntering =
true;
529 ParticleEntryAvatar *theAvatar =
new ParticleEntryAvatar(0.0, nucleus, *
p);
531 FinalState *fs = theAvatar->getFinalState();
541 theCNZ += (*p)->getZ();
551 if(!success || !atLeastOneNucleonEntering) {
552 INCL_DEBUG(
"No nucleon entering in forced CN, forcing a transparent" << std::endl);
553 forceTransparent =
true;
562 theCNEnergy -= theProjectileRemnant->getEnergy();
563 theCNMomentum -= theProjectileRemnant->getMomentum();
571 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i) {
572 theCNSpin -= (*i)->getAngularMomentum();
577 const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
578 if(theCNInvariantMassSquared<0.) {
580 forceTransparent =
true;
583 const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
584 if(theCNExcitationEnergy<0.) {
586 INCL_DEBUG(
"CN excitation energy is negative, forcing a transparent" << std::endl
587 <<
" theCNA = " << theCNA << std::endl
588 <<
" theCNZ = " << theCNZ << std::endl
589 <<
" theCNEnergy = " << theCNEnergy << std::endl
590 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" << std::endl
591 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy << std::endl
592 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" << std::endl
594 forceTransparent =
true;
598 INCL_DEBUG(
"CN excitation energy is positive, forcing a CN" << std::endl
599 <<
" theCNA = " << theCNA << std::endl
600 <<
" theCNZ = " << theCNZ << std::endl
601 <<
" theCNEnergy = " << theCNEnergy << std::endl
602 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" << std::endl
603 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy << std::endl
604 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" << std::endl
606 nucleus->
setA(theCNA);
607 nucleus->
setZ(theCNZ);
611 nucleus->
setMass(theCNMass+theCNExcitationEnergy);
625 void INCL::rescaleOutgoingForRecoil() {
626 RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
629 const RootFinder::Solution theSolution =
RootFinder::solve(&theRecoilFunctor, 1.0);
630 if(theSolution.success) {
631 theRecoilFunctor(theSolution.x);
633 INCL_WARN(
"Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." << std::endl);
638 #ifndef INCLXX_IN_GEANT4_MODE
639 void INCL::globalConservationChecks(
G4bool afterRecoil) {
644 const G4double pTransBalance = theBalance.momentum.perp();
645 if(theBalance.Z != 0) {
646 INCL_ERROR(
"Violation of charge conservation! ZBalance = " << theBalance.Z << std::endl);
648 if(theBalance.A != 0) {
649 INCL_ERROR(
"Violation of baryon-number conservation! ABalance = " << theBalance.A << std::endl);
651 G4double EThreshold, pLongThreshold, pTransThreshold;
656 pTransThreshold = 1.;
660 pLongThreshold = 0.1;
661 pTransThreshold = 0.1;
663 if(std::abs(theBalance.energy)>EThreshold) {
664 INCL_WARN(
"Violation of energy conservation > " << EThreshold <<
" MeV. EBalance = " << theBalance.energy <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
666 if(std::abs(pLongBalance)>pLongThreshold) {
667 INCL_WARN(
"Violation of longitudinal momentum conservation > " << pLongThreshold <<
" MeV/c. pLongBalance = " << pLongBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
669 if(std::abs(pTransBalance)>pTransThreshold) {
670 INCL_WARN(
"Violation of transverse momentum conservation > " << pTransThreshold <<
" MeV/c. pTransBalance = " << pTransBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
674 theEventInfo.
EBalance = theBalance.energy;
680 G4bool INCL::continueCascade() {
685 <<
"), stopping cascade" << std::endl);
691 INCL_DEBUG(
"No participants in the nucleus and no incoming particles left, stopping cascade" << std::endl);
695 if(nucleus->
getA() <= minRemnantSize) {
697 <<
") smaller than or equal to minimum (" << minRemnantSize
698 <<
"), stopping cascade" << std::endl);
704 INCL_DEBUG(
"Trying to make a compound nucleus, stopping cascade" << std::endl);
734 G4int INCL::makeProjectileRemnant() {
743 G4int nUnmergedSpectators = 0;
746 if(dynSpectators.empty() && geomSpectators.empty()) {
748 }
else if(dynSpectators.size()==1 && geomSpectators.empty()) {
757 ParticleList rejected = theProjectileRemnant->addAllDynamicalSpectators(dynSpectators);
759 nUnmergedSpectators = rejected.size();
767 return nUnmergedSpectators;
770 void INCL::initMaxInteractionDistance(ParticleSpecies
const &projectileSpecies,
const G4double kineticEnergy) {
771 if(projectileSpecies.theType !=
Composite) {
772 maxInteractionDistance = 0.;
780 maxInteractionDistance = r0 + theNNDistance;
781 INCL_DEBUG(
"Initialised interaction distance: r0 = " << r0 << std::endl
782 <<
" theNNDistance = " << theNNDistance << std::endl
783 <<
" maxInteractionDistance = " << maxInteractionDistance << std::endl);
786 void INCL::initUniverseRadius(ParticleSpecies
const &
p,
const G4double kineticEnergy,
const G4int A,
const G4int Z) {
789 IsotopicDistribution
const &anIsotopicDistribution =
791 IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
792 for(
IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
796 rMax =
std::max(maximumRadius, rMax);
801 rMax =
std::min(pMaximumRadius, nMaximumRadius);
806 }
else if(p.theType==
PiPlus
812 INCL_DEBUG(
"Initialised universe radius: " << maxUniverseRadius << std::endl);
815 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.
G4int shuffleComponentsHelper(G4int range)
Helper function for ProjectileRemnant::shuffleStoredComponents.
Float_t effectiveImpactParameter
Effective (Coulomb-distorted) impact parameter [fm].
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()
static void distortOut(ParticleList const &pL, Nucleus const *const n)
Modify the momentum of an outgoing particle.
Class for non-relativistic Coulomb distortion.
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.
virtual G4INCL::IAvatar * propagate()=0
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
Abstract interface to the nuclear potential.
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.
const ThreeVector & getIncomingAngularMomentum() const
Get the incoming angular-momentum vector.
static void setCoulomb(ICoulomb *const coulomb)
Set the Coulomb-distortion algorithm.
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.
Bool_t forcedDeltasOutside
Event involved forced delta decays outside the nucleus.
G4double getEnergy() const
Bool_t pionAbsorption
True if the event is a pion absorption.
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.
Abstract interface for the cross-section classes.
Short_t At
Target mass number given as input.
static void deleteBlockers()
Int_t nTransparents
Number of transparent shots.
void reset()
Reset the projectile remnant to the state at the beginning of the cascade.
void finalizeGlobalInfo()
Float_t stoppingTime
Cascade stopping time [fm/c].
static void setBlocker(IPauli *const)
Float_t Ep
Projectile kinetic energy given as input.
void setCrossSections(ICrossSections *c)
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.
G4int getVerbosity() const
Get the verbosity.
G4double getImpactParameter() const
Short_t Zt
Charge number of the target nucleus.
Float_t impactParameter
Impact parameter [fm].
void useFusionKinematics()
Adjust the kinematics for complete-fusion events.
Cross sections used in INCL4.6.
G4bool getCDPP() const
Do we want CDPP?
Static class for selecting Coulomb distortion.
UnorderedVector< Particle * > ParticleList
INCL(Config const *const config)
static std::string const getVersionString()
Get the INCL version string.
static G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
static void deleteCoulomb()
Delete the Coulomb-distortion object.
Simple container for output of calculation-wide results.
Float_t pTransBalance
Transverse momentum-conservation balance [MeV/c].
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
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.
PauliType getPauliType() const
Get the Pauli-blocking algorithm.
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.
Placeholder class for no Coulomb distortion.
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.
std::vector< Isotope > IsotopeVector
Functions that encapsulate a mass table.
Float_t reactionCrossSection
Calculated reaction cross section.
void setGenerator(G4INCL::IRandomGenerator *aGenerator)
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.
void initVerbosityLevelFromEnvvar()
void addParticleEntryAvatar(IAvatar *a)
Add one ParticleEntry avatar.
Float_t errorCompleteFusionCrossSection
Error on the calculated complete-fusion cross section (nParticles==0)
Random::SeedVector getRandomSeeds() const
Get the seeds for the random-number generator.
void setA(const G4int A)
Set the mass number of the cluster.
ClusterAlgorithmType getClusterAlgorithm() const
Get the clustering algorithm.
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)
std::string const & getLogFileName() const
Get the log file name.
Static class for cluster formation.
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.
virtual G4double shoot(ParticleSpecies const projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)=0
LocalEnergyType getLocalEnergyBBType() const
Get the type of local energy for N-N avatars.
void reset()
Reset the EventInfo members.
CoulombType getCoulombType() const
Get the Coulomb-distortion algorithm.
static void setClusteringModel(IClusteringModel *const model)
Set the clustering model.
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?
G4INCL::FinalState * getFinalState()
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.
Abstract interface for Coulomb distortion.
static void deleteClusteringModel()
Short_t Zt
Target charge number given as input.
static void setCDPP(IPauli *const)
Bool_t transparent
True if the event is transparent.
IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
Cluster coalescence algorithm used in the IAEA intercomparison.
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.
Cross sections used in INCL4.6.
Short_t Ap
Mass number of the projectile nucleus.
Short_t nCascadeParticles
Number of cascade particles.
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
ParticleList::const_iterator ParticleIter
Simple class for computing intersections between a straight line and a sphere.
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)