File indexing completed on 2025-08-05 08:19:07
0001
0002
0003
0004
0005
0006 #ifndef NUCLEON_H
0007 #define NUCLEON_H
0008
0009 #include <boost/math/constants/constants.hpp>
0010
0011 #include "fast_exp.h"
0012 #include "fwd_decl.h"
0013 #include "random.h"
0014
0015 namespace trento {
0016
0017 class Nucleon;
0018
0019
0020
0021
0022
0023
0024 class NucleonProfile {
0025 public:
0026
0027 explicit NucleonProfile(const VarMap& var_map);
0028
0029
0030 double radius() const;
0031
0032
0033 double max_impact() const;
0034
0035
0036
0037 void fluctuate();
0038
0039
0040
0041 double thickness(double distance_sqr) const;
0042
0043
0044
0045 double deterministic_thickness(double distance_sqr) const;
0046
0047
0048 double norm_Tpp(double bpp_sqr) const;
0049
0050
0051 bool participate(Nucleon& A, Nucleon& B) const;
0052
0053 private:
0054
0055 const double width_sqr_;
0056
0057
0058 const double trunc_radius_sqr_;
0059
0060
0061 const double max_impact_sqr_;
0062
0063
0064
0065 const double neg_one_div_two_width_sqr_;
0066
0067
0068 const double neg_one_div_four_width_sqr_;
0069
0070
0071 const double one_div_four_pi_;
0072
0073
0074
0075 const double cross_sec_param_;
0076
0077
0078 const FastExp<double> fast_exp_;
0079
0080
0081 std::gamma_distribution<double> fluct_dist_;
0082
0083
0084 double prefactor_;
0085
0086
0087 bool with_ncoll_;
0088 };
0089
0090
0091
0092
0093
0094
0095 class Nucleon {
0096 public:
0097
0098
0099 Nucleon() = default;
0100
0101
0102 double x() const;
0103
0104
0105 double y() const;
0106
0107
0108 double z() const;
0109
0110
0111 bool is_participant() const;
0112
0113 private:
0114
0115 friend class Nucleus;
0116
0117
0118
0119 friend bool NucleonProfile::participate(Nucleon&, Nucleon&) const;
0120
0121
0122 void set_position(double x, double y, double z);
0123
0124
0125 void set_participant();
0126
0127
0128 double x_, y_, z_;
0129
0130
0131 bool participant_;
0132 };
0133
0134
0135
0136
0137
0138
0139 inline double Nucleon::x() const {
0140 return x_;
0141 }
0142
0143 inline double Nucleon::y() const {
0144 return y_;
0145 }
0146
0147 inline double Nucleon::z() const {
0148 return z_;
0149 }
0150
0151 inline bool Nucleon::is_participant() const {
0152 return participant_;
0153 }
0154
0155 inline void Nucleon::set_position(double x, double y, double z) {
0156 x_ = x;
0157 y_ = y;
0158 z_ = z;
0159 participant_ = false;
0160 }
0161
0162 inline void Nucleon::set_participant() {
0163 participant_ = true;
0164 }
0165
0166
0167
0168 inline double NucleonProfile::radius() const {
0169 return std::sqrt(trunc_radius_sqr_);
0170 }
0171
0172 inline double NucleonProfile::max_impact() const {
0173 return std::sqrt(max_impact_sqr_);
0174 }
0175
0176 inline void NucleonProfile::fluctuate() {
0177 prefactor_ = fluct_dist_(random::engine) *
0178 math::double_constants::one_div_two_pi / width_sqr_;
0179 }
0180
0181 inline double NucleonProfile::thickness(double distance_sqr) const {
0182 if (distance_sqr > trunc_radius_sqr_)
0183 return 0.;
0184 return prefactor_ * fast_exp_(neg_one_div_two_width_sqr_*distance_sqr);
0185 }
0186
0187
0188 inline double NucleonProfile::deterministic_thickness(double distance_sqr) const {
0189 if (distance_sqr > trunc_radius_sqr_)
0190 return 0.;
0191 return math::double_constants::one_div_two_pi / width_sqr_
0192 * fast_exp_(neg_one_div_two_width_sqr_*distance_sqr);
0193 }
0194
0195
0196 inline double NucleonProfile::norm_Tpp(double bpp_sqr) const {
0197 return one_div_four_pi_ / width_sqr_
0198 * fast_exp_(neg_one_div_four_width_sqr_*bpp_sqr);
0199 }
0200
0201 inline bool NucleonProfile::participate(Nucleon& A, Nucleon& B) const {
0202
0203
0204 if (A.is_participant() && B.is_participant() && (! with_ncoll_))
0205 return true;
0206
0207 double dx = A.x() - B.x();
0208 double dy = A.y() - B.y();
0209 double distance_sqr = dx*dx + dy*dy;
0210
0211
0212 if (distance_sqr > max_impact_sqr_)
0213 return false;
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 auto one_minus_prob = std::exp(
0226 -std::exp(cross_sec_param_ - .25*distance_sqr/width_sqr_));
0227
0228
0229 if (one_minus_prob < random::canonical<double>()) {
0230 A.set_participant();
0231 B.set_participant();
0232 return true;
0233 }
0234
0235 return false;
0236 }
0237
0238 }
0239
0240 #endif