16 #include "gsl/gsl_integration.h" 
   17 #include "gsl/gsl_multiroots.h" 
   36                                             double effective_chemical_potential,
 
   38   const double Ekin = std::sqrt(
p * 
p + mass * mass);
 
   40       2 * (1 + statistics * std::exp(-(Ekin - effective_chemical_potential) /
 
   42   const double term2 = (
p * 
p) / (temperature * Ekin);
 
   49                                                  gsl_vector *
function) {
 
   53   const double mass = (par->
mass);
 
   55   const double effective_chemical_potential =
 
   59   const double p_radial = gsl_vector_get(roots_array, 0);
 
   61   gsl_vector_set(
function, 0,
 
   63                                      effective_chemical_potential, statistics));
 
   69                                         gsl_multiroot_fsolver *solver) {
 
   71       "\n***\nfind_p_at_maximum_of_the_distribution(): iter = %3u \t" 
   74       iter, gsl_vector_get(solver->x, 0), gsl_vector_get(solver->f, 0));
 
   78     double mass, 
double temperature, 
double effective_chemical_potential,
 
   79     double statistics, 
double p_max_initial_guess, 
double solution_precision,
 
   81   const gsl_multiroot_fsolver_type *Solver_name;
 
   82   gsl_multiroot_fsolver *Root_finder;
 
   86   size_t initial_guess_update = 0;
 
   88   const size_t problem_dimension = 1;
 
   91       mass, temperature, effective_chemical_potential, statistics};
 
   93   gsl_multiroot_function MaximumOfDistribution = {
 
   96   double roots_array_initial[1] = {p_max_initial_guess};
 
   98   gsl_vector *roots_array = gsl_vector_alloc(problem_dimension);
 
   99   gsl_vector_set(roots_array, 0, roots_array_initial[0]);
 
  101   Solver_name = gsl_multiroot_fsolver_hybrids;
 
  102   Root_finder = gsl_multiroot_fsolver_alloc(Solver_name, problem_dimension);
 
  103   gsl_multiroot_fsolver_set(Root_finder, &MaximumOfDistribution, roots_array);
 
  114     status = gsl_multiroot_fsolver_iterate(Root_finder);
 
  122       if (initial_guess_update < 100) {
 
  130         p_max_initial_guess += 0.05;
 
  131         initial_guess_update++;
 
  132         roots_array_initial[0] = p_max_initial_guess;
 
  133         gsl_vector_set(roots_array, 0, roots_array_initial[0]);
 
  134         gsl_multiroot_fsolver_set(Root_finder, &MaximumOfDistribution,
 
  138         std::cout << 
"\n\nGSL error message:\n" 
  139                   << gsl_strerror(status) << std::endl;
 
  140         logg[LogArea::Distributions::id].warn(
 
  142             "\nfind_p_at_maximum_of_the_distribution\nis stuck!" 
  143             "\n\nInput parameters:" 
  145             mass, 
"\n           temperature [GeV] = ", temperature,
 
  146             "\neffective_chemical_potential = ", effective_chemical_potential,
 
  147             "\n                  statistics = ", statistics,
 
  148             "\n          solution_precision = ", solution_precision,
 
  150             "Initialization cannot sample the momenta without " 
  151             "calculating the distribution maximum." 
  152             "\nTry adjusting the initial guess (which is " 
  153             "looped over in the GSL procedure) or the " 
  154             "solution precision." 
  155             "\nUncomment print_state_p_max to check solver progress.\n\n\n");
 
  156         throw std::runtime_error(
 
  157             "QuantumSampling::find_p_at_maximum_of_the_distribution returned " 
  163     status = gsl_multiroot_test_residual(Root_finder->f, solution_precision);
 
  165     if (status == GSL_SUCCESS) {
 
  166       p_max[0] = gsl_vector_get(Root_finder->x, 0);
 
  168   } 
while (status == GSL_CONTINUE && iter < 100000);
 
  170   gsl_multiroot_fsolver_free(Root_finder);
 
  171   gsl_vector_free(roots_array);
 
  177     double mass, 
double temperature, 
double effective_chemical_potential,
 
  178     double statistics, 
double solution_precision) {
 
  190   double initial_guess_p_max = 0.050;
 
  196       mass, temperature, effective_chemical_potential, statistics,
 
  197       initial_guess_p_max, solution_precision, p_max);
 
  199   double distribution_function_maximum =
 
  200       p_max[0] * p_max[0] *
 
  202                                 effective_chemical_potential, statistics);
 
  204   return distribution_function_maximum;
 
  212     const std::map<PdgCode, int> &initial_multiplicities, 
double volume,
 
  214     : volume_(volume), temperature_(temperature) {
 
  220   constexpr 
double solution_precision = 1e-8;
 
  222   for (
const auto &pdg_and_mult : initial_multiplicities) {
 
  223     const PdgCode pdg = pdg_and_mult.first;
 
  224     const int number_of_particles = pdg_and_mult.second;
 
  226     const double number_density = number_of_particles / V_in_GeV;
 
  229     const double quantum_statistics = (pdg.
spin() % 2 == 0) ? -1.0 : 1.0;
 
  231     const double particle_mass = ptype.
mass();
 
  232     double chemical_potential = 0.0;
 
  236         spin_degeneracy, particle_mass, number_density, 
temperature_,
 
  237         quantum_statistics, solution_precision);
 
  240         particle_mass, 
temperature_, chemical_potential, quantum_statistics,
 
  259   const double mass = ptype.
mass();
 
  266   constexpr 
double maximum_momentum = 10.0;  
 
  267   const double statistics = (pdg.
spin() % 2 == 0) ? -1.0 : 1.0;
 
  268   double sampled_momentum = 0.0, sampled_ratio = 0.0;
 
  272     double distribution_at_sampled_p =
 
  273         sampled_momentum * sampled_momentum *
 
  276     sampled_ratio = distribution_at_sampled_p / distr_max;
 
  279   return sampled_momentum;
 
A class which encapsulates a GSL algorithm for finding the effective chemical potential and supportin...
double effective_chemical_potential(double degeneracy, double mass, double number_density, double temperature, double statistics, double solution_precision)
Convenience wrapper for finding the effective chemical potential for a given particle species and per...
Particle type contains the static properties of a particle species.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
unsigned int spin() const
unsigned int spin_degeneracy() const
QuantumSampling(const std::map< PdgCode, int > &initial_multiplicities, double volume, double temperature)
Constructor of a QuantumSampling object.
static double p_max_root_equation(double p, double mass, double temperature, double effective_chemical_potential, double statistics)
Root equation for finding the radial momentum at which the Juttner distribution function has its maxi...
const double temperature_
Temperature [GeV].
static int find_p_at_maximum_of_the_distribution(double mass, double temperature, double effective_chemical_potential, double statistics, double p_max_initial_guess, double solution_precision, double *p_max)
A GSL root solver for finding the radial momentum value at which the maximum of the given Juttner dis...
std::map< PdgCode, double > distribution_function_maximums_
Tabulated distribution function maxima for every particle species.
static double maximum_of_the_distribution(double mass, double temperature, double effective_chemical_potential, double statistics, double solution_precision)
A convenience wrapper for finding the maximum value of the Juttner distribution, returning the value ...
std::map< PdgCode, double > effective_chemical_potentials_
Tabulated effective chemical potentials for every particle species.
const double volume_
Volume [fm^3] in which particles sre sampled.
static void print_state_p_max(unsigned int iter, gsl_multiroot_fsolver *solver)
A GSL utility which allows for printing out the status of the solver during the root finding procedur...
static int p_max_root_equation_for_GSL(const gsl_vector *roots_array, void *parameters, gsl_vector *function)
Root equation for finding the radial momentum at which the Juttner distribution function has its maxi...
double sample(const PdgCode pdg)
Sampling radial momenta of given particle species from Boltzmann, Bose, or Fermi distribution.
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
double juttner_distribution_func(double momentum_radial, double mass, double temperature, double effective_chemical_potential, double statistics)
Relativistic Juttner distribution function is just a convenience wrapper for displaying Fermi,...
constexpr double hbarc
GeV <-> fm conversion factor.