13 #include <boost/math/constants/constants.hpp>
14 #include <boost/math/special_functions/expint.hpp>
15 #include <boost/math/tools/roots.hpp>
16 #include <boost/program_options/variables_map.hpp>
28 template <
typename RealType>
using param_type =
29 typename std::gamma_distribution<RealType>::param_type;
31 template <
typename RealType>
32 param_type<RealType> gamma_param_unit_mean(RealType
alpha = 1.) {
40 constexpr
double trunc_radius_widths = 5.;
43 constexpr
double max_impact_widths = 6.;
53 double cross_sec_from_energy(
double sqrts) {
58 return a +
b * pow(std::log(sqrts) -
c, d);
63 double compute_cross_sec_param(
const VarMap& var_map) {
68 auto sigma_nn = var_map[
"cross-section"].as<
double>();
70 sigma_nn = cross_sec_from_energy(var_map[
"beam-energy"].as<double>());
72 auto width = var_map[
"nucleon-width"].as<
double>();
82 math::tools::eps_tolerance<double> tol{
83 (std::numeric_limits<double>::digits * 3) / 4};
88 boost::uintmax_t max_iter = 1000;
94 auto c = sqr(max_impact_widths) / 4;
97 auto result = math::tools::toms748_solve(
98 [&
rhs, &
c](
double x) {
101 return c - expint(-exp(x)) + expint(-exp(x-
c)) -
rhs;
103 a,
b, tol, max_iter);
105 return .5*(result.first + result.second);
107 catch (
const std::domain_error&) {
109 throw std::domain_error{
110 "unable to fit cross section -- nucleon width too small?"};
117 : width_sqr_(sqr(var_map[
"nucleon-width"].as<
double>())),
118 trunc_radius_sqr_(sqr(trunc_radius_widths)*width_sqr_),
119 max_impact_sqr_(sqr(max_impact_widths)*width_sqr_),
120 neg_one_div_two_width_sqr_(-.5/width_sqr_),
121 neg_one_div_four_width_sqr_(-.25/width_sqr_),
122 one_div_four_pi_(0.5*math::double_constants::one_div_two_pi),
123 cross_sec_param_(compute_cross_sec_param(var_map)),
124 fast_exp_(-.5*sqr(trunc_radius_widths), 0., 1000),
125 fluct_dist_(gamma_param_unit_mean(var_map[
"fluctuation"].as<
double>())),
126 prefactor_(math::double_constants::one_div_two_pi/width_sqr_),
127 with_ncoll_(var_map[
"ncoll"].as<bool>())