// // ******************************************************************** // * 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 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics // Davide Mancusi, CEA // Alain Boudard, CEA // Sylvie Leray, CEA // Joseph Cugnon, University of Liege // #define INCLXX_IN_GEANT4_MODE 1 #include "globals.hh" /* * G4INCLNucleus.hh * * \date Jun 5, 2009 * \author Pekka Kaitaniemi */ #ifndef G4INCLNUCLEUS_HH_ #define G4INCLNUCLEUS_HH_ #include #include #include "G4INCLParticle.hh" #include "G4INCLEventInfo.hh" #include "G4INCLCluster.hh" #include "G4INCLFinalState.hh" #include "G4INCLStore.hh" #include "G4INCLGlobals.hh" #include "G4INCLParticleTable.hh" #include "G4INCLConfig.hh" #include "G4INCLConfigEnums.hh" #include "G4INCLCluster.hh" #include "G4INCLProjectileRemnant.hh" namespace G4INCL { class Nucleus : public Cluster { public: Nucleus(G4int mass, G4int charge, Config const * const conf, const G4double universeRadius=-1.); virtual ~Nucleus(); /** * Call the Cluster method to generate the initial distribution of * particles. At the beginning all particles are assigned as spectators. */ void initializeParticles(); /// \brief Insert a new particle (e.g. a projectile) in the nucleus. void insertParticle(Particle *p) { theZ += p->getZ(); theA += p->getA(); theStore->particleHasEntered(p); if(p->isNucleon()) { theNpInitial += Math::heaviside(ParticleTable::getIsospin(p->getType())); theNnInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType())); } if(!p->isTargetSpectator()) theStore->getBook()->incrementCascading(); }; /** * Apply reaction final state information to the nucleus. */ void applyFinalState(FinalState *); G4int getInitialA() const { return theInitialA; }; G4int getInitialZ() const { return theInitialZ; }; /** * Get the list of particles that were created by the last applied final state */ ParticleList const &getCreatedParticles() const { return justCreated; } /** * Get the list of particles that were updated by the last applied final state */ ParticleList const &getUpdatedParticles() const { return toBeUpdated; } /// \brief Get the delta that could not decay Particle *getBlockedDelta() const { return blockedDelta; } /** * Propagate the particles one time step. * * @param step length of the time step */ void propagateParticles(G4double step); G4int getNumberOfEnteringProtons() const { return theNpInitial; }; G4int getNumberOfEnteringNeutrons() const { return theNnInitial; }; /** \brief Outgoing - incoming separation energies. * * Used by CDPP. */ G4double computeSeparationEnergyBalance() const { G4double S = 0.0; ParticleList outgoing = theStore->getOutgoingParticles(); for(ParticleIter i = outgoing.begin(); i != outgoing.end(); ++i) { const ParticleType t = (*i)->getType(); switch(t) { case Proton: case Neutron: case DeltaPlusPlus: case DeltaPlus: case DeltaZero: case DeltaMinus: S += thePotential->getSeparationEnergy(*i); break; case Composite: S += (*i)->getZ() * thePotential->getSeparationEnergy(Proton) + ((*i)->getA() - (*i)->getZ()) * thePotential->getSeparationEnergy(Neutron); break; case PiPlus: S += thePotential->getSeparationEnergy(Proton) - thePotential->getSeparationEnergy(Neutron); break; case PiMinus: S += thePotential->getSeparationEnergy(Neutron) - thePotential->getSeparationEnergy(Proton); break; default: break; } } S -= theNpInitial * thePotential->getSeparationEnergy(Proton); S -= theNnInitial * thePotential->getSeparationEnergy(Neutron); return S; } /** \brief Force the decay of outgoing deltas. * * \return true if any delta was forced to decay. */ G4bool decayOutgoingDeltas(); /** \brief Force the decay of deltas inside the nucleus. * * \return true if any delta was forced to decay. */ G4bool decayInsideDeltas(); /** \brief Force the decay of unstable outgoing clusters. * * \return true if any cluster was forced to decay. */ G4bool decayOutgoingClusters(); /** \brief Force the phase-space decay of the Nucleus. * * Only applied if Z==0 or Z==A. * * \return true if the nucleus was forced to decay. */ G4bool decayMe(); /// \brief Force emission of all pions inside the nucleus. void emitInsidePions(); /** \brief Compute the recoil momentum and spin of the nucleus. */ void computeRecoilKinematics(); /** \brief Compute the current center-of-mass position. * * \return the center-of-mass position vector [fm]. */ ThreeVector computeCenterOfMass() const; /** \brief Compute the current total energy. * * \return the total energy [MeV] */ G4double computeTotalEnergy() const; /** \brief Compute the current excitation energy. * * \return the excitation energy [MeV] */ G4double computeExcitationEnergy() const; /** \brief Set the incoming angular-momentum vector. */ void setIncomingAngularMomentum(const ThreeVector &j) { incomingAngularMomentum = j; } /** \brief Get the incoming angular-momentum vector. */ const ThreeVector &getIncomingAngularMomentum() const { return incomingAngularMomentum; } /** \brief Set the incoming momentum vector. */ void setIncomingMomentum(const ThreeVector &p) { incomingMomentum = p; } /** \brief Get the incoming momentum vector. */ const ThreeVector &getIncomingMomentum() const { return incomingMomentum; } /** \brief Set the initial energy. */ void setInitialEnergy(const G4double e) { initialEnergy = e; } /** \brief Get the initial energy. */ G4double getInitialEnergy() const { return initialEnergy; } /** \brief Get the excitation energy of the nucleus. * * Method computeRecoilKinematics() should be called first. */ G4double getExcitationEnergy() const { return theExcitationEnergy; } ///\brief Returns true if the nucleus contains any deltas. inline G4bool containsDeltas() { ParticleList inside = theStore->getParticles(); for(ParticleIter i=inside.begin(); i!=inside.end(); ++i) if((*i)->isDelta()) return true; return false; } /** * Print the nucleus info */ std::string print(); std::string dump(); Store* getStore() const {return theStore; }; void setStore(Store *s) { delete theStore; theStore = s; }; G4double getInitialInternalEnergy() const { return initialInternalEnergy; }; /** \brief Is the event transparent? * * To be called at the end of the cascade. **/ G4bool isEventTransparent() const; /** \brief Does the nucleus give a cascade remnant? * * To be called after computeRecoilKinematics(). **/ G4bool hasRemnant() const { return remnant; } /** * Fill the event info which contains INCL output data */ // void fillEventInfo(Results::EventInfo *eventInfo); void fillEventInfo(EventInfo *eventInfo); G4bool getTryCompoundNucleus() { return tryCN; } /// \brief Return the charge number of the projectile G4int getProjectileChargeNumber() const { return projectileZ; } /// \brief Return the mass number of the projectile G4int getProjectileMassNumber() const { return projectileA; } /// \brief Set the charge number of the projectile void setProjectileChargeNumber(G4int n) { projectileZ=n; } /// \brief Set the mass number of the projectile void setProjectileMassNumber(G4int n) { projectileA=n; } /// \brief Returns true if a transparent event should be forced. G4bool isForcedTransparent() { return forceTransparent; } /// \brief Get the transmission barrier G4double getTransmissionBarrier(Particle const * const p) { const G4double theTransmissionRadius = theDensity->getTransmissionRadius(p); const G4double theParticleZ = p->getZ(); return PhysicalConstants::eSquared*(theZ-theParticleZ)*theParticleZ/theTransmissionRadius; } /// \brief Struct for conservation laws struct ConservationBalance { ThreeVector momentum; G4double energy; G4int Z, A; }; /// \brief Compute charge, mass, energy and momentum balance ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const; /// \brief Adjust the kinematics for complete-fusion events void useFusionKinematics(); /** \brief Get the maximum allowed radius for a given particle. * * Calls the NuclearDensity::getMaxRFromP() method for nucleons and deltas, * and the NuclearDensity::getTrasmissionRadius() method for pions. * * \param particle pointer to a particle * \return surface radius */ G4double getSurfaceRadius(Particle const * const particle) const { if(particle->isPion()) // Temporarily set RPION = RMAX return getUniverseRadius(); //return 0.5*(theDensity->getTransmissionRadius(particle)+getUniverseRadius()); else { const G4double pr = particle->getMomentum().mag()/thePotential->getFermiMomentum(particle); if(pr>=1.) return getUniverseRadius(); else return theDensity->getMaxRFromP(pr); } } /** \brief Get the Coulomb radius for a given particle * * That's the radius of the sphere that the Coulomb trajectory of the * incoming particle should intersect. The intersection point is used to * determine the effective impact parameter of the trajectory and the new * entrance angle. * * If the particle is not a Cluster, the Coulomb radius reduces to the * surface radius. We use a parametrisation for d, t, He3 and alphas. For * heavier clusters we fall back to the surface radius. * * \param p the particle species * \return Coulomb radius */ G4double getCoulombRadius(ParticleSpecies const &p) const { if(p.theType == Composite) { const G4int zp = p.theZ; const G4int ap = p.theA; G4double barr, radius = 0.; if(zp==1 && ap==2) { // d barr = 0.2565*Math::pow23((G4double)theA)-0.78; radius = ParticleTable::eSquared*zp*theZ/barr - 2.5; } else if((zp==1 || zp==2) && ap==3) { // t, He3 barr = 0.5*(0.5009*Math::pow23((G4double)theA)-1.16); radius = ParticleTable::eSquared*theZ/barr - 0.5; } else if(zp==2 && ap==4) { // alpha barr = 0.5939*Math::pow23((G4double)theA)-1.64; radius = ParticleTable::eSquared*zp*theZ/barr - 0.5; } else if(zp>2) { radius = getUniverseRadius(); } if(radius<=0.) { ERROR("Negative Coulomb radius! Using the universe radius" << std::endl); radius = getUniverseRadius(); } return radius; } else return getUniverseRadius(); } /// \brief Getter for theUniverseRadius. G4double getUniverseRadius() const { return theUniverseRadius; } /// \brief Setter for theUniverseRadius. void setUniverseRadius(const G4double universeRadius) { theUniverseRadius=universeRadius; } /// \brief Is it a nucleus-nucleus collision? G4bool isNucleusNucleusCollision() const { return isNucleusNucleus; } /// \brief Set a nucleus-nucleus collision void setNucleusNucleusCollision() { isNucleusNucleus=true; } /// \brief Set a particle-nucleus collision void setParticleNucleusCollision() { isNucleusNucleus=false; } /// \brief Set the projectile remnant void setProjectileRemnant(ProjectileRemnant * const c) { delete theProjectileRemnant; theProjectileRemnant = c; } /// \brief Get the projectile remnant ProjectileRemnant *getProjectileRemnant() const { return theProjectileRemnant; } /// \brief Delete the projectile remnant void deleteProjectileRemnant() { delete theProjectileRemnant; theProjectileRemnant = NULL; } /// \brief Move the components of the projectile remnant to the outgoing list void moveProjectileRemnantComponentsToOutgoing() { theStore->addToOutgoing(theProjectileRemnant->getParticles()); theProjectileRemnant->clearParticles(); } /** \brief Finalise the projectile remnant * * Complete the treatment of the projectile remnant. If it contains * nucleons, assign its excitation energy and spin. Move stuff to the * outgoing list, if appropriate. * * \param emissionTime the emission time of the projectile remnant */ void finalizeProjectileRemnant(const G4double emissionTime); /// \brief Update the particle potential energy. inline void updatePotentialEnergy(Particle *p) { p->setPotentialEnergy(thePotential->computePotentialEnergy(p)); } /// \brief Getter for theDensity NuclearDensity* getDensity() const { return theDensity; }; /// \brief Getter for thePotential NuclearPotential::INuclearPotential* getPotential() const { return thePotential; }; private: /** \brief Compute the recoil kinematics for a 1-nucleon remnant. * * Puts the remnant nucleon on mass shell and tries to enforce approximate * energy conservation by modifying the masses of the outgoing particles. */ void computeOneNucleonRecoilKinematics(); private: G4int theInitialZ, theInitialA; /// \brief The number of entering protons G4int theNpInitial; /// \brief The number of entering neutrons G4int theNnInitial; G4double initialInternalEnergy; ThreeVector incomingAngularMomentum, incomingMomentum; ThreeVector initialCenterOfMass; G4bool remnant; ParticleList toBeUpdated; ParticleList justCreated; Particle *blockedDelta; G4double initialEnergy; Store *theStore; G4bool tryCN; G4bool forceTransparent; /// \brief The charge number of the projectile G4int projectileZ; /// \brief The mass number of the projectile G4int projectileA; /// \brief The radius of the universe G4double theUniverseRadius; /** \brief true if running a nucleus-nucleus collision * * Tells INCL whether to make a projectile-like pre-fragment or not. */ G4bool isNucleusNucleus; /// \brief Pointer to the quasi-projectile ProjectileRemnant *theProjectileRemnant; /// \brief Pointer to the NuclearDensity object NuclearDensity *theDensity; /// \brief Pointer to the NuclearPotential object NuclearPotential::INuclearPotential *thePotential; }; } #endif /* G4INCLNUCLEUS_HH_ */