 |
Version: SMASH-1.8
|
|
Go to the documentation of this file.
43 const int max_iter = 50;
45 double e_previous_step = 0.0;
46 const double tolerance = 5.e-4;
48 for (iter = 0; iter < max_iter; iter++) {
51 if (std::abs(
e_ - e_previous_step) < tolerance) {
54 const double gamma_inv = std::sqrt(1.0 -
v_.
sqr());
71 if (iter == max_iter) {
72 std::cout <<
"Warning from solver: max iterations exceeded."
73 <<
" Accuracy: " << std::abs(
e_ - e_previous_step)
74 <<
" is less than tolerance " << tolerance << std::endl;
92 return out <<
"T[mu,0]: " << node.
Tmu0() <<
", nb: " << node.
nb()
93 <<
", ns: " << node.
ns() <<
", v: " << node.
v()
94 <<
", e: " << node.
e() <<
", p: " << node.
p()
95 <<
", T: " << node.
T() <<
", mub: " << node.
mub()
96 <<
", mus: " << node.
mus();
100 const std::array<int, 3> n_cells,
101 const std::array<double, 3> origin,
102 bool periodicity,
double e_critical,
103 double t_start,
double delta_t,
105 bool BF_microcanonical)
106 : eos_typelist_(list_eos_particles()),
107 N_sorts_(eos_typelist_.size()),
112 BF_enforce_microcanonical_(BF_microcanonical) {
114 lat_ = make_unique<RectangularLattice<ThermLatticeNode>>(
115 lat_sizes, n_cells, origin, periodicity, upd);
116 const std::array<double, 3> abc =
lat_->cell_sizes();
125 bool ignore_cells_under_treshold) {
129 for (
auto &node : *
lat_) {
133 if (!ignore_cells_under_treshold ||
134 node.Tmu0().x0() + std::abs(node.Tmu0().x1()) +
135 std::abs(node.Tmu0().x2()) + std::abs(node.Tmu0().x3()) >=
137 node.compute_rest_frame_quantities(
eos_);
146 +0.5 *
lat_->cell_sizes()[0]),
148 +0.5 *
lat_->cell_sizes()[1]),
150 +0.5 *
lat_->cell_sizes()[2]));
154 ParticleList &plist,
const FourVector required_total_momentum) {
158 required_total_momentum);
164 for (
auto &particle : plist) {
165 particle.set_4momentum(particle.type().mass(),
166 particle.momentum().threevec() + mom_to_add);
175 double E_expected = required_total_momentum.
abs();
176 for (
auto &particle : plist) {
177 particle.boost_momentum(beta_CM_generated);
178 E += particle.momentum().x0();
182 double a, a_min, a_max, er;
183 const int max_iter = 100;
185 if (E_expected >= E) {
193 a = 0.5 * (a_min + a_max);
195 for (
const auto &particle : plist) {
196 const double p2 = particle.momentum().threevec().sqr();
197 const double E2 = particle.momentum().x0() * particle.momentum().x0();
198 E += std::sqrt(E2 + a * (a + 2.0) * p2);
209 }
while (std::abs(er) > tolerance && iter < max_iter);
213 for (
auto &particle : plist) {
214 particle.set_4momentum(particle.type().mass(),
215 (1 + a) * particle.momentum().threevec());
216 particle.boost_momentum(-beta_CM_required);
227 for (
size_t i_type = 0; (i_type <
N_sorts_) && (N_to_sample > 0); i_type++) {
228 if (
get_class(i_type) != particle_class) {
252 const double gamma = 1.0 / std::sqrt(1.0 - cell.
v().
sqr());
253 const double N_this_cell =
261 for (
int i = 0; i <
mult_int_[type_index]; i++) {
264 double partial_sum = 0.0;
265 int index_only_thermalized = -1;
266 while (partial_sum < r) {
267 index_only_thermalized++;
268 partial_sum +=
N_in_cells_[index_only_thermalized];
283 particle.
set_4momentum(m, phitheta.threevec() * momentum_radial);
287 plist.push_back(particle);
292 double time,
int ntest) {
296 const double gamma = 1.0 / std::sqrt(1.0 - cell.
v().
sqr());
297 for (
size_t i = 0; i <
N_sorts_; i++) {
306 for (
size_t i = 0; i <
N_sorts_; i++) {
317 const auto Nbar_antibar = bessel_sampler_B.sample();
324 for (
size_t i = 0; i <
N_sorts_; i++) {
328 std::pair<int, int> NS_antiS;
334 NS_antiS = bessel_sampler_S.
sample();
336 NS_antiS = std::make_pair(
339 if (NS_antiS.first - NS_antiS.second !=
349 for (
size_t i = 0; i <
N_sorts_; i++) {
353 std::pair<int, int> NC_antiC;
358 conserved_initial.
charge() - ch_sampled);
359 NC_antiC = bessel_sampler_C.
sample();
361 NC_antiC = std::make_pair(
364 if (NC_antiC.first - NC_antiC.second !=
365 conserved_initial.
charge() - ch_sampled) {
376 for (
size_t itype = 0; itype <
N_sorts_; itype++) {
381 const double e_init = conserved_initial.
momentum().
x0();
384 e_tot += particle.momentum().x0();
386 if (std::abs(e_tot - e_init) > 0.01 * e_init) {
388 " too far from ", e_init);
399 int S_plus = 0, S_minus = 0, B_plus = 0, B_minus = 0, E_plus = 0, E_minus = 0;
401 auto condition1 = [](int, int, int) {
return true; };
403 while (conserved_initial.
momentum().
x0() > energy ||
406 energy +=
p.momentum().x0();
407 if (
p.pdgcode().strangeness() > 0) {
409 S_plus +=
p.pdgcode().strangeness();
414 auto condition2 = [](
int S, int, int) {
return (
S < 0); };
416 while (S_plus + S_minus > conserved_initial.
strangeness()) {
418 const int s_part =
p.pdgcode().strangeness();
420 if (S_plus + S_minus + s_part >= conserved_initial.
strangeness()) {
427 auto condition3 = [](
int S, int, int) {
return (
S == 0); };
432 while (conserved_remaining.
momentum().
x0() > energy ||
435 energy +=
p.momentum().x0();
436 if (
p.pdgcode().baryon_number() > 0) {
438 B_plus +=
p.pdgcode().baryon_number();
443 auto condition4 = [](
int S,
int B, int) {
return (
S == 0) && (B < 0); };
445 while (B_plus + B_minus > conserved_remaining.
baryon_number()) {
447 const int bar =
p.pdgcode().baryon_number();
448 if (B_plus + B_minus + bar >= conserved_remaining.
baryon_number()) {
455 auto condition5 = [](
int S,
int B, int) {
return (
S == 0) && (B == 0); };
459 while (conserved_remaining.
momentum().
x0() > energy ||
460 E_plus < conserved_remaining.
charge()) {
462 energy +=
p.momentum().x0();
463 if (
p.pdgcode().charge() > 0) {
465 E_plus +=
p.pdgcode().charge();
470 auto condition6 = [](
int S,
int B,
int C) {
471 return (
S == 0) && (B == 0) && (C < 0);
474 while (E_plus + E_minus > conserved_remaining.
charge()) {
476 const int charge =
p.pdgcode().charge();
477 if (E_plus + E_minus + charge >= conserved_remaining.
charge()) {
484 auto condition7 = [](
int S,
int B,
int C) {
485 return (
S == 0) && (B == 0) && (C == 0);
490 while (conserved_remaining.
momentum().
x0() > energy) {
493 energy +=
p.momentum().x0();
507 for (
auto &particle : particles) {
508 const bool is_on_lattice =
509 lat_->value_at(particle.position().threevec(), node);
510 if (is_on_lattice && node.
e() >
e_crit_) {
532 const size_t lattice_total_cells =
lat_->size();
533 for (
size_t i = 0; i < lattice_total_cells; i++) {
539 "Number of cells in the thermalization region = ",
542 ", in % of lattice: ",
554 throw std::invalid_argument(
555 "This thermalization algorithm is"
556 " not yet implemented");
573 struct to_average on_lattice = {0.0, 0.0, 0.0, 0.0, 0.0};
574 struct to_average in_therm_reg = {0.0, 0.0, 0.0, 0.0, 0.0};
575 double e_sum_on_lattice = 0.0, e_sum_in_therm_reg = 0.0;
576 int node_counter = 0;
577 for (
const auto &node : *
lat_) {
578 const double e = node.e();
579 on_lattice.T += node.T() * e;
580 on_lattice.mub += node.mub() * e;
581 on_lattice.mus += node.mus() * e;
582 on_lattice.nb += node.nb() * e;
583 on_lattice.ns += node.ns() * e;
584 e_sum_on_lattice += e;
586 in_therm_reg.T += node.T() * e;
587 in_therm_reg.mub += node.mub() * e;
588 in_therm_reg.mus += node.mus() * e;
589 in_therm_reg.nb += node.nb() * e;
590 in_therm_reg.ns += node.ns() * e;
591 e_sum_in_therm_reg += e;
596 on_lattice.T /= e_sum_on_lattice;
597 on_lattice.mub /= e_sum_on_lattice;
598 on_lattice.mus /= e_sum_on_lattice;
599 on_lattice.nb /= e_sum_on_lattice;
600 on_lattice.ns /= e_sum_on_lattice;
603 in_therm_reg.T /= e_sum_in_therm_reg;
604 in_therm_reg.mub /= e_sum_in_therm_reg;
605 in_therm_reg.mus /= e_sum_in_therm_reg;
606 in_therm_reg.nb /= e_sum_in_therm_reg;
607 in_therm_reg.ns /= e_sum_in_therm_reg;
610 std::cout <<
"Current time [fm/c]: " << clock.
current_time() << std::endl;
611 std::cout <<
"Averages on the lattice - T[GeV], mub[GeV], mus[GeV], "
612 <<
"nb[fm^-3], ns[fm^-3]: " << on_lattice.T <<
" " << on_lattice.mub
613 <<
" " << on_lattice.mus <<
" " << on_lattice.nb <<
" "
614 << on_lattice.ns << std::endl;
615 std::cout <<
"Averages in therm. region - T[GeV], mub[GeV], mus[GeV], "
616 <<
"nb[fm^-3], ns[fm^-3]: " << in_therm_reg.T <<
" "
617 << in_therm_reg.mub <<
" " << in_therm_reg.mus <<
" "
618 << in_therm_reg.nb <<
" " << in_therm_reg.ns << std::endl;
619 std::cout <<
"Volume with e > e_crit [fm^3]: " <<
cell_volume_ * node_counter
Class to handle the equation of state (EoS) of the hadron gas, consisting of all hadrons included int...
LatticeUpdate
Enumerator option for lattice updates.
double p() const
Get pressure in the rest frame.
void sample_multinomial(HadronClass particle_class, int N)
The sample_multinomial function samples integer numbers n_i distributed according to the multinomial ...
GrandCanThermalizer(const std::array< double, 3 > lat_sizes, const std::array< int, 3 > n_cells, const std::array< double, 3 > origin, bool periodicity, double e_critical, double t_start, double delta_t, ThermalizationAlgorithm algo, bool BF_microcanonical)
Default constructor for the GranCanThermalizer to allocate the lattice.
FourVector momentum() const
std::array< double, 3 > solve_eos(double e, double nb, double ns, std::array< double, 3 > initial_approximation)
Compute temperature and chemical potentials given energy-, net baryon-, net strangeness density and a...
double cell_volume_
Volume of a single cell, necessary to convert thermal densities to actual particle numbers.
double mub_
Net baryon chemical potential.
void from_table(EosTable::table_element &res, double e, double nb) const
Get the element of eos table.
const FourVector & momentum() const
Get the particle's 4-momentum.
A class to pre-calculate and store parameters relevant for density calculation.
double ns() const
Get net strangeness density of the cell in the computational frame.
Mesons with strangeness S < 0.
ThermLatticeNode()
Default constructor of thermal quantities on the lattice returning thermodynamic quantities in comput...
static double partial_density(const ParticleType &ptype, double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute partial density of one hadron sort.
static double net_strange_density(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute net strangeness density.
FourVector Tmu0_
Four-momentum flow of the cell.
ThreeVector v() const
Get 3-velocity of the rest frame.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
const size_t N_sorts_
Number of different species to be sampled.
The intention of this class is to efficiently sample from the Bessel distribution ,...
Non-strange mesons (S = 0) with electric cherge Q < 0.
void distribute_isotropically()
Populate the object with a new direction.
const ThermalizationAlgorithm algorithm_
Algorithm to choose for sampling of particles obeying conservation laws.
void add_values(const ParticleData &p)
Add the quantum numbers of a single particle to the collection.
void thermalize(const Particles &particles, double time, int ntest)
Main thermalize function, that chooses the algorithm to follow (BF or mode sampling).
void thermalize_BF_algo(QuantumNumbers &conserved_initial, double time, int ntest)
Samples particles according to the BF algorithm by making use of the.
void print_statistics(const Clock &clock) const
Generates standard output with information about the thermodynamic properties of the lattice,...
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
constexpr double really_small
Numerical error tolerance.
The ThermLatticeNode class is intended to compute thermodynamical quantities in a cell given a set of...
void compute_rest_frame_quantities(HadronGasEos &eos)
Temperature, chemical potentials and rest frame velocity are calculated given the hadron gas equation...
double e() const
Get energy density in the rest frame.
bool is_tabulated() const
Create an EoS table or not?
ThermalizationAlgorithm
Defines the algorithm used for the forced thermalization.
double T() const
Get the temperature.
double p_
Pressure in the rest frame.
void set_formation_time(const double &form_time)
Set the absolute formation time.
void boost_momentum(const ThreeVector &v)
Apply a Lorentz-boost to only the momentum.
int binomial(const int N, const T &p)
Returns a binomially distributed random number.
void update_lattice(RectangularLattice< T > *lat, const LatticeUpdate update, const DensityType dens_type, const DensityParameters &par, const Particles &particles, const bool compute_gradient=false)
Updates the contents on the lattice.
const bool BF_enforce_microcanonical_
Enforce energy conservation as part of BF sampling algorithm or not.
std::pair< int, int > sample()
Sample two numbers from given Poissonians with a fixed difference.
double N_total_in_cells_
Total number of particles over all cells in thermalization region.
Neutral non-strange mesons.
HadronClass get_class(size_t typelist_index) const
Defines the class of hadrons by quantum numbers.
ThreeVector uniform_in_cell() const
Mesons with strangeness S > 0.
Non-strange mesons (S = 0) with electric cherge Q > 0.
static double net_baryon_density(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute net baryon density.
void set_rest_frame_quantities(double T0, double mub0, double mus0, const ThreeVector v0)
Set all the rest frame quantities to some values, this is useful for testing.
void update_thermalizer_lattice(const Particles &particles, const DensityParameters &par, bool ignore_cells_under_threshold=true)
Compute all the thermodynamical quantities on the lattice from particles.
ThreeVector v_
Velocity of the rest frame.
int poisson(const T &lam)
Returns a Poisson distributed random number.
void renormalize_momenta(ParticleList &plist, const FourVector required_total_momentum)
Changes energy and momenta of the particles in plist to match the required_total_momentum.
Clock tracks the time in the simulation.
ParticleData sample_in_random_cell_mode_algo(const double time, F &&condition)
Samples one particle and the species, cell, momentum and coordinate are chosen from the corresponding...
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Define the data structure for one element of the table.
void compute_N_in_cells_mode_algo(F &&condition)
Computes average number of particles in each cell for the mode algorithm.
double ns_
Net strangeness density of the cell in the computational frame.
void sample_in_random_cell_BF_algo(ParticleList &plist, const double time, size_t type_index)
The total number of particles of species type_index is defined by mult_int_ array that is returned by...
double mus() const
Get the net strangeness chemical potential.
std::vector< double > N_in_cells_
Number of particles to be sampled in one cell.
ParticleList sampled_list_
Newly generated particles by thermalizer.
int baryon_number() const
std::vector< size_t > cells_to_sample_
Cells above critical energy density.
double abs() const
calculate the lorentz invariant absolute value
std::array< double, 7 > mult_classes_
The different hadron species according to the enum defined in.
HadronClass
Specifier to classify the different hadron species according to their quantum numbers.
DensityType
Allows to choose which kind of density to calculate.
double nb_
Net baryon density of the cell in the computational frame.
HadronGasEos eos_
Hadron gas equation of state.
std::vector< double > mult_sort_
Real number multiplicity for each particle type.
std::vector< int > mult_int_
Integer multiplicity for each particle type.
virtual double current_time() const =0
double mub() const
Get the net baryon chemical potential.
double nb() const
Get net baryon density of the cell in the computational frame.
FourVector Tmu0() const
Get Four-momentum flow of the cell.
void set_4position(const FourVector &pos)
Set the particle's 4-position directly.
const ParticleTypePtrList eos_typelist_
List of particle types from which equation of state is computed.
double mus_
Net strangeness chemical potential.
double mult_class(const HadronClass cl) const
void thermalize_mode_algo(QuantumNumbers &conserved_initial, double time)
Samples particles to the according to the mode algorithm.
void add_particle(const ParticleData &p, double factor)
Add particle contribution to Tmu0, nb and ns May look like unused at first glance,...
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
double sample_momenta_from_thermal(const double temperature, const double mass)
Samples a momentum from the Maxwell-Boltzmann (thermal) distribution in a faster way,...
ParticleList to_remove_
Particles to be removed after this thermalization step.
static double pressure(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute pressure .
const ParticleType & type() const
Get the type of the particle.
ThreeVector threevec() const
const double e_crit_
Critical energy density above which cells are thermalized.
static constexpr int LGrandcanThermalizer
std::unique_ptr< RectangularLattice< ThermLatticeNode > > lat_
The lattice on which the thermodynamic quantities are calculated.
double e_
Energy density in the rest frame.
static double energy_density(double T, double mub, double mus)
Compute energy density.
int baryon_number() const