35#define INCLXX_IN_GEANT4_MODE 1
83 :propagationModel(0), theA(208), theZ(82),
84 targetInitSuccess(false),
85 maxImpactParameter(0.),
86 maxUniverseRadius(0.),
87 maxInteractionDistance(0.),
88 fixedImpactParameter(0.),
100#ifdef INCLXX_IN_GEANT4_MODE
156#ifndef INCLXX_IN_GEANT4_MODE
161 theGlobalInfo.
Ap = theSpecies.
theA;
162 theGlobalInfo.
Zp = theSpecies.
theZ;
165 INFO(theConfig->
echo() << std::endl);
179 delete propagationAction;
181 delete propagationModel;
186 if(A < 0 || A > 300 || Z < 1 || Z > 200) {
187 ERROR(
"Unsupported target: A = " << A <<
" Z = " << Z << std::endl);
188 ERROR(
"Target configuration rejected." << std::endl);
193 initUniverseRadius(projectileSpecies, kineticEnergy, A, Z);
205 initMaxInteractionDistance(projectileSpecies, kineticEnergy);
212 if(projectileSpecies.
theA > 0)
213 minRemnantSize = std::min(theA, 4);
215 minRemnantSize = std::min(theA-1, 4);
223 nucleus =
new Nucleus(A, Z, theConfig, maxUniverseRadius);
238 targetInitSuccess =
prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ);
240 if(!targetInitSuccess) {
241 WARN(
"Target initialisation failed for A=" << targetA <<
", Z=" << targetZ << std::endl);
246 const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
256 theEventInfo.
reset();
265 theEventInfo.
Ap = projectileSpecies.
theA;
266 theEventInfo.
Zp = projectileSpecies.
theZ;
267 theEventInfo.
Ep = kineticEnergy;
268 theEventInfo.
At = nucleus->
getA();
269 theEventInfo.
Zt = nucleus->
getZ();
272 if(maxImpactParameter<=0.) {
285 if(fixedImpactParameter<0.) {
286 impactParameter = maxImpactParameter * std::sqrt(
Random::shoot0());
289 impactParameter = fixedImpactParameter;
296 const G4double effectiveImpactParameter = propagationModel->
shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
297 if(effectiveImpactParameter < 0.) {
314 void INCL::cascade() {
326 if(avatar == 0)
break;
349 }
while(continueCascade());
353 void INCL::postCascade() {
359 DEBUG(
"Trying compound nucleus" << std::endl);
360 makeCompoundNucleus();
362#ifndef INCLXX_IN_GEANT4_MODE
363 if(!theEventInfo.
transparent) globalConservationChecks(
true);
376 if(projectileRemnant) {
406 DEBUG(
"Cascade resulted in complete fusion, using realistic fusion kinematics" << std::endl);
413 WARN(
"Complete-fusion kinematics yields negative excitation energy, returning a transparent!" << std::endl);
430#ifndef INCLXX_IN_GEANT4_MODE
432 globalConservationChecks(
false);
437 if(nucleus->
hasRemnant()) rescaleOutgoingForRecoil();
444#ifndef INCLXX_IN_GEANT4_MODE
446 globalConservationChecks(
true);
458 void INCL::makeCompoundNucleus() {
463 nucleus->
setA(theEventInfo.
At);
464 nucleus->
setZ(theEventInfo.
Zt);
472 G4int theCNA=theEventInfo.
At, theCNZ=theEventInfo.
Zt;
477 ParticleList initialProjectileComponents = theProjectileRemnant->getParticles();
478 std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
483 G4bool atLeastOneNucleonEntering =
false;
484 for(std::vector<Particle*>::const_iterator p=shuffledComponents.begin(); p!=shuffledComponents.end(); ++p) {
488 (*p)->getPropagationVelocity(),
490 if(!intersectionUniverse.exists)
496 (*p)->getPropagationVelocity(),
497 maxInteractionDistance));
498 if(intersectionInteraction.exists)
499 atLeastOneNucleonEntering =
true;
502 ParticleEntryAvatar theAvatar(0.0, nucleus, *p);
503 FinalState *fs = theAvatar.getFinalState();
512 theCNZ += (*p)->getZ();
523 if(!success || !atLeastOneNucleonEntering) {
524 DEBUG(
"No nucleon entering in forced CN, or some nucleons entering below zero, forcing a transparent" << std::endl);
537 theCNEnergy -= theProjectileRemnant->getEnergy();
538 theCNMomentum -= theProjectileRemnant->getMomentum();
546 for(
ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i) {
547 theCNSpin -= (*i)->getAngularMomentum();
552 const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
553 if(theCNInvariantMassSquared<0.) {
560 const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
561 if(theCNExcitationEnergy<0.) {
569 nucleus->
setA(theCNA);
570 nucleus->
setZ(theCNZ);
574 nucleus->
setMass(theCNMass+theCNExcitationEnergy);
589 void INCL::rescaleOutgoingForRecoil() {
590 RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
596 theRecoilFunctor(theSolution.first);
598 WARN(
"Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." << std::endl);
603#ifndef INCLXX_IN_GEANT4_MODE
604 void INCL::globalConservationChecks(
G4bool afterRecoil) {
609 const G4double pTransBalance = theBalance.momentum.perp();
610 if(theBalance.Z != 0) {
611 ERROR(
"Violation of charge conservation! ZBalance = " << theBalance.Z << std::endl);
613 if(theBalance.A != 0) {
614 ERROR(
"Violation of baryon-number conservation! ABalance = " << theBalance.A << std::endl);
616 G4double EThreshold, pLongThreshold, pTransThreshold;
621 pTransThreshold = 1.;
625 pLongThreshold = 0.1;
626 pTransThreshold = 0.1;
628 if(std::abs(theBalance.energy)>EThreshold) {
629 WARN(
"Violation of energy conservation > " << EThreshold <<
" MeV. EBalance = " << theBalance.energy <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
631 if(std::abs(pLongBalance)>pLongThreshold) {
632 WARN(
"Violation of longitudinal momentum conservation > " << pLongThreshold <<
" MeV/c. pLongBalance = " << pLongBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
634 if(std::abs(pTransBalance)>pTransThreshold) {
635 WARN(
"Violation of transverse momentum conservation > " << pTransThreshold <<
" MeV/c. pTransBalance = " << pTransBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.
eventNumber << std::endl);
639 theEventInfo.
EBalance = theBalance.energy;
645 G4bool INCL::continueCascade() {
650 <<
"), stopping cascade" << std::endl);
656 DEBUG(
"No participants in the nucleus and no incoming particles left, stopping cascade" << std::endl);
660 if(nucleus->
getA() <= minRemnantSize) {
661 DEBUG(
"Remnant size (" << nucleus->
getA()
662 <<
") smaller than or equal to minimum (" << minRemnantSize
663 <<
"), stopping cascade" << std::endl);
669 DEBUG(
"Trying to make a compound nucleus, stopping cascade" << std::endl);
673 DEBUG(
"Forcing a transparent, stopping cascade" << std::endl);
693 G4int INCL::makeProjectileRemnant() {
694 G4int nUnmergedSpectators = 0;
705 if(dynSpectators.empty() && geomSpectators.empty()) {
708 }
else if(geomSpectators.size()+dynSpectators.size()==1) {
709 if(dynSpectators.empty()) {
712#if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
713 Particle *theSpectator = geomSpectators.front();
728 ParticleList rejected = theProjectileRemnant->addMostDynamicalSpectators(dynSpectators);
730 nUnmergedSpectators = rejected.size();
738 return nUnmergedSpectators;
741 void INCL::initMaxInteractionDistance(ParticleSpecies
const &projectileSpecies,
const G4double kineticEnergy) {
742 if(projectileSpecies.theType !=
Composite) {
743 maxInteractionDistance = 0.;
747 const G4double projectileKineticEnergyPerNucleon = kineticEnergy/projectileSpecies.theA;
753 void INCL::initUniverseRadius(ParticleSpecies
const &p,
const G4double kineticEnergy,
const G4int A,
const G4int Z) {
756 IsotopicDistribution
const &anIsotopicDistribution =
758 IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
759 for(
IsotopeIter i=theIsotopes.begin(); i!=theIsotopes.end(); ++i) {
762 FATAL(
"NULL density in initUniverseRadius. "
763 <<
"Projectile type=" << p.theType
766 <<
", kinE=" << kineticEnergy
767 <<
", target A=" << A
772 rMax = std::max(theDensity->getMaximumRadius(), rMax);
777 FATAL(
"NULL density in initUniverseRadius. "
778 <<
"Projectile type=" << p.theType
781 <<
", kinE=" << kineticEnergy
782 <<
", target A=" << A
787 rMax = theDensity->getMaximumRadius();
790 maxUniverseRadius = rMax;
794 maxUniverseRadius = rMax
796 + interactionDistanceNN;
798 maxUniverseRadius = rMax;
799 }
else if(p.theType==
PiPlus
804 maxUniverseRadius = rMax
806 + interactionDistancePiN;
808 maxUniverseRadius = rMax;
Static class for cluster formation.
Static class for selecting Coulomb distortion.
Class for non-relativistic Coulomb distortion.
Placeholder class for no Coulomb distortion.
Simple container for output of calculation-wide results.
Abstract interface for Coulomb distortion.
Simple class for computing intersections between a straight line and a sphere.
void beforeAvatarAction(IAvatar *a, Nucleus *n)
void afterAvatarAction(IAvatar *a, Nucleus *n, FinalState *fs)
G4int getCascading() const
ParticleList const & getParticles() const
void setExcitationEnergy(const G4double e)
Set the excitation energy of the cluster.
void setSpin(const ThreeVector &j)
Set the spin of the nucleus.
void setA(const G4int A)
Set the mass number of the cluster.
void setZ(const G4int Z)
Set the charge number of the cluster.
Cluster coalescence algorithm used in the IAEA intercomparison.
static void setClusteringModel(IClusteringModel *const model)
Set the clustering model.
static void deleteClusteringModel()
PauliType getPauliType() const
Get the Pauli-blocking algorithm.
static std::string const getVersionID()
Get the INCL version ID.
G4double getImpactParameter() const
G4int getTargetA() const
Get the target mass number.
G4int getVerbosity() const
Get the verbosity.
std::string const & getLogFileName() const
Get the log file name.
ParticleSpecies getProjectileSpecies() const
Get the projectile species.
ClusterAlgorithmType getClusterAlgorithm() const
Get the clustering algorithm.
std::string const echo() const
Echo the input options.
LocalEnergyType getLocalEnergyPiType() const
Get the type of local energy for pi-N and decay avatars.
G4bool isNaturalTarget() const
Natural targets.
G4bool getCDPP() const
Do we want CDPP?
LocalEnergyType getLocalEnergyBBType() const
Get the type of local energy for N-N avatars.
G4int getTargetZ() const
Get the target charge number.
CoulombType getCoulombType() const
Get the Coulomb-distortion algorithm.
G4float getProjectileKineticEnergy() const
Get the projectile kinetic energy.
SeedVector const getRandomSeeds() const
Get the seeds for the random-number generator.
static G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
static void distortOut(ParticleList const &pL, Nucleus const *const n)
Modify the momentum of an outgoing particle.
static void deleteCoulomb()
Delete the Coulomb-distortion object.
static void setCoulomb(ICoulomb *const coulomb)
Set the Coulomb-distortion algorithm.
static G4double interactionDistancePiN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
static G4double interactionDistancePiN1GeV()
The interaction distance for pions at 1 GeV.
static G4double interactionDistanceNN1GeV()
The interaction distance for nucleons at 1 GeV.
static G4double interactionDistanceNN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
G4INCL::FinalState * getFinalState()
G4bool initializeTarget(const G4int A, const G4int Z)
INCL(Config const *const config)
const EventInfo & processEvent()
void finalizeGlobalInfo()
G4bool prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z)
virtual G4double getCurrentTime()=0
virtual G4double getStoppingTime()=0
virtual G4INCL::IAvatar * propagate()=0
virtual void setNucleus(G4INCL::Nucleus *nucleus)=0
virtual G4double shoot(ParticleSpecies const projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)=0
static Intersection getEarlierTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the first intersection of a straight particle trajectory with a sphere.
static void setLoggerSlave(LoggerSlave *const slave)
static void deleteLoggerSlave()
static void setVerbosityLevel(G4int)
static NuclearDensity * createDensity(const G4int A, const G4int Z)
G4double getNuclearRadius()
const ThreeVector & getIncomingAngularMomentum() const
Get the incoming angular-momentum vector.
ProjectileRemnant * getProjectileRemnant() const
Get the projectile remnant.
G4bool isForcedTransparent()
Returns true if a transparent event should be forced.
void fillEventInfo(EventInfo *eventInfo)
G4bool decayMe()
Force the phase-space decay of the Nucleus.
G4bool decayInsideDeltas()
Force the decay of deltas inside the nucleus.
void computeRecoilKinematics()
Compute the recoil momentum and spin of the nucleus.
void finalizeProjectileRemnant(const G4double emissionTime)
Finalise the projectile remnant.
G4bool containsDeltas()
Returns true if the nucleus contains any deltas.
G4bool getTryCompoundNucleus()
G4bool isEventTransparent() const
Is the event transparent?
void applyFinalState(FinalState *)
void moveProjectileRemnantComponentsToOutgoing()
Move the components of the projectile remnant to the outgoing list.
void deleteProjectileRemnant()
Delete the projectile remnant.
void useFusionKinematics()
Adjust the kinematics for complete-fusion events.
const ThreeVector & getIncomingMomentum() const
Get the incoming momentum vector.
G4bool decayOutgoingClusters()
Force the decay of unstable outgoing clusters.
G4double getExcitationEnergy() const
Get the excitation energy of the nucleus.
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const
Compute charge, mass, energy and momentum balance.
void initializeParticles()
G4bool hasRemnant() const
Does the nucleus give a cascade remnant?
G4double computeExcitationEnergy() const
Compute the current excitation energy.
G4bool decayOutgoingDeltas()
Force the decay of outgoing deltas.
static NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
static IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
static void initialize(Config const *const theConfig=0)
Initialize the particle table.
static G4int drawRandomNaturalIsotope(const G4int Z)
G4double getEnergy() const
void setMass(G4double mass)
G4int getZ() const
Returns the charge number.
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
void setEnergy(G4double energy)
G4int getA() const
Returns the baryon number.
static void setBlocker(IPauli const *const)
static void setCDPP(IPauli const *const)
static void deleteBlockers()
void reset()
Reset the projectile remnant to the state at the beginning of the cascade.
void beforePropagationAction(IPropagationModel *pm)
void afterPropagationAction(IPropagationModel *pm, IAvatar *avatar)
static void setGenerator(G4INCL::IRandomGenerator *aGenerator)
static void deleteGenerator()
static std::pair< G4double, G4double > const & getSolution()
Get the solution of the last call to solve().
static G4bool solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
ParticleList const & getIncomingParticles() const
void deleteIncoming()
Clear the incoming list and delete the particles.
ParticleList const & getOutgoingParticles() const
void addToOutgoing(Particle *p)
add the particle to the outgoing particle list.
void clearIncoming()
Clear the incoming list.
ParticleList extractDynamicalSpectators()
Returns a list of dynamical spectators.
IsotopeVector::iterator IsotopeIter
@ IntercomparisonClusterAlgorithm
std::list< G4INCL::Particle * > ParticleList
G4int shuffleComponentsHelper(G4int range)
Helper function for ProjectileRemnant::shuffleStoredComponents.
std::list< G4INCL::Particle * >::const_iterator ParticleIter
std::vector< Isotope > IsotopeVector
Bool_t pionAbsorption
True if the event is absorption.
void reset()
Reset the EventInfo members.
Bool_t forcedDeltasOutside
Event involved forced delta decays outside the nucleus.
Short_t At
Mass number of the target nucleus.
Short_t Zp
Charge number of the projectile nucleus.
Float_t pTransBalance
Transverse momentum-conservation balance [MeV/c].
static Int_t eventNumber
Number of the event.
Float_t Ep
Projectile kinetic energy given as input.
Bool_t transparent
True if the event is transparent.
Bool_t deltasInside
Event involved deltas in the nucleus at the end of the cascade.
Float_t EBalance
Energy-conservation balance [MeV].
Bool_t nucleonAbsorption
True if the event is absorption.
Float_t effectiveImpactParameter
Number of reflection avatars.
Float_t stoppingTime
Cascade stopping time [fm/c].
Short_t Ap
Mass number of the projectile nucleus.
Bool_t clusterDecay
Event involved cluster decay.
Bool_t forcedDeltasInside
Event involved forced delta decays inside the nucleus.
Short_t Zt
Charge number of the target nucleus.
ParticleType projectileType
Protjectile particle type.
Float_t impactParameter
Impact parameter [fm].
Int_t nUnmergedSpectators
Number of dynamical spectators that were merged back into the projectile remnant.
Float_t pLongBalance
Longitudinal momentum-conservation balance [MeV/c].
Int_t nNucleonAbsorptions
Number of nucleon absorptions (no outcoming particles)
std::string deexcitationModel
Name of the de-excitation model.
Float_t pionAbsorptionCrossSection
Pion absorption cross section.
Float_t Ep
Projectile kinetic energy given as input.
Short_t At
Target mass number given as input.
Int_t nShots
Number of shots.
Float_t nucleonAbsorptionCrossSection
Nucleon absorption cross section.
Float_t errorReactionCrossSection
Error on the calculated reaction cross section.
Short_t Zt
Target charge number given as input.
Int_t nPionAbsorptions
Number of nucleon absorptions (no outcoming pions)
Short_t Ap
Projectile mass number given as input.
Int_t nTransparents
Number of transparent shots.
Int_t nForcedCompoundNucleus
Number of forced compound-nucleus events.
Short_t Zp
Projectile charge number given as input.
Int_t nForcedTransparents
Number of forced transparents.
std::string cascadeModel
Name of the cascade model.
Float_t reactionCrossSection
Calculated reaction cross section.
Float_t geometricCrossSection
Geometric cross section.