Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:29

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // INCL++ intra-nuclear cascade model
0027 // Alain Boudard, CEA-Saclay, France
0028 // Joseph Cugnon, University of Liege, Belgium
0029 // Jean-Christophe David, CEA-Saclay, France
0030 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
0031 // Sylvie Leray, CEA-Saclay, France
0032 // Davide Mancusi, CEA-Saclay, France
0033 //
0034 #define INCLXX_IN_GEANT4_MODE 1
0035 
0036 #include "globals.hh"
0037 
0038 /** \file G4INCLProjectileRemnant.hh
0039  * \brief Class for constructing a projectile-like remnant.
0040  *
0041  * \date 20 March 2012
0042  * \author Davide Mancusi
0043  */
0044 
0045 #ifndef G4INCLPROJECTILEREMNANT_HH_
0046 #define G4INCLPROJECTILEREMNANT_HH_
0047 
0048 #include "G4INCLCluster.hh"
0049 #include "G4INCLRandom.hh"
0050 #include "G4INCLAllocationPool.hh"
0051 #include <vector>
0052 #include <map>
0053 #include <numeric>
0054 #include <functional>
0055 
0056 namespace G4INCL {
0057 
0058   class ProjectileRemnant : public Cluster {
0059     public:
0060 
0061     // typedefs for the calculation of the projectile excitation energy
0062     typedef std::vector<G4double> EnergyLevels;
0063     typedef std::map<long, G4double> EnergyLevelMap;
0064 
0065     ProjectileRemnant(ParticleSpecies const &species, const G4double kineticEnergy)
0066       : Cluster(species.theZ, species.theA, species.theS) {
0067 
0068       // Use the table mass
0069       setTableMass();
0070 
0071       // Set the kinematics
0072       const G4double projectileMass = getMass();
0073       const G4double energy = kineticEnergy + projectileMass;
0074       const G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
0075 
0076       // Initialise the particles
0077       initializeParticles();
0078       internalBoostToCM();
0079       putParticlesOffShell();
0080 
0081       // Store the energy levels of the ProjectileRemnant (used to compute its
0082       // excitation energy)
0083       storeEnergyLevels();
0084 
0085       // Boost the whole thing
0086       const ThreeVector aBoostVector = ThreeVector(0.0, 0.0, momentumZ / energy);
0087       boost(-aBoostVector);
0088 
0089       // Freeze the internal motion of the particles
0090       freezeInternalMotion();
0091 
0092       // Set as projectile spectator
0093       makeProjectileSpectator();
0094     }
0095 
0096     ~ProjectileRemnant() {
0097       deleteStoredComponents();
0098       // The ProjectileRemnant owns its particles
0099       deleteParticles();
0100       clearEnergyLevels();
0101     }
0102 
0103     /// \brief Reset the projectile remnant to the state at the beginning of the cascade
0104     void reset();
0105 
0106     /** \brief Remove a nucleon from the projectile remnant
0107      *
0108      * \param p particle to be removed
0109      * \param theProjectileCorrection correction to be given to the projectile total energy
0110      */
0111     void removeParticle(Particle * const p, const G4double theProjectileCorrection);
0112 
0113     /** \brief Add back dynamical spectators to the projectile remnant
0114      *
0115      * Try to add the dynamical spectators back to the projectile remnant.
0116      * Refuse to do so if this leads to a negative projectile excitation
0117      * energy.
0118      *
0119      * Return a list of rejected dynamical spectators.
0120      */
0121     ParticleList addDynamicalSpectators(ParticleList pL);
0122 
0123     /** \brief Add back dynamical spectators to the projectile remnant
0124      *
0125      * Try as hard as possible to add back all the dynamical spectators.  Don't
0126      * add spectators that lead to negative excitation energies. Start by
0127      * adding all of them, and repeatedly remove the most troublesome one until
0128      * the excitation energy becomes non-negative.
0129      *
0130      * Return a list of rejected dynamical spectators.
0131      */
0132     ParticleList addMostDynamicalSpectators(ParticleList pL);
0133 
0134     /** \brief Add back all dynamical spectators to the projectile remnant
0135      *
0136      * Return a list of rejected dynamical spectators.
0137      */
0138     ParticleList addAllDynamicalSpectators(ParticleList const &pL);
0139 
0140     /// \brief Clear the stored projectile components and delete the particles
0141     void deleteStoredComponents() {
0142       for(std::map<long,Particle*>::const_iterator p=storedComponents.begin(), e=storedComponents.end(); p!=e; ++p)
0143         delete p->second;
0144       clearStoredComponents();
0145     }
0146 
0147     /// \brief Clear the stored projectile components
0148     void clearStoredComponents() {
0149       storedComponents.clear();
0150     }
0151 
0152     /// \brief Clear the stored energy levels
0153     void clearEnergyLevels() {
0154       theInitialEnergyLevels.clear();
0155       theGroundStateEnergies.clear();
0156     }
0157 
0158     /** \brief Compute the excitation energy when a nucleon is removed
0159      *
0160      * Compute the excitation energy of the projectile-like remnant as the
0161      * difference between the initial and the present configuration. This
0162      * follows the algorithm proposed by A. Boudard in INCL4.2-HI, as
0163      * implemented in Geant4.
0164      *
0165      * \return the excitation energy
0166      */
0167     G4double computeExcitationEnergyExcept(const long exceptID) const;
0168 
0169     /** \brief Compute the excitation energy if some nucleons are put back
0170      *
0171      * \return the excitation energy
0172      */
0173     G4double computeExcitationEnergyWith(const ParticleList &pL) const;
0174 
0175     /// \brief Store the projectile components
0176     void storeComponents() {
0177       for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0178         // Store the particles (needed for forced CN)
0179         storedComponents[(*p)->getID()]=new Particle(**p);
0180       }
0181     }
0182 
0183     /// \brief Get the number of the stored components
0184     G4int getNumberStoredComponents() const {
0185       return (G4int)storedComponents.size();
0186     }
0187 
0188     /// \brief Store the energy levels
0189     void storeEnergyLevels() {
0190       EnergyLevels energies;
0191 
0192       for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0193         const G4double theCMEnergy = (*p)->getEnergy();
0194         // Store the CM energy in the EnergyLevels map
0195         theInitialEnergyLevels[(*p)->getID()] = theCMEnergy;
0196         energies.push_back(theCMEnergy);
0197       }
0198 
0199       std::sort(energies.begin(), energies.end());
0200 // assert(energies.size()==(unsigned int)theA);
0201       theGroundStateEnergies.resize(energies.size());
0202       // Compute the partial sums of the CM energies -- they are our reference
0203       // ground-state energies for any number of nucleons
0204       std::partial_sum(energies.begin(), energies.end(), theGroundStateEnergies.begin());
0205     }
0206 
0207     EnergyLevels const &getGroundStateEnergies() const {
0208       return theGroundStateEnergies;
0209     }
0210 
0211     private:
0212 
0213     /** \brief Compute the excitation energy for a given configuration
0214      *
0215      * The function that does the real job of calculating the excitation energy
0216      * for a given configuration of energy levels.
0217      *
0218      * \param levels a configuration of energy levels
0219      * \return the excitation energy
0220      */
0221     G4double computeExcitationEnergy(const EnergyLevels &levels) const;
0222 
0223     EnergyLevels getPresentEnergyLevelsExcept(const long exceptID) const;
0224 
0225     EnergyLevels getPresentEnergyLevelsWith(const ParticleList &pL) const;
0226 
0227     /// \brief Shuffle the list of stored projectile components
0228     ParticleList shuffleStoredComponents() {
0229       ParticleList pL = getStoredComponents();
0230       std::shuffle(pL.begin(), pL.end(), Random::getAdapter());
0231       return pL;
0232     }
0233 
0234     ParticleList getStoredComponents() const {
0235       ParticleList pL;
0236       for(std::map<long,Particle*>::const_iterator p=storedComponents.begin(), e=storedComponents.end(); p!=e; ++p)
0237         pL.push_back(p->second);
0238       return pL;
0239     }
0240 
0241     /// \brief Return the stored momentum of a given projectile component
0242     ThreeVector const &getStoredMomentum(Particle const * const p) const {
0243       std::map<long,Particle*>::const_iterator i = storedComponents.find(p->getID());
0244       if(i==storedComponents.end()) {
0245         INCL_ERROR("Couldn't find particle " << p->getID() << " in the list of projectile components" << '\n');
0246         return p->getMomentum();
0247       } else {
0248         return i->second->getMomentum();
0249       }
0250     }
0251 
0252     /** \brief Add back a nucleon to the projectile remnant
0253      *
0254      * Try to add a dynamical spectator back to the projectile remnant. Refuse
0255      * to do so if this leads to a negative projectile excitation energy.
0256      * Return true on success, false on failure.
0257      */
0258     G4bool addDynamicalSpectator(Particle * const p);
0259 
0260     /// \brief Return the stored energy of a given projectile component
0261     /*    G4double getStoredEnergy(Particle const * const p) {
0262           std::map<long,Particle*>::const_iterator i = initialProjectileComponents.find(p->getID());
0263           if(i==initialProjectileComponents.end()) {
0264           INCL_ERROR("Couldn't find particle " << p->getID() << " in the list of projectile components" << '\n');
0265           return 0.;
0266           } else {
0267           return i->second->getEnergy();
0268           }
0269           }*/
0270 
0271     /** \brief Stored projectile components
0272      *
0273      * These particles are owned by the ProjectileRemnant.
0274      */
0275     std::map<long, Particle*> storedComponents;
0276 
0277     /// \brief Initial energy levels of the projectile
0278     EnergyLevelMap theInitialEnergyLevels;
0279 
0280     /// \brief Ground-state energies for any number of nucleons
0281     EnergyLevels theGroundStateEnergies;
0282 
0283     INCL_DECLARE_ALLOCATION_POOL(ProjectileRemnant)
0284   };
0285 }
0286 
0287 #endif // G4INCLPROJECTILEREMNANT_HH_
0288