Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-07 10:11:31

0001 // HINucleusModel.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2025 Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // This file contains the definition of the HIUserHooks class and a
0007 // set of other classes used inside Pythia8 to model collisions
0008 // involving heavy ions.
0009 // Nucleon: represents a proton or a neutron inside a necleus.
0010 // NucleusModel: models the Nucleon distribution in a nucleus.
0011 // WoodsSaxonModel: NucleusModel implementing a simple Woods-Saxon.
0012 // GLISSANDOModel: NucleusModel implementing the GLISSANDO prescription.
0013 
0014 #ifndef Pythia8_HINucleusModel_H
0015 #define Pythia8_HINucleusModel_H
0016 
0017 #include "Pythia8/HIBasics.h"
0018 
0019 namespace Pythia8 {
0020 
0021 //==========================================================================
0022 
0023 // The Nucleon class represents a nucleon in a nucleus. It has an id
0024 // number (proton or neutron) an impact parameter position (absolute
0025 // and relative to the nucleus center), a status and a state to be
0026 // defined and used by a SubCollisionModel.
0027 
0028 class Nucleon {
0029 
0030 public:
0031 
0032   // Enum for specifying the status of a nucleon.
0033   enum Status : int {
0034     UNWOUNDED = 0,  // The nucleon is not wounded.
0035     ELASTIC = 1,    // The nucleon is elastically scattered.
0036     DIFF = 2,       // The nucleon is diffractively wounded.
0037     ABS = 3         // The nucleon is absorptively wounded.
0038   };
0039 
0040   // The state of a nucleon is a general vector of doubles.
0041   typedef vector<double> State;
0042 
0043   // The constuctor takes a particle id and a position in impact
0044   // parameter relative to the nucleus center as arguments.
0045   Nucleon(int idIn = 0, int indexIn = 0, const Vec4 & pos = Vec4())
0046     : idSave(idIn), indexSave(indexIn), nPosSave(pos), bPosSave(pos),
0047       statusSave(UNWOUNDED), eventp(0), isDone(0) {}
0048 
0049   // Accessor functions:
0050 
0051   // The particle id of the nucleon.
0052   int id() const { return idSave; }
0053 
0054   // The index of the nucleon in the nucleus.
0055   int index() const { return indexSave; }
0056 
0057   // The position of this nucleon relative to the nucleus center.
0058   const Vec4 & nPos() const { return nPosSave; }
0059 
0060   // The absolute position in impact parameter space.
0061   const Vec4 & bPos() const { return bPosSave; }
0062 
0063   // Shift the absolute position in impact parameter space.
0064   void bShift(const Vec4 & bvec) { bPosSave += bvec; }
0065 
0066   // The status of the nucleon.
0067   Nucleon::Status status() const { return statusSave; }
0068 
0069   // Check if nucleon has been assigned.
0070   bool done() const { return isDone; }
0071 
0072   // The event this nucleon is assigned to.
0073   EventInfo * event() const { return eventp; }
0074 
0075   // The physical state of the incoming nucleon.
0076   const State & state() const { return stateSave; }
0077 
0078   // Return an alternative state.
0079   const State & altState(int i = 0) {
0080     static State nullstate;
0081     return i < int(altStatesSave.size())? altStatesSave[i]: nullstate;
0082   }
0083 
0084   // Manipulating functions:
0085 
0086   // Set the status.
0087   void status(Nucleon::Status s) { statusSave = s; }
0088 
0089   // Set the physical state.
0090   void state(State s) { stateSave = s; }
0091 
0092   // Add an alternative state.
0093   void addAltState(State s) { altStatesSave.push_back(s); }
0094 
0095   // Select an event for this nucleon.
0096   void select(EventInfo & evp, Nucleon::Status s) {
0097     eventp = &evp;
0098     isDone = true;
0099     status(s);
0100   }
0101 
0102   // Select this nucleon to be assigned to an event.
0103   void select() { isDone = true; }
0104 
0105   // Print out debugging information.
0106   void debug();
0107 
0108   // Reset the states and status.
0109   void reset() {
0110     statusSave = UNWOUNDED;
0111     altStatesSave.clear();
0112     bPosSave = nPosSave;
0113     isDone = false;
0114     eventp = 0;
0115   }
0116 
0117 private:
0118 
0119   // The type of nucleon.
0120   int idSave;
0121 
0122   // The index of this nucleon.
0123   int indexSave;
0124 
0125   // The position in impact parameter relative to the nucleus center.
0126   Vec4 nPosSave;
0127 
0128   // The absolute position in impact parameter.
0129   Vec4 bPosSave;
0130 
0131   // The status.
0132   Nucleon::Status statusSave;
0133 
0134   // The state of this nucleon.
0135   State stateSave;
0136 
0137   // Alternative states to be used to understand fluctuations in the
0138   // state of this nucleon.
0139   vector<State> altStatesSave;
0140 
0141   // Pointer to the event this nucleon ends up in.
0142   EventInfo * eventp;
0143 
0144   // True if this nucleon has been assigned to an event.
0145   bool isDone;
0146 
0147 };
0148 
0149 //==========================================================================
0150 
0151 
0152 class Nucleus {
0153 
0154 public:
0155 
0156   // Default constructor.
0157   Nucleus() = default;
0158 
0159   // Constructor with nucleons and impact parameter.
0160   Nucleus(vector<Nucleon> nucleons, Vec4 bPos) : bPosSave(bPos) {
0161     nucleonsSave = make_shared<vector<Nucleon>>(nucleons);
0162     for (Nucleon& nucleon : *nucleonsSave) {
0163       nucleon.reset();
0164       nucleon.bShift(bPos);
0165     }
0166   }
0167 
0168   // Iterate over nucleons.
0169   vector<Nucleon>::iterator begin() { return nucleonsSave->begin(); }
0170   vector<Nucleon>::iterator end() { return nucleonsSave->end(); }
0171   vector<Nucleon>::const_iterator begin() const {return nucleonsSave->begin();}
0172   vector<Nucleon>::const_iterator end() const {return nucleonsSave->end();}
0173 
0174 private:
0175 
0176   // Saved nucleons and impact parameter.
0177   shared_ptr<vector<Nucleon>> nucleonsSave;
0178   Vec4 bPosSave;
0179 
0180 };
0181 
0182 //==========================================================================
0183 
0184 // This class generates the impact parameter distribution of nucleons
0185 // in a nucleus.
0186 
0187 class NucleusModel {
0188 
0189 public:
0190 
0191   // Default constructor giving the nucleus id and an optional
0192   // radius (in femtometer).
0193   NucleusModel() : isProj(true), idSave(0), ISave(0), ASave(0),
0194      ZSave(0), LSave(0), RSave(0.0), settingsPtr(0),
0195      rndmPtr(0) {}
0196 
0197   // Virtual destructor.
0198   virtual ~NucleusModel() {}
0199 
0200   static shared_ptr<NucleusModel> create(int model);
0201 
0202   // Init method.
0203   void initPtr(int idIn, bool isProjIn, Info& infoIn);
0204   virtual bool init() { return true; }
0205   virtual bool initGeometry() { return false; }
0206 
0207   // Set the particle id of the produced nucleus.
0208   void setParticle(int idIn);
0209 
0210   // Set (new) nucleon momentum.
0211   virtual void setPN(const Vec4 & pNIn) { pNSave = pNIn; }
0212 
0213   // Set (new) effective nucleon mass.
0214   virtual void setMN(double mNIn) { mNSave = mNIn; }
0215 
0216   // Produce an instance of the incoming nucleon.
0217   virtual Particle produceIon();
0218 
0219   // Generate a vector of nucleons according to the implemented model
0220   // for a nucleus given by the PDG number.
0221   virtual vector<Nucleon> generate() const = 0;
0222 
0223   // Accessor functions.
0224   int id() const { return idSave; }
0225   int I() const { return ISave; }
0226   int A() const { return ASave; }
0227   int Z() const { return ZSave; }
0228   int L() const { return LSave; }
0229   double R() const { return RSave; }
0230 
0231   int idN() const { return idNSave; }
0232   const Vec4 & pN() const { return pNSave; }
0233   double mN() const { return mNSave; }
0234 
0235 protected:
0236 
0237   // Projectile or target.
0238   bool isProj;
0239 
0240   // The nucleus.
0241   int idSave;
0242 
0243   // Cache information about the nucleus.
0244   int ISave, ASave, ZSave, LSave;
0245 
0246   // The estimate of the nucleus radius.
0247   double RSave;
0248 
0249   // The mass of the nucleus and its nucleons.
0250   double mSave{};
0251 
0252   // The nucleon beam momentum.
0253   Vec4 pNSave{};
0254 
0255   // The effective nucleon mass.
0256   double mNSave{};
0257 
0258   int idNSave = 2212;
0259 
0260   // Pointers to useful objects.
0261   Info* infoPtr;
0262   Settings* settingsPtr;
0263   Rndm* rndmPtr;
0264   Logger* loggerPtr;
0265 
0266 };
0267 
0268 //==========================================================================
0269 
0270 // A nucleus model defined by an external file to be read in, containing
0271 // x,y,z coordinates of the nucleons.
0272 
0273 class ExternalNucleusModel : public NucleusModel {
0274 
0275 public:
0276 
0277   // Default constructor.
0278   ExternalNucleusModel() : fName(""), doShuffle(true), nUsed(0) {}
0279 
0280   // Initialize class. Read in file to buffer.
0281   bool init() override;
0282 
0283   // Generate a vector of nucleons according to the implemented model
0284   // for a nucleus given by the PDG number.
0285   vector<Nucleon> generate() const override;
0286 
0287 private:
0288 
0289   // The filename to read from.
0290   string fName;
0291 
0292   // Shuffle configurations.
0293   bool doShuffle;
0294 
0295   // The read nucleon configurations. Time component is always zero.
0296   mutable vector<vector<Vec4> > nucleonPositions;
0297 
0298   // The number of configurations used so far.
0299   mutable size_t nUsed;
0300 
0301 };
0302 
0303 //==========================================================================
0304 
0305 // A NucleusModel which allows for a hard core, optionally a Gaussian
0306 // hard core. This is an abstract class intended as a base class for
0307 // models with this functionality.
0308 
0309 class HardCoreModel : public NucleusModel {
0310 
0311 public:
0312 
0313   // Default constructor.
0314   HardCoreModel() : useHardCore(), gaussHardCore(), hardCoreRadius(0.9) {}
0315 
0316   // Virtual destructor.
0317   virtual ~HardCoreModel() {}
0318 
0319   // Initialize the parameters for hard core generation.
0320   // To be called in init() in derived classes.
0321   void initHardCore();
0322 
0323   // Get the radius of the hard core. If using a Gaussian hard core, the
0324   // radius is distributed according to a 1D Gaussian.
0325   double rSample() const {
0326     if (gaussHardCore) return hardCoreRadius * abs(rndmPtr->gauss());
0327     return hardCoreRadius;}
0328 
0329 protected:
0330 
0331   // Use the hard core or not.
0332   bool useHardCore;
0333 
0334   // Use a Gaussian hard core.
0335   bool gaussHardCore;
0336 
0337   // The radius or width of the hard core.
0338   double hardCoreRadius;
0339 
0340 };
0341 
0342 //==========================================================================
0343 
0344 // A general Woods-Saxon distributed nucleus.
0345 
0346 class WoodsSaxonModel : public HardCoreModel {
0347 
0348 public:
0349 
0350   // Virtual destructor.
0351   virtual ~WoodsSaxonModel() {}
0352 
0353   // The default constructor needs a nucleus id, a radius, R, and a
0354   // "skin width", a (both length in femtometers).
0355   WoodsSaxonModel(): aSave(0.0), intlo(0.0),
0356                     inthi0(0.0), inthi1(0.0), inthi2(0.0) {}
0357 
0358   // Initialize parameters.
0359   bool init() override;
0360   bool initGeometry() override;
0361 
0362   // Generate all the nucleons.
0363   vector<Nucleon> generate() const override;
0364 
0365   // Accessor functions.
0366   double a() const { return aSave; }
0367 
0368 protected:
0369 
0370   // Generate the position of a single nucleon. (The time component
0371   // is always zero).
0372   Vec4 generateNucleon() const;
0373 
0374   // Calculate overestimates for sampling.
0375   void overestimates() {
0376     intlo = R()*R()*R()/3.0;
0377     inthi0 = a()*R()*R();
0378     inthi1 = 2.0*a()*a()*R();
0379     inthi2 = 2.0*a()*a()*a();
0380   }
0381 
0382 protected:
0383 
0384   // The nucleus radius, skin depth parameter, and hard core nucleon radius.
0385   double aSave;
0386 
0387 private:
0388 
0389   // Cashed integrals over the different parts of the over estimating
0390   // functions.
0391   double intlo, inthi0, inthi1, inthi2;
0392 
0393 };
0394 
0395 
0396 //==========================================================================
0397 
0398 // The GLISSANDOModel is a specific parameterization of a Woods-Saxon
0399 // potential for A>16. It is described in arXiv:1310.5475 [nucl-th].
0400 
0401 class GLISSANDOModel : public WoodsSaxonModel {
0402 
0403 public:
0404 
0405   // Default constructor.
0406   GLISSANDOModel() {}
0407 
0408   // Virtual destructor.
0409   virtual ~GLISSANDOModel() {}
0410 
0411   // Initialize.
0412   bool init() override;
0413   bool initGeometry() override;
0414 
0415 };
0416 
0417 //==========================================================================
0418 
0419 // A Harmonic-Oscillator Shell model for light nuclei.
0420 
0421 class HOShellModel : public HardCoreModel {
0422 
0423 public:
0424 
0425   // Default constructor.
0426   HOShellModel(): nucleusChR(), protonChR(), C2() {}
0427 
0428   // Destructor.
0429   virtual ~HOShellModel() {}
0430 
0431   // Initialize, set up parameters.
0432   virtual bool init() override;
0433 
0434   // Generate a vector of nucleons according to the implemented model
0435   // for a nucleus given by the PDG number.
0436   virtual vector<Nucleon> generate() const override;
0437 
0438 protected:
0439 
0440   // Generate the position of a single nucleon. (The time component
0441   // is always zero).
0442   virtual Vec4 generateNucleon() const;
0443 
0444   // The density function.
0445   double rho(double r) const {
0446     double pref = 4./(pow(sqrt(M_PI * C2),3)) * (1 + (A() - 4.)/6. * r*r/C2);
0447     return pref * exp(-r*r / C2);
0448   };
0449 
0450   // Nucleus charge radius.
0451   double nucleusChR;
0452 
0453   // Nucleon charge radius.
0454   double protonChR;
0455 
0456   // C2 parameter.
0457   double C2;
0458 
0459   // Maximum rho for these parameters.
0460   double rhoMax;
0461 
0462 };
0463 
0464 //==========================================================================
0465 
0466 // The Hulthen potential for deuterons.
0467 
0468 class HulthenModel : public NucleusModel {
0469 
0470 public:
0471 
0472   // Default constructor.
0473   HulthenModel(): hA(), hB() {}
0474 
0475   // Virtual destructor.
0476   virtual ~HulthenModel() {}
0477 
0478   virtual bool init() override;
0479 
0480   // Generate a vector of nucleons according to the Hulthen potential.
0481   virtual vector<Nucleon> generate() const override;
0482 
0483 protected:
0484 
0485   // The (normalized) density function.
0486   double rho(double r) const {
0487     double pref = (2*hA*hB*(hA + hB))/pow2(hA - hB);
0488     double exps = exp(-2.*hA*r) + exp(-2.*hB*r) - 2.*exp(-(hA+hB)*r);
0489     return pref * exps;
0490   };
0491 
0492   // Parameters of the Hulthen model.
0493   double hA;
0494   double hB;
0495 
0496 };
0497 
0498 //==========================================================================
0499 
0500 // A Gaussian distribution for light nuclei.
0501 
0502 class GaussianModel : public HardCoreModel {
0503 
0504 public:
0505 
0506   // Default constructor.
0507   GaussianModel(): nucleusChR() {}
0508 
0509   // Destructor.
0510   virtual ~GaussianModel() {}
0511 
0512   virtual bool init() override;
0513 
0514   // Generate a vector of nucleons according to the implemented model
0515   // for a nucleus given by the PDG number.
0516   virtual vector<Nucleon> generate() const override;
0517 
0518 protected:
0519 
0520   // Generate the position of a single nucleon. (The time component
0521   // is always zero).
0522   virtual Vec4 generateNucleon() const;
0523 
0524   // Nucleus charge radius.
0525   double nucleusChR;
0526 
0527 };
0528 
0529 //==========================================================================
0530 
0531 // A model for nuclei clustered in smaller nuclei.
0532 
0533 class ClusterModel : public HardCoreModel {
0534 
0535 public:
0536 
0537   // Contructor.
0538   ClusterModel() {}
0539 
0540   // Virtual destructor.
0541   virtual ~ClusterModel() {}
0542 
0543   // Initialize parameters.
0544   virtual bool init() override;
0545 
0546   // Generate a vector of nucleons. Note that this model
0547   // is only implemented for XX, YY ZZ.
0548   virtual vector<Nucleon> generate() const override;
0549 
0550 private:
0551 
0552   // The model to generate clusters from.
0553   unique_ptr<NucleusModel> nModelPtr;
0554 
0555 };
0556 
0557 //==========================================================================
0558 
0559 } // end namespace Pythia8
0560 
0561 #endif // Pythia8_HINucleusModel_H