PYTHIA  8.317
HINucleusModel.h
1 // HINucleusModel.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2026 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // This file contains the definition of the HIUserHooks class and a
7 // set of other classes used inside Pythia8 to model collisions
8 // involving heavy ions.
9 // Nucleon: represents a proton or a neutron inside a necleus.
10 // NucleusModel: models the Nucleon distribution in a nucleus.
11 // WoodsSaxonModel: NucleusModel implementing a simple Woods-Saxon.
12 // GLISSANDOModel: NucleusModel implementing the GLISSANDO prescription.
13 
14 #ifndef Pythia8_HINucleusModel_H
15 #define Pythia8_HINucleusModel_H
16 
17 #include "Pythia8/HIBasics.h"
18 
19 namespace Pythia8 {
20 
21 //==========================================================================
22 
23 // The Nucleon class represents a nucleon in a nucleus. It has an id
24 // number (proton or neutron) an impact parameter position (absolute
25 // and relative to the nucleus center), a status and a state to be
26 // defined and used by a SubCollisionModel.
27 
28 class Nucleon {
29 
30 public:
31 
32  // Enum for specifying the status of a nucleon.
33  enum Status : int {
34  UNWOUNDED = 0, // The nucleon is not wounded.
35  ELASTIC = 1, // The nucleon is elastically scattered.
36  DIFF = 2, // The nucleon is diffractively wounded.
37  ABS = 3 // The nucleon is absorptively wounded.
38  };
39 
40  // The state of a nucleon is a general vector of doubles.
41  typedef vector<double> State;
42 
43  // The constuctor takes a particle id and a position in impact
44  // parameter relative to the nucleus center as arguments.
45  Nucleon(int idIn = 0, int indexIn = 0, const Vec4 & pos = Vec4())
46  : idSave(idIn), indexSave(indexIn), nPosSave(pos), bPosSave(pos),
47  statusSave(UNWOUNDED), eventp(0), isDone(0) {}
48 
49  // Accessor functions:
50 
51  // The particle id of the nucleon.
52  int id() const { return idSave; }
53 
54  // The index of the nucleon in the nucleus.
55  int index() const { return indexSave; }
56 
57  // The position of this nucleon relative to the nucleus center.
58  const Vec4& nPos() const { return nPosSave; }
59 
60  // The absolute position in impact parameter space.
61  const Vec4& bPos() const { return bPosSave; }
62 
63  // Shift the absolute position in impact parameter space.
64  void bShift(const Vec4 & bvec) { bPosSave += bvec; }
65 
66  // The status of the nucleon.
67  Nucleon::Status status() const { return statusSave; }
68 
69  // Check if nucleon has been assigned.
70  bool done() const { return isDone; }
71 
72  // The event this nucleon is assigned to.
73  EventInfo* event() const { return eventp; }
74 
75  // The physical state of the incoming nucleon.
76  const State& state() const { return stateSave; }
77 
78  // Return an alternative state.
79  const State& altState(int i = 0) {
80  static State nullstate;
81  return i < int(altStatesSave.size())? altStatesSave[i]: nullstate;
82  }
83 
84  // Manipulating functions:
85 
86  // Set the status.
87  void status(Nucleon::Status s) { statusSave = s; }
88 
89  // Set the physical state.
90  void state(const State& s) { stateSave = s; }
91 
92  // Add an alternative state.
93  void addAltState(const State& s) { altStatesSave.push_back(s); }
94 
95  // Select an event for this nucleon.
97  eventp = &evp;
98  isDone = true;
99  status(s);
100  }
101 
102  // Select this nucleon to be assigned to an event.
103  void select() { isDone = true; }
104 
105  // Print out debugging information.
106  void debug();
107 
108  // Reset the states and status.
109  void reset() {
110  statusSave = UNWOUNDED;
111  altStatesSave.clear();
112  bPosSave = nPosSave;
113  isDone = false;
114  eventp = 0;
115  }
116 
117 private:
118 
119  // The type of nucleon.
120  int idSave;
121 
122  // The index of this nucleon.
123  int indexSave;
124 
125  // The position in impact parameter relative to the nucleus center.
126  Vec4 nPosSave;
127 
128  // The absolute position in impact parameter.
129  Vec4 bPosSave;
130 
131  // The status.
132  Nucleon::Status statusSave;
133 
134  // The state of this nucleon.
135  State stateSave;
136 
137  // Alternative states to be used to understand fluctuations in the
138  // state of this nucleon.
139  vector<State> altStatesSave;
140 
141  // Pointer to the event this nucleon ends up in.
142  EventInfo * eventp;
143 
144  // True if this nucleon has been assigned to an event.
145  bool isDone;
146 
147 };
148 
149 //==========================================================================
150 
151 
152 class Nucleus {
153 
154 public:
155 
156  // Default constructor.
157  Nucleus() = default;
158 
159  // Constructor with nucleons and impact parameter.
160  Nucleus(vector<Nucleon> nucleons, Vec4 bPos) : bPosSave(bPos) {
161  nucleonsSave = make_shared<vector<Nucleon>>(nucleons);
162  for (Nucleon& nucleon : *nucleonsSave) {
163  nucleon.reset();
164  nucleon.bShift(bPos);
165  }
166  }
167 
168  // Move the nucleus around in impact parameter space.
169  Nucleus & reposition(const Vec4 & bPosNew) {
170  for (Nucleon& nucleon : *nucleonsSave)
171  nucleon.bShift(bPosNew - bPosSave);
172  bPosSave = bPosNew;
173  return *this;
174  }
175 
176  // Iterate over nucleons.
177  vector<Nucleon>::iterator begin() { return nucleonsSave->begin(); }
178  vector<Nucleon>::iterator end() { return nucleonsSave->end(); }
179  vector<Nucleon>::const_iterator begin() const {return nucleonsSave->begin();}
180  vector<Nucleon>::const_iterator end() const {return nucleonsSave->end();}
181  int size() const {return nucleonsSave->size();}
182 
183  const Vec4 & bPos() { return bPosSave; }
184 
185 private:
186 
187  // Saved nucleons and impact parameter.
188  shared_ptr<vector<Nucleon>> nucleonsSave;
189  Vec4 bPosSave;
190 
191 };
192 
193 //==========================================================================
194 
195 // This class generates the impact parameter distribution of nucleons
196 // in a nucleus.
197 
199 
200 public:
201 
202  // Default constructor given the nucleus pdg ID and an optional
203  // radius (in femtometer).
204  NucleusModel() : isProj(true), idSave(0), ISave(0), ASave(0),
205  ZSave(0), LSave(0), RSave(0.0), settingsPtr(0),
206  rndmPtr(0) {}
207 
208  // Virtual destructor.
209  virtual ~NucleusModel() {}
210 
211  static shared_ptr<NucleusModel> create(int model);
212 
213  // Init method.
214  void initPtr(int idIn, bool isProjIn, Info& infoIn);
215  virtual bool init() { return true; }
216  virtual bool initGeometry() { return false; }
217 
218  // Set the particle id of the produced nucleus.
219  void setParticle(int idIn);
220 
221  // Set (new) nucleon 4-momentum.
222  virtual void setPN(const Vec4 & pNIn) { pNSave = pNIn; }
223 
224  // Set (new) effective nucleon mass.
225  virtual void setMN(double mNIn) { mNSave = mNIn; }
226 
227  // Produce an instance of the incoming nucleon.
228  virtual Particle produceIon();
229 
230  // Generate a vector of nucleons according to the implemented model
231  // for a nucleus given by the PDG number.
232  virtual vector<Nucleon> generate() const = 0;
233 
234  // Accessor functions.
235  int id() const { return idSave; }
236  int I() const { return ISave; }
237  int A() const { return ASave; }
238  int Z() const { return ZSave; }
239  int L() const { return LSave; }
240  double R() const { return RSave; }
241 
242  int idN() const { return idNSave; }
243  const Vec4& pN() const { return pNSave; }
244  double mN() const { return mNSave; }
245 
246 protected:
247 
248  // Projectile or target.
249  bool isProj;
250 
251  // The nucleus.
252  int idSave;
253 
254  // Cache information about the nucleus.
255  int ISave, ASave, ZSave, LSave;
256 
257  // The estimate of the nucleus radius.
258  double RSave;
259 
260  // The mass of the nucleus and its nucleons.
261  double mSave{};
262 
263  // The nucleon beam momentum.
264  Vec4 pNSave{};
265 
266  // The effective nucleon mass.
267  double mNSave{};
268 
269  int idNSave = 2212;
270 
271  // Possibility to only generate a fixed number of nuclei and pick
272  // randomly between these.
273  size_t cacheSize = 0;
274  mutable map<int, vector< vector<Nucleon> > > nucleonCache;
275 
276  // Pointers to useful objects.
278  Settings* settingsPtr;
279  Rndm* rndmPtr;
280  Logger* loggerPtr;
281 
282 };
283 
284 //==========================================================================
285 
286 // A nucleus model defined by an external file to be read in, containing
287 // x,y,z coordinates of the nucleons.
288 
290 
291 public:
292 
293  // Default constructor.
294  ExternalNucleusModel() : fName(""), doShuffle(true), nUsed(0) {}
295 
296  // Initialize class. Read in file to buffer.
297  bool init() override;
298 
299  // Generate a vector of nucleons according to the implemented model
300  // for a nucleus given by the PDG number.
301  vector<Nucleon> generate() const override;
302 
303 private:
304 
305  // The filename to read from.
306  string fName;
307 
308  // Shuffle configurations.
309  bool doShuffle;
310 
311  // The read nucleon configurations. Time component is always zero.
312  mutable vector<vector<Vec4> > nucleonPositions;
313 
314  // The number of configurations used so far.
315  mutable size_t nUsed;
316 
317 };
318 
319 //==========================================================================
320 
321 // A NucleusModel which allows for a hard core, optionally a Gaussian
322 // hard core. This is an abstract class intended as a base class for
323 // models with this functionality.
324 
325 class HardCoreModel : public NucleusModel {
326 
327 public:
328 
329  // Default constructor.
330  HardCoreModel() : useHardCore(), gaussHardCore(), hardCoreRadius(0.9) {}
331 
332  // Virtual destructor.
333  virtual ~HardCoreModel() {}
334 
335  // Initialize the parameters for hard core generation.
336  // To be called in init() in derived classes.
337  void initHardCore();
338 
339  // Get the radius of the hard core. If using a Gaussian hard core, the
340  // radius is distributed according to a 1D Gaussian.
341  double rSample() const {
342  if (gaussHardCore) return hardCoreRadius * abs(rndmPtr->gauss());
343  return hardCoreRadius;}
344 
345 protected:
346 
347  // Use the hard core or not.
349 
350  // Use a Gaussian hard core.
352 
353  // The radius or width of the hard core.
355 
356 };
357 
358 //==========================================================================
359 
360 // A general Woods-Saxon distributed nucleus.
361 
363 
364 public:
365 
366  // Virtual destructor.
367  virtual ~WoodsSaxonModel() {}
368 
369  // The default constructor needs a nucleus id, a radius, R, and a
370  // "skin width", a (both length in femtometers).
371  WoodsSaxonModel(): aSave(0.0), intlo(0.0),
372  inthi0(0.0), inthi1(0.0), inthi2(0.0) {}
373 
374  // Initialize parameters.
375  bool init() override;
376  bool initGeometry() override;
377 
378  // Generate all the nucleons.
379  vector<Nucleon> generate() const override;
380 
381  // Accessor functions.
382  double a() const { return aSave; }
383 
384 protected:
385 
386  // Generate the position of a single nucleon. (The time component
387  // is always zero).
388  Vec4 generateNucleon() const;
389 
390  // Calculate overestimates for sampling.
391  void overestimates() {
392  intlo = R()*R()*R()/3.0;
393  inthi0 = a()*R()*R();
394  inthi1 = 2.0*a()*a()*R();
395  inthi2 = 2.0*a()*a()*a();
396  }
397 
398 protected:
399 
400  // The nucleus radius, skin depth parameter, and hard core nucleon radius.
401  double aSave;
402 
403 private:
404 
405  // Cashed integrals over the different parts of the over estimating
406  // functions.
407  double intlo, inthi0, inthi1, inthi2;
408 
409 };
410 
411 
412 //==========================================================================
413 
414 // The GLISSANDOModel is a specific parameterization of a Woods-Saxon
415 // potential for A>16. It is described in arXiv:1310.5475 [nucl-th].
416 
418 
419 public:
420 
421  // Default constructor.
423 
424  // Virtual destructor.
425  virtual ~GLISSANDOModel() {}
426 
427  // Initialize.
428  bool init() override;
429  bool initGeometry() override;
430 
431 };
432 
433 //==========================================================================
434 
435 // A Harmonic-Oscillator Shell model for light nuclei.
436 
437 class HOShellModel : public HardCoreModel {
438 
439 public:
440 
441  // Default constructor.
442  HOShellModel(): nucleusChR(), protonChR(), C2() {}
443 
444  // Destructor.
445  virtual ~HOShellModel() {}
446 
447  // Initialize, set up parameters.
448  virtual bool init() override;
449 
450  // Generate a vector of nucleons according to the implemented model
451  // for a nucleus given by the PDG number.
452  virtual vector<Nucleon> generate() const override;
453 
454 protected:
455 
456  // Generate the position of a single nucleon. (The time component
457  // is always zero).
458  virtual Vec4 generateNucleon() const;
459 
460  // The density function.
461  double rho(double r) const {
462  double pref = 4./(pow(sqrt(M_PI * C2),3)) * (1 + (A() - 4.)/6. * r*r/C2);
463  return pref * exp(-r*r / C2);
464  };
465 
466  // Nucleus charge radius.
467  double nucleusChR;
468 
469  // Nucleon charge radius.
470  double protonChR;
471 
472  // C2 parameter.
473  double C2;
474 
475  // Maximum rho for these parameters.
476  double rhoMax;
477 
478 };
479 
480 //==========================================================================
481 
482 // The Hulthen potential for deuterons.
483 
484 class HulthenModel : public NucleusModel {
485 
486 public:
487 
488  // Default constructor.
489  HulthenModel(): hA(), hB() {}
490 
491  // Virtual destructor.
492  virtual ~HulthenModel() {}
493 
494  virtual bool init() override;
495 
496  // Generate a vector of nucleons according to the Hulthen potential.
497  virtual vector<Nucleon> generate() const override;
498 
499 protected:
500 
501  // The (normalized) density function.
502  double rho(double r) const {
503  double pref = (2*hA*hB*(hA + hB))/pow2(hA - hB);
504  double exps = exp(-2.*hA*r) + exp(-2.*hB*r) - 2.*exp(-(hA+hB)*r);
505  return pref * exps;
506  };
507 
508  // Parameters of the Hulthen model.
509  double hA;
510  double hB;
511 
512 };
513 
514 //==========================================================================
515 
516 // A Gaussian distribution for light nuclei.
517 
518 class GaussianModel : public HardCoreModel {
519 
520 public:
521 
522  // Default constructor.
523  GaussianModel(): nucleusChR() {}
524 
525  // Destructor.
526  virtual ~GaussianModel() {}
527 
528  virtual bool init() override;
529 
530  // Generate a vector of nucleons according to the implemented model
531  // for a nucleus given by the PDG number.
532  virtual vector<Nucleon> generate() const override;
533 
534 protected:
535 
536  // Generate the position of a single nucleon. (The time component
537  // is always zero).
538  virtual Vec4 generateNucleon() const;
539 
540  // Nucleus charge radius.
541  double nucleusChR;
542 
543 };
544 
545 //==========================================================================
546 
547 // A model for nuclei clustered in smaller nuclei.
548 
549 class ClusterModel : public HardCoreModel {
550 
551 public:
552 
553  // Contructor.
555 
556  // Virtual destructor.
557  virtual ~ClusterModel() {}
558 
559  // Initialize parameters.
560  virtual bool init() override;
561 
562  // Generate a vector of nucleons. Note that this model
563  // is only implemented for XX, YY ZZ.
564  virtual vector<Nucleon> generate() const override;
565 
566 private:
567 
568  // The model to generate clusters from.
569  unique_ptr<NucleusModel> nModelPtr;
570 
571 };
572 
573 //==========================================================================
574 
575 } // end namespace Pythia8
576 
577 #endif // Pythia8_HINucleusModel_H
Z0 Z(f is quark or lepton).*/ void Sigma1ffbar2gmZZprime
Initialize process.
Definition: SigmaNewGaugeBosons.cc:110
constexpr double pow2(const double &x)
Powers of small integers - for balance speed/code clarity.
Definition: PythiaStdlib.h:175
double rho(double r) const
The (normalized) density function.
Definition: HINucleusModel.h:502
GLISSANDOModel()
Default constructor.
Definition: HINucleusModel.h:422
double nucleusChR
Nucleus charge radius.
Definition: HINucleusModel.h:464
double a() const
Accessor functions.
Definition: HINucleusModel.h:382
Definition: Info.h:45
bool done() const
Check if nucleon has been assigned.
Definition: HINucleusModel.h:70
virtual ~HardCoreModel()
Virtual destructor.
Definition: HINucleusModel.h:333
void reset()
Reset the states and status.
Definition: HINucleusModel.h:109
A general Woods-Saxon distributed nucleus.
Definition: HINucleusModel.h:362
double hA
Parameters of the Hulthen model.
Definition: HINucleusModel.h:506
Definition: HINucleusModel.h:152
double RSave
The estimate of the nucleus radius.
Definition: HINucleusModel.h:258
void overestimates()
Calculate overestimates for sampling.
Definition: HINucleusModel.h:391
vector< Nucleon >::iterator begin()
Iterate over nucleons.
Definition: HINucleusModel.h:177
The Hulthen potential for deuterons.
Definition: HINucleusModel.h:484
void state(const State &s)
Set the physical state.
Definition: HINucleusModel.h:90
HardCoreModel()
Default constructor.
Definition: HINucleusModel.h:330
vector< double > State
The state of a nucleon is a general vector of doubles.
Definition: HINucleusModel.h:41
bool gaussHardCore
Use a Gaussian hard core.
Definition: HINucleusModel.h:351
virtual ~HOShellModel()
Destructor.
Definition: HINucleusModel.h:445
const Vec4 & bPos() const
The absolute position in impact parameter space.
Definition: HINucleusModel.h:61
Definition: HINucleusModel.h:28
Definition: HINucleusModel.h:198
const Vec4 & nPos() const
The position of this nucleon relative to the nucleus center.
Definition: HINucleusModel.h:58
GaussianModel()
Default constructor.
Definition: HINucleusModel.h:523
int index() const
The index of the nucleon in the nucleus.
Definition: HINucleusModel.h:55
Definition: Logger.h:23
double protonChR
Nucleon charge radius.
Definition: HINucleusModel.h:470
virtual void setPN(const Vec4 &pNIn)
Set (new) nucleon 4-momentum.
Definition: HINucleusModel.h:222
const State & altState(int i=0)
Return an alternative state.
Definition: HINucleusModel.h:79
EventInfo * event() const
The event this nucleon is assigned to.
Definition: HINucleusModel.h:73
Definition: HINucleusModel.h:417
Nucleus(vector< Nucleon > nucleons, Vec4 bPos)
Constructor with nucleons and impact parameter.
Definition: HINucleusModel.h:160
HOShellModel()
Default constructor.
Definition: HINucleusModel.h:442
bool useHardCore
Use the hard core or not.
Definition: HINucleusModel.h:348
A Gaussian distribution for light nuclei.
Definition: HINucleusModel.h:518
Definition: Basics.h:393
Nucleus & reposition(const Vec4 &bPosNew)
Move the nucleus around in impact parameter space.
Definition: HINucleusModel.h:169
The nucleon is not wounded.
Definition: HINucleusModel.h:35
bool isProj
Projectile or target.
Definition: HINucleusModel.h:249
A Harmonic-Oscillator Shell model for light nuclei.
Definition: HINucleusModel.h:437
double rho(double r) const
The density function.
Definition: HINucleusModel.h:461
The nucleon is diffractively wounded.
Definition: HINucleusModel.h:37
double aSave
The nucleus radius, skin depth parameter, and hard core nucleon radius.
Definition: HINucleusModel.h:401
virtual void setMN(double mNIn)
Set (new) effective nucleon mass.
Definition: HINucleusModel.h:225
The nucleon is elastically scattered.
Definition: HINucleusModel.h:36
double hardCoreRadius
The radius or width of the hard core.
Definition: HINucleusModel.h:354
Info * infoPtr
Pointers to useful objects.
Definition: HINucleusModel.h:277
int idSave
The nucleus.
Definition: HINucleusModel.h:252
int id() const
Accessor functions:
Definition: HINucleusModel.h:52
Definition: Event.h:32
ExternalNucleusModel()
Default constructor.
Definition: HINucleusModel.h:294
void debug()
Print out debugging information.
Definition: HINucleusModel.cc:23
int ISave
Cache information about the nucleus.
Definition: HINucleusModel.h:255
virtual ~GaussianModel()
Destructor.
Definition: HINucleusModel.h:526
void select()
Select this nucleon to be assigned to an event.
Definition: HINucleusModel.h:103
Status
Enum for specifying the status of a nucleon.
Definition: HINucleusModel.h:33
Class for storing Events and Info objects.
Definition: HIBasics.h:25
int id() const
Accessor functions.
Definition: HINucleusModel.h:235
void select(EventInfo &evp, Nucleon::Status s)
Select an event for this nucleon.
Definition: HINucleusModel.h:96
virtual ~NucleusModel()
Virtual destructor.
Definition: HINucleusModel.h:209
Definition: HINucleusModel.h:289
double rSample() const
Definition: HINucleusModel.h:341
Nucleon::Status status() const
The status of the nucleon.
Definition: HINucleusModel.h:67
WoodsSaxonModel()
Definition: HINucleusModel.h:371
void bShift(const Vec4 &bvec)
Shift the absolute position in impact parameter space.
Definition: HINucleusModel.h:64
NucleusModel()
Definition: HINucleusModel.h:204
void addAltState(const State &s)
Add an alternative state.
Definition: HINucleusModel.h:93
HulthenModel()
Default constructor.
Definition: HINucleusModel.h:489
double rhoMax
Maximum rho for these parameters.
Definition: HINucleusModel.h:476
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
const State & state() const
The physical state of the incoming nucleon.
Definition: HINucleusModel.h:76
void status(Nucleon::Status s)
Manipulating functions:
Definition: HINucleusModel.h:87
Nucleon(int idIn=0, int indexIn=0, const Vec4 &pos=Vec4())
Definition: HINucleusModel.h:45
virtual ~HulthenModel()
Virtual destructor.
Definition: HINucleusModel.h:492
double nucleusChR
Nucleus charge radius.
Definition: HINucleusModel.h:541
A model for nuclei clustered in smaller nuclei.
Definition: HINucleusModel.h:549
double C2
C2 parameter.
Definition: HINucleusModel.h:473
Definition: HINucleusModel.h:325
virtual ~GLISSANDOModel()
Virtual destructor.
Definition: HINucleusModel.h:425
Definition: Basics.h:32
virtual ~WoodsSaxonModel()
Virtual destructor.
Definition: HINucleusModel.h:367
virtual ~ClusterModel()
Virtual destructor.
Definition: HINucleusModel.h:557
Definition: Settings.h:196
ClusterModel()
Contructor.
Definition: HINucleusModel.h:554