Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nucleon.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file nucleon.h
1 // TRENTO: Reduced Thickness Event-by-event Nuclear Topology
2 // Copyright 2015 Jonah E. Bernhard, J. Scott Moreland
3 // TRENTO3D: Three-dimensional extension of TRENTO by Weiyao Ke
4 // MIT License
5 
6 #ifndef NUCLEON_H
7 #define NUCLEON_H
8 
9 #include <boost/math/constants/constants.hpp>
10 
11 #include "fast_exp.h"
12 #include "fwd_decl.h"
13 #include "random.h"
14 
15 namespace trento {
16 
17 class Nucleon;
18 
25  public:
27  explicit NucleonProfile(const VarMap& var_map);
28 
30  double radius() const;
31 
33  double max_impact() const;
34 
37  void fluctuate();
38 
41  double thickness(double distance_sqr) const;
42 
45  double deterministic_thickness(double distance_sqr) const;
46 
48  double norm_Tpp(double bpp_sqr) const;
49 
51  bool participate(Nucleon& A, Nucleon& B) const;
52 
53  private:
55  const double width_sqr_;
56 
58  const double trunc_radius_sqr_;
59 
61  const double max_impact_sqr_;
62 
66 
69 
71  const double one_div_four_pi_;
72 
75  const double cross_sec_param_;
76 
79 
81  std::gamma_distribution<double> fluct_dist_;
82 
84  double prefactor_;
85 
88 };
89 
95 class Nucleon {
96  public:
99  Nucleon() = default;
100 
102  double x() const;
103 
105  double y() const;
106 
108  double z() const;
109 
111  bool is_participant() const;
112 
113  private:
115  friend class Nucleus;
116 
119  friend bool NucleonProfile::participate(Nucleon&, Nucleon&) const;
120 
122  void set_position(double x, double y, double z);
123 
125  void set_participant();
126 
128  double x_, y_, z_;
129 
132 };
133 
134 // These functions are short, called very often, and account for a large
135 // fraction of the total computation time, so request inlining.
136 
137 // Nucleon inline member functions
138 
139 inline double Nucleon::x() const {
140  return x_;
141 }
142 
143 inline double Nucleon::y() const {
144  return y_;
145 }
146 
147 inline double Nucleon::z() const {
148  return z_;
149 }
150 
151 inline bool Nucleon::is_participant() const {
152  return participant_;
153 }
154 
155 inline void Nucleon::set_position(double x, double y, double z) {
156  x_ = x;
157  y_ = y;
158  z_ = z;
159  participant_ = false;
160 }
161 
163  participant_ = true;
164 }
165 
166 // NucleonProfile inline member functions
167 
168 inline double NucleonProfile::radius() const {
169  return std::sqrt(trunc_radius_sqr_);
170 }
171 
172 inline double NucleonProfile::max_impact() const {
173  return std::sqrt(max_impact_sqr_);
174 }
175 
178  math::double_constants::one_div_two_pi / width_sqr_;
179 }
180 
181 inline double NucleonProfile::thickness(double distance_sqr) const {
182  if (distance_sqr > trunc_radius_sqr_)
183  return 0.;
184  return prefactor_ * fast_exp_(neg_one_div_two_width_sqr_*distance_sqr);
185 }
186 
187 // WK
188 inline double NucleonProfile::deterministic_thickness(double distance_sqr) const {
189  if (distance_sqr > trunc_radius_sqr_)
190  return 0.;
191  return math::double_constants::one_div_two_pi / width_sqr_
192  * fast_exp_(neg_one_div_two_width_sqr_*distance_sqr);
193 }
194 
195 // WK
196 inline double NucleonProfile::norm_Tpp(double bpp_sqr) const {
197  return one_div_four_pi_ / width_sqr_
199 }
200 
201 inline bool NucleonProfile::participate(Nucleon& A, Nucleon& B) const {
202  // If both nucleons are already participants, there's nothing to do, unless
203  // in Ncoll mode
204  if (A.is_participant() && B.is_participant() && (! with_ncoll_))
205  return true;
206 
207  double dx = A.x() - B.x();
208  double dy = A.y() - B.y();
209  double distance_sqr = dx*dx + dy*dy;
210 
211  // Check if nucleons are out of range.
212  if (distance_sqr > max_impact_sqr_)
213  return false;
214 
215  // The probability is
216  // P = 1 - exp(...)
217  // which we could sample as
218  // P > U
219  // where U is a standard uniform (0, 1) random number. We can also compute
220  // 1 - P = exp(...)
221  // and then sample
222  // (1 - P) > (1 - U)
223  // or equivalently
224  // (1 - P) < U
225  auto one_minus_prob = std::exp(
226  -std::exp(cross_sec_param_ - .25*distance_sqr/width_sqr_));
227 
228  // Sample one random number and decide if this pair participates.
229  if (one_minus_prob < random::canonical<double>()) {
230  A.set_participant();
231  B.set_participant();
232  return true;
233  }
234 
235  return false;
236 }
237 
238 } // namespace trento
239 
240 #endif // NUCLEON_H