Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:25

0001 // HINucleusModel.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 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 
0206   // Set the particle id of the produced nucleus.
0207   void setParticle(int idIn);
0208 
0209   // Set (new) nucleon momentum.
0210   virtual void setPN(const Vec4 & pNIn) { pNSave = pNIn; }
0211 
0212   // Produce an instance of the incoming nucleon.
0213   virtual Particle produceIon();
0214 
0215   // Generate a vector of nucleons according to the implemented model
0216   // for a nucleus given by the PDG number.
0217   virtual vector<Nucleon> generate() const = 0;
0218 
0219   // Accessor functions.
0220   int id() const { return idSave; }
0221   int I() const { return ISave; }
0222   int A() const { return ASave; }
0223   int Z() const { return ZSave; }
0224   int L() const { return LSave; }
0225   double R() const { return RSave; }
0226 
0227 protected:
0228 
0229   // Projectile or target.
0230   bool isProj;
0231 
0232   // The nucleus.
0233   int idSave;
0234 
0235   // Cache information about the nucleus.
0236   int ISave, ASave, ZSave, LSave;
0237 
0238   // The estimate of the nucleus radius.
0239   double RSave;
0240 
0241   // The mass of the nucleus and its nucleons.
0242   double mSave{};
0243 
0244   // The nucleon beam momentum.
0245   Vec4 pNSave{};
0246 
0247   // Pointers to useful objects.
0248   Info* infoPtr;
0249   Settings* settingsPtr;
0250   Rndm* rndmPtr;
0251   Logger* loggerPtr;
0252 
0253 };
0254 
0255 //==========================================================================
0256 
0257 // A nucleus model defined by an external file to be read in, containing
0258 // x,y,z coordinates of the nucleons.
0259 
0260 class ExternalNucleusModel : public NucleusModel {
0261 
0262 public:
0263 
0264   // Default constructor.
0265   ExternalNucleusModel() : fName(""), doShuffle(true), nUsed(0) {}
0266 
0267   // Initialize class. Read in file to buffer.
0268   bool init() override;
0269 
0270   // Generate a vector of nucleons according to the implemented model
0271   // for a nucleus given by the PDG number.
0272   vector<Nucleon> generate() const override;
0273 
0274 private:
0275 
0276   // The filename to read from.
0277   string fName;
0278 
0279   // Shuffle configurations.
0280   bool doShuffle;
0281 
0282   // The read nucleon configurations. Time component is always zero.
0283   mutable vector<vector<Vec4> > nucleonPositions;
0284 
0285   // The number of configurations used so far.
0286   mutable size_t nUsed;
0287 
0288 };
0289 
0290 //==========================================================================
0291 
0292 // A NucleusModel which allows for a hard core, optionally a Gaussian
0293 // hard core. This is an abstract class intended as a base class for
0294 // models with this functionality.
0295 
0296 class HardCoreModel : public NucleusModel {
0297 
0298 public:
0299 
0300   // Default constructor.
0301   HardCoreModel() : useHardCore(), gaussHardCore(), hardCoreRadius(0.9) {}
0302 
0303   // Virtual destructor.
0304   virtual ~HardCoreModel() {}
0305 
0306   // Initialize the parameters for hard core generation.
0307   // To be called in init() in derived classes.
0308   void initHardCore();
0309 
0310   // Get the radius of the hard core. If using a Gaussian hard core, the
0311   // radius is distributed according to a 1D Gaussian.
0312   double rSample() const {
0313     if (gaussHardCore) return hardCoreRadius * abs(rndmPtr->gauss());
0314     return hardCoreRadius;}
0315 
0316 protected:
0317 
0318   // Use the hard core or not.
0319   bool useHardCore;
0320 
0321   // Use a Gaussian hard core.
0322   bool gaussHardCore;
0323 
0324   // The radius or width of the hard core.
0325   double hardCoreRadius;
0326 
0327 };
0328 
0329 //==========================================================================
0330 
0331 // A general Woods-Saxon distributed nucleus.
0332 
0333 class WoodsSaxonModel : public HardCoreModel {
0334 
0335 public:
0336 
0337   // Virtual destructor.
0338   virtual ~WoodsSaxonModel() {}
0339 
0340   // The default constructor needs a nucleus id, a radius, R, and a
0341   // "skin width", a (both length in femtometers).
0342   WoodsSaxonModel(): aSave(0.0), intlo(0.0),
0343                     inthi0(0.0), inthi1(0.0), inthi2(0.0) {}
0344 
0345   // Initialize parameters.
0346   bool init() override;
0347 
0348   // Generate all the nucleons.
0349   vector<Nucleon> generate() const override;
0350 
0351   // Accessor functions.
0352   double a() const { return aSave; }
0353 
0354 protected:
0355 
0356   // Generate the position of a single nucleon. (The time component
0357   // is always zero).
0358   Vec4 generateNucleon() const;
0359 
0360   // Calculate overestimates for sampling.
0361   void overestimates() {
0362     intlo = R()*R()*R()/3.0;
0363     inthi0 = a()*R()*R();
0364     inthi1 = 2.0*a()*a()*R();
0365     inthi2 = 2.0*a()*a()*a();
0366   }
0367 
0368 protected:
0369 
0370   // The nucleus radius, skin depth parameter, and hard core nucleon radius.
0371   double aSave;
0372 
0373 private:
0374 
0375   // Cashed integrals over the different parts of the over estimating
0376   // functions.
0377   double intlo, inthi0, inthi1, inthi2;
0378 
0379 };
0380 
0381 
0382 //==========================================================================
0383 
0384 // The GLISSANDOModel is a specific parameterization of a Woods-Saxon
0385 // potential for A>16. It is described in arXiv:1310.5475 [nucl-th].
0386 
0387 class GLISSANDOModel : public WoodsSaxonModel {
0388 
0389 public:
0390 
0391   // Default constructor.
0392   GLISSANDOModel() {}
0393 
0394   // Virtual destructor.
0395   virtual ~GLISSANDOModel() {}
0396 
0397   // Initialize.
0398   bool init() override;
0399 
0400 };
0401 
0402 //==========================================================================
0403 
0404 // A Harmonic-Oscillator Shell model for light nuclei.
0405 
0406 class HOShellModel : public HardCoreModel {
0407 
0408 public:
0409 
0410   // Default constructor.
0411   HOShellModel(): nucleusChR(), protonChR(), C2() {}
0412 
0413   // Destructor.
0414   virtual ~HOShellModel() {}
0415 
0416   // Initialize, set up parameters.
0417   virtual bool init() override;
0418 
0419   // Generate a vector of nucleons according to the implemented model
0420   // for a nucleus given by the PDG number.
0421   virtual vector<Nucleon> generate() const override;
0422 
0423 protected:
0424 
0425   // Generate the position of a single nucleon. (The time component
0426   // is always zero).
0427   virtual Vec4 generateNucleon() const;
0428 
0429   // The density function.
0430   double rho(double r) const {
0431     double pref = 4./(pow(sqrt(M_PI * C2),3)) * (1 + (A() - 4.)/6. * r*r/C2);
0432     return pref * exp(-r*r / C2);
0433   };
0434 
0435   // Nucleus charge radius.
0436   double nucleusChR;
0437 
0438   // Nucleon charge radius.
0439   double protonChR;
0440 
0441   // C2 parameter.
0442   double C2;
0443 
0444   // Maximum rho for these parameters.
0445   double rhoMax;
0446 
0447 };
0448 
0449 //==========================================================================
0450 
0451 // The Hulthen potential for deuterons.
0452 
0453 class HulthenModel : public NucleusModel {
0454 
0455 public:
0456 
0457   // Default constructor.
0458   HulthenModel(): hA(), hB() {}
0459 
0460   // Virtual destructor.
0461   virtual ~HulthenModel() {}
0462 
0463   virtual bool init() override;
0464 
0465   // Generate a vector of nucleons according to the Hulthen potential.
0466   virtual vector<Nucleon> generate() const override;
0467 
0468 protected:
0469 
0470   // The (normalized) density function.
0471   double rho(double r) const {
0472     double pref = (2*hA*hB*(hA + hB))/pow2(hA - hB);
0473     double exps = exp(-2.*hA*r) + exp(-2.*hB*r) - 2.*exp(-(hA+hB)*r);
0474     return pref * exps;
0475   };
0476 
0477   // Parameters of the Hulthen model.
0478   double hA;
0479   double hB;
0480 
0481 };
0482 
0483 //==========================================================================
0484 
0485 // A Gaussian distribution for light nuclei.
0486 
0487 class GaussianModel : public HardCoreModel {
0488 
0489 public:
0490 
0491   // Default constructor.
0492   GaussianModel(): nucleusChR() {}
0493 
0494   // Destructor.
0495   virtual ~GaussianModel() {}
0496 
0497   virtual bool init() override;
0498 
0499   // Generate a vector of nucleons according to the implemented model
0500   // for a nucleus given by the PDG number.
0501   virtual vector<Nucleon> generate() const override;
0502 
0503 protected:
0504 
0505   // Generate the position of a single nucleon. (The time component
0506   // is always zero).
0507   virtual Vec4 generateNucleon() const;
0508 
0509   // Nucleus charge radius.
0510   double nucleusChR;
0511 
0512 };
0513 
0514 //==========================================================================
0515 
0516 // A model for nuclei clustered in smaller nuclei.
0517 
0518 class ClusterModel : public HardCoreModel {
0519 
0520 public:
0521 
0522   // Contructor.
0523   ClusterModel() {}
0524 
0525   // Virtual destructor.
0526   virtual ~ClusterModel() {}
0527 
0528   // Initialize parameters.
0529   virtual bool init() override;
0530 
0531   // Generate a vector of nucleons. Note that this model
0532   // is only implemented for XX, YY ZZ.
0533   virtual vector<Nucleon> generate() const override;
0534 
0535 private:
0536 
0537   // The model to generate clusters from.
0538   unique_ptr<NucleusModel> nModelPtr;
0539 
0540 };
0541 
0542 //==========================================================================
0543 
0544 } // end namespace Pythia8
0545 
0546 #endif // Pythia8_HINucleusModel_H