Version: SMASH-1.8
grandcan_thermalizer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
9 
10 #include <time.h>
11 
12 #include "smash/angles.h"
13 #include "smash/cxx14compat.h"
14 #include "smash/distributions.h"
16 #include "smash/logging.h"
17 #include "smash/particles.h"
18 #include "smash/quantumnumbers.h"
19 #include "smash/random.h"
20 
21 namespace smash {
22 static constexpr int LGrandcanThermalizer = LogArea::GrandcanThermalizer::id;
23 
25  : Tmu0_(FourVector()),
26  nb_(0.0),
27  ns_(0.0),
28  e_(0.0),
29  p_(0.0),
30  v_(ThreeVector()),
31  T_(0.0),
32  mub_(0.0),
33  mus_(0.0) {}
34 
35 void ThermLatticeNode::add_particle(const ParticleData &part, double factor) {
36  Tmu0_ += part.momentum() * factor;
37  nb_ += static_cast<double>(part.type().baryon_number()) * factor;
38  ns_ += static_cast<double>(part.type().strangeness()) * factor;
39 }
40 
43  const int max_iter = 50;
44  v_ = ThreeVector(0.0, 0.0, 0.0);
45  double e_previous_step = 0.0;
46  const double tolerance = 5.e-4;
47  int iter;
48  for (iter = 0; iter < max_iter; iter++) {
49  e_previous_step = e_;
50  e_ = Tmu0_.x0() - Tmu0_.threevec() * v_;
51  if (std::abs(e_ - e_previous_step) < tolerance) {
52  break;
53  }
54  const double gamma_inv = std::sqrt(1.0 - v_.sqr());
55  EosTable::table_element tabulated;
56  eos.from_table(tabulated, e_, gamma_inv * nb_);
57  if (!eos.is_tabulated() || tabulated.p < 0.0) {
58  auto T_mub_mus = eos.solve_eos(e_, gamma_inv * nb_, gamma_inv * ns_);
59  T_ = T_mub_mus[0];
60  mub_ = T_mub_mus[1];
61  mus_ = T_mub_mus[2];
63  } else {
64  p_ = tabulated.p;
65  T_ = tabulated.T;
66  mub_ = tabulated.mub;
67  mus_ = tabulated.mus;
68  }
69  v_ = Tmu0_.threevec() / (Tmu0_.x0() + p_);
70  }
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;
75  }
76 }
77 
78 void ThermLatticeNode::set_rest_frame_quantities(double T0, double mub0,
79  double mus0,
80  const ThreeVector v0) {
81  T_ = T0;
82  mub_ = mub0;
83  mus_ = mus0;
84  v_ = v0;
89 }
90 
91 std::ostream &operator<<(std::ostream &out, const ThermLatticeNode &node) {
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();
97 }
98 
99 GrandCanThermalizer::GrandCanThermalizer(const std::array<double, 3> lat_sizes,
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()),
108  e_crit_(e_critical),
109  t_start_(t_start),
110  period_(delta_t),
111  algorithm_(algo),
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();
117  cell_volume_ = abc[0] * abc[1] * abc[2];
118  cells_to_sample_.resize(50000);
119  mult_sort_.resize(N_sorts_);
120  mult_int_.resize(N_sorts_);
121 }
122 
124  const Particles &particles, const DensityParameters &dens_par,
125  bool ignore_cells_under_treshold) {
126  const DensityType dens_type = DensityType::Hadron;
128  update_lattice(lat_.get(), update, dens_type, dens_par, particles);
129  for (auto &node : *lat_) {
130  /* If energy density is definitely below e_crit -
131  no need to find T, mu, etc. So if e = T00 - T0i*vi <=
132  T00 + sum abs(T0i) < e_crit, no efforts are necessary. */
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()) >=
136  e_crit_) {
137  node.compute_rest_frame_quantities(eos_);
138  } else {
139  node = ThermLatticeNode();
140  }
141  }
142 }
143 
145  return ThreeVector(random::uniform(-0.5 * lat_->cell_sizes()[0],
146  +0.5 * lat_->cell_sizes()[0]),
147  random::uniform(-0.5 * lat_->cell_sizes()[1],
148  +0.5 * lat_->cell_sizes()[1]),
149  random::uniform(-0.5 * lat_->cell_sizes()[2],
150  +0.5 * lat_->cell_sizes()[2]));
151 }
152 
154  ParticleList &plist, const FourVector required_total_momentum) {
155  // Centralize momenta
156  QuantumNumbers conserved = QuantumNumbers(plist);
157  logg[LGrandcanThermalizer].info("Required 4-momentum: ",
158  required_total_momentum);
159  logg[LGrandcanThermalizer].info("Sampled 4-momentum: ", conserved.momentum());
160  const ThreeVector mom_to_add =
161  (required_total_momentum.threevec() - conserved.momentum().threevec()) /
162  plist.size();
163  logg[LGrandcanThermalizer].info("Adjusting momenta by ", mom_to_add);
164  for (auto &particle : plist) {
165  particle.set_4momentum(particle.type().mass(),
166  particle.momentum().threevec() + mom_to_add);
167  }
168 
169  // Boost every particle to the common center of mass frame
170  conserved = QuantumNumbers(plist);
171  const ThreeVector beta_CM_generated = conserved.momentum().velocity();
172  const ThreeVector beta_CM_required = required_total_momentum.velocity();
173 
174  double E = 0.0;
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();
179  }
180  // Renorm. momenta by factor (1+a) to get the right energy, binary search
181  const double tolerance = really_small;
182  double a, a_min, a_max, er;
183  const int max_iter = 100;
184  int iter = 0;
185  if (E_expected >= E) {
186  a_min = 0.0;
187  a_max = 10.0;
188  } else {
189  a_min = -1.0;
190  a_max = 0.0;
191  }
192  do {
193  a = 0.5 * (a_min + a_max);
194  E = 0.0;
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);
199  }
200  er = E - E_expected;
201  if (er >= 0.0) {
202  a_max = a;
203  } else {
204  a_min = a;
205  }
206  logg[LGrandcanThermalizer].debug("Iteration ", iter, ": a = ", a,
207  ", Δ = ", er);
208  iter++;
209  } while (std::abs(er) > tolerance && iter < max_iter);
210 
211  logg[LGrandcanThermalizer].info("Renormalizing momenta by factor 1+a, a = ",
212  a);
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);
217  }
218 }
219 
221  int N_to_sample) {
222  /* The array mult_sort_ contains real numbers \f$ a_i \f$. The numbers \f$
223  * n_i \f$ are saved in the mult_int_ array. Only particles of class
224  * particle_class are sampled, where particle_class is defined by the
225  * get_class function. */
226  double sum = mult_class(particle_class);
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) {
229  continue;
230  }
231  const double p = mult_sort_[i_type] / sum;
232  mult_int_[i_type] = random::binomial(N_to_sample, p);
234  /*std::cout << eos_typelist_[i_type]->name() <<
235  ": mult_sort = " << mult_sort_[i_type] <<
236  ", sum = " << sum <<
237  ", p = " << p <<
238  ", N to sample = " << N_to_sample <<
239  ", mult_int_ = " << mult_int_[i_type] << std::endl;*/
240  sum -= mult_sort_[i_type];
241  N_to_sample -= mult_int_[i_type];
242  }
243 }
244 
246  const double time,
247  size_t type_index) {
248  N_in_cells_.clear();
249  N_total_in_cells_ = 0.0;
250  for (auto cell_index : cells_to_sample_) {
251  const ThermLatticeNode cell = (*lat_)[cell_index];
252  const double gamma = 1.0 / std::sqrt(1.0 - cell.v().sqr());
253  const double N_this_cell =
254  cell_volume_ * gamma *
255  HadronGasEos::partial_density(*eos_typelist_[type_index], cell.T(),
256  cell.mub(), cell.mus());
257  N_in_cells_.push_back(N_this_cell);
258  N_total_in_cells_ += N_this_cell;
259  }
260 
261  for (int i = 0; i < mult_int_[type_index]; i++) {
262  // Choose random cell, probability = N_in_cell/N_total
263  double r = random::uniform(0.0, N_total_in_cells_);
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];
269  }
270  const int cell_index = cells_to_sample_[index_only_thermalized];
271  const ThermLatticeNode cell = (*lat_)[cell_index];
272  const ThreeVector cell_center = lat_->cell_center(cell_index);
273 
274  ParticleData particle(*eos_typelist_[type_index]);
275  // Note: it's pole mass for resonances!
276  const double m = eos_typelist_[type_index]->mass();
277  // Position
278  particle.set_4position(FourVector(time, cell_center + uniform_in_cell()));
279  // Momentum
280  double momentum_radial = sample_momenta_from_thermal(cell.T(), m);
281  Angles phitheta;
282  phitheta.distribute_isotropically();
283  particle.set_4momentum(m, phitheta.threevec() * momentum_radial);
284  particle.boost_momentum(-cell.v());
285  particle.set_formation_time(time);
286 
287  plist.push_back(particle);
288  }
289 }
290 
292  double time, int ntest) {
293  std::fill(mult_sort_.begin(), mult_sort_.end(), 0.0);
294  for (auto cell_index : cells_to_sample_) {
295  const ThermLatticeNode cell = (*lat_)[cell_index];
296  const double gamma = 1.0 / std::sqrt(1.0 - cell.v().sqr());
297  for (size_t i = 0; i < N_sorts_; i++) {
298  // N_i = n u^mu dsigma_mu = (isochronous hypersurface) n * V * gamma
299  mult_sort_[i] += cell_volume_ * gamma * ntest *
301  *eos_typelist_[i], cell.T(), cell.mub(), cell.mus());
302  }
303  }
304 
305  std::fill(mult_classes_.begin(), mult_classes_.end(), 0.0);
306  for (size_t i = 0; i < N_sorts_; i++) {
307  mult_classes_[static_cast<size_t>(get_class(i))] += mult_sort_[i];
308  }
309 
312  conserved_initial.baryon_number());
313 
314  while (true) {
315  sampled_list_.clear();
316  std::fill(mult_int_.begin(), mult_int_.end(), 0);
317  const auto Nbar_antibar = bessel_sampler_B.sample();
318 
319  sample_multinomial(HadronClass::Baryon, Nbar_antibar.first);
320  sample_multinomial(HadronClass::Antibaryon, Nbar_antibar.second);
321 
322  // Count strangeness of the sampled particles
323  int S_sampled = 0;
324  for (size_t i = 0; i < N_sorts_; i++) {
325  S_sampled += eos_typelist_[i]->strangeness() * mult_int_[i];
326  }
327 
328  std::pair<int, int> NS_antiS;
330  random::BesselSampler bessel_sampler_S(
333  conserved_initial.strangeness() - S_sampled);
334  NS_antiS = bessel_sampler_S.sample();
336  NS_antiS = std::make_pair(
339  if (NS_antiS.first - NS_antiS.second !=
340  conserved_initial.strangeness() - S_sampled) {
341  continue;
342  }
343  }
344 
347  // Count charge of the sampled particles
348  int ch_sampled = 0;
349  for (size_t i = 0; i < N_sorts_; i++) {
350  ch_sampled += eos_typelist_[i]->charge() * mult_int_[i];
351  }
352 
353  std::pair<int, int> NC_antiC;
355  random::BesselSampler bessel_sampler_C(
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) {
366  continue;
367  }
368  }
369 
375 
376  for (size_t itype = 0; itype < N_sorts_; itype++) {
378  }
380  double e_tot;
381  const double e_init = conserved_initial.momentum().x0();
382  e_tot = 0.0;
383  for (auto &particle : sampled_list_) {
384  e_tot += particle.momentum().x0();
385  }
386  if (std::abs(e_tot - e_init) > 0.01 * e_init) {
387  logg[LGrandcanThermalizer].info("Rejecting: energy ", e_tot,
388  " too far from ", e_init);
389  continue;
390  }
391  }
392  break;
393  }
394 }
395 
397  QuantumNumbers &conserved_initial, double time) {
398  double energy = 0.0;
399  int S_plus = 0, S_minus = 0, B_plus = 0, B_minus = 0, E_plus = 0, E_minus = 0;
400  // Mode 1: sample until energy is conserved, take only strangeness < 0
401  auto condition1 = [](int, int, int) { return true; };
402  compute_N_in_cells_mode_algo(condition1);
403  while (conserved_initial.momentum().x0() > energy ||
404  S_plus < conserved_initial.strangeness()) {
405  ParticleData p = sample_in_random_cell_mode_algo(time, condition1);
406  energy += p.momentum().x0();
407  if (p.pdgcode().strangeness() > 0) {
408  sampled_list_.push_back(p);
409  S_plus += p.pdgcode().strangeness();
410  }
411  }
412 
413  // Mode 2: sample until strangeness is conserved
414  auto condition2 = [](int S, int, int) { return (S < 0); };
415  compute_N_in_cells_mode_algo(condition2);
416  while (S_plus + S_minus > conserved_initial.strangeness()) {
417  ParticleData p = sample_in_random_cell_mode_algo(time, condition2);
418  const int s_part = p.pdgcode().strangeness();
419  // Do not allow particles with S = -2 or -3 spoil the total sum
420  if (S_plus + S_minus + s_part >= conserved_initial.strangeness()) {
421  sampled_list_.push_back(p);
422  S_minus += s_part;
423  }
424  }
425 
426  // Mode 3: sample non-strange baryons
427  auto condition3 = [](int S, int, int) { return (S == 0); };
428  QuantumNumbers conserved_remaining =
429  conserved_initial - QuantumNumbers(sampled_list_);
430  energy = 0.0;
431  compute_N_in_cells_mode_algo(condition3);
432  while (conserved_remaining.momentum().x0() > energy ||
433  B_plus < conserved_remaining.baryon_number()) {
434  ParticleData p = sample_in_random_cell_mode_algo(time, condition3);
435  energy += p.momentum().x0();
436  if (p.pdgcode().baryon_number() > 0) {
437  sampled_list_.push_back(p);
438  B_plus += p.pdgcode().baryon_number();
439  }
440  }
441 
442  // Mode 4: sample non-strange anti-baryons
443  auto condition4 = [](int S, int B, int) { return (S == 0) && (B < 0); };
444  compute_N_in_cells_mode_algo(condition4);
445  while (B_plus + B_minus > conserved_remaining.baryon_number()) {
446  ParticleData p = sample_in_random_cell_mode_algo(time, condition4);
447  const int bar = p.pdgcode().baryon_number();
448  if (B_plus + B_minus + bar >= conserved_remaining.baryon_number()) {
449  sampled_list_.push_back(p);
450  B_minus += bar;
451  }
452  }
453 
454  // Mode 5: sample non_strange mesons, but take only with charge > 0
455  auto condition5 = [](int S, int B, int) { return (S == 0) && (B == 0); };
456  conserved_remaining = conserved_initial - QuantumNumbers(sampled_list_);
457  energy = 0.0;
458  compute_N_in_cells_mode_algo(condition5);
459  while (conserved_remaining.momentum().x0() > energy ||
460  E_plus < conserved_remaining.charge()) {
461  ParticleData p = sample_in_random_cell_mode_algo(time, condition5);
462  energy += p.momentum().x0();
463  if (p.pdgcode().charge() > 0) {
464  sampled_list_.push_back(p);
465  E_plus += p.pdgcode().charge();
466  }
467  }
468 
469  // Mode 6: sample non_strange mesons to conserve charge
470  auto condition6 = [](int S, int B, int C) {
471  return (S == 0) && (B == 0) && (C < 0);
472  };
473  compute_N_in_cells_mode_algo(condition6);
474  while (E_plus + E_minus > conserved_remaining.charge()) {
475  ParticleData p = sample_in_random_cell_mode_algo(time, condition6);
476  const int charge = p.pdgcode().charge();
477  if (E_plus + E_minus + charge >= conserved_remaining.charge()) {
478  sampled_list_.push_back(p);
479  E_minus += charge;
480  }
481  }
482 
483  // Mode 7: sample neutral non-strange mesons to conserve energy
484  auto condition7 = [](int S, int B, int C) {
485  return (S == 0) && (B == 0) && (C == 0);
486  };
487  conserved_remaining = conserved_initial - QuantumNumbers(sampled_list_);
488  energy = 0.0;
489  compute_N_in_cells_mode_algo(condition7);
490  while (conserved_remaining.momentum().x0() > energy) {
491  ParticleData p = sample_in_random_cell_mode_algo(time, condition7);
492  sampled_list_.push_back(p);
493  energy += p.momentum().x0();
494  }
495 }
496 
497 void GrandCanThermalizer::thermalize(const Particles &particles, double time,
498  int ntest) {
499  logg[LGrandcanThermalizer].info("Starting forced thermalization, time ", time,
500  " fm/c");
501  to_remove_.clear();
502  sampled_list_.clear();
503  /* Remove particles from the cells with e > e_crit_,
504  * sum up their conserved quantities */
505  QuantumNumbers conserved_initial = QuantumNumbers();
506  ThermLatticeNode node;
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_) {
511  to_remove_.push_back(particle);
512  }
513  }
514  /* Do not thermalize too small number of particles: for the number
515  * of particles < 30 the algorithm tends to hang or crash too often. */
516  if (to_remove_.size() > 30) {
517  for (auto &particle : to_remove_) {
518  conserved_initial.add_values(particle);
519  }
520  } else {
521  to_remove_.clear();
522  conserved_initial = QuantumNumbers();
523  }
524  logg[LGrandcanThermalizer].info("Removed ", to_remove_.size(), " particles.");
525 
526  // Exit if there is nothing to thermalize
527  if (conserved_initial == QuantumNumbers()) {
528  return;
529  }
530  // Save the indices of cells inside the volume with e > e_crit_
531  cells_to_sample_.clear();
532  const size_t lattice_total_cells = lat_->size();
533  for (size_t i = 0; i < lattice_total_cells; i++) {
534  if ((*lat_)[i].e() > e_crit_) {
535  cells_to_sample_.push_back(i);
536  }
537  }
539  "Number of cells in the thermalization region = ",
540  cells_to_sample_.size(),
541  ", its total volume [fm^3]: ", cells_to_sample_.size() * cell_volume_,
542  ", in % of lattice: ",
543  100.0 * cells_to_sample_.size() / lattice_total_cells);
544 
545  switch (algorithm_) {
548  thermalize_BF_algo(conserved_initial, time, ntest);
549  break;
551  thermalize_mode_algo(conserved_initial, time);
552  break;
553  default:
554  throw std::invalid_argument(
555  "This thermalization algorithm is"
556  " not yet implemented");
557  }
558  logg[LGrandcanThermalizer].info("Sampled ", sampled_list_.size(),
559  " particles.");
560 
561  // Adjust momenta
562  renormalize_momenta(sampled_list_, conserved_initial.momentum());
563 }
564 
566  struct to_average {
567  double T;
568  double mub;
569  double mus;
570  double nb;
571  double ns;
572  };
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;
585  if (e >= e_crit_) {
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;
592  node_counter++;
593  }
594  }
595  if (e_sum_on_lattice > really_small) {
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;
601  }
602  if (e_sum_in_therm_reg > really_small) {
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;
608  }
609 
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
620  << std::endl;
621 }
622 
623 } // namespace smash
smash::HadronGasEos
Class to handle the equation of state (EoS) of the hadron gas, consisting of all hadrons included int...
Definition: hadgas_eos.h:112
smash::LatticeUpdate
LatticeUpdate
Enumerator option for lattice updates.
Definition: lattice.h:36
smash::ThermLatticeNode::p
double p() const
Get pressure in the rest frame.
Definition: grandcan_thermalizer.h:100
smash::GrandCanThermalizer::sample_multinomial
void sample_multinomial(HadronClass particle_class, int N)
The sample_multinomial function samples integer numbers n_i distributed according to the multinomial ...
Definition: grandcan_thermalizer.cc:220
smash
Definition: action.h:24
smash::GrandCanThermalizer::GrandCanThermalizer
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.
Definition: grandcan_thermalizer.cc:99
smash::QuantumNumbers::momentum
FourVector momentum() const
Definition: quantumnumbers.h:131
quantumnumbers.h
smash::HadronGasEos::solve_eos
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...
Definition: hadgas_eos.cc:506
smash::GrandCanThermalizer::cell_volume_
double cell_volume_
Volume of a single cell, necessary to convert thermal densities to actual particle numbers.
Definition: grandcan_thermalizer.h:514
smash::ThermLatticeNode::mub_
double mub_
Net baryon chemical potential.
Definition: grandcan_thermalizer.h:126
smash::HadronGasEos::from_table
void from_table(EosTable::table_element &res, double e, double nb) const
Get the element of eos table.
Definition: hadgas_eos.h:303
smash::ParticleData::momentum
const FourVector & momentum() const
Get the particle's 4-momentum.
Definition: particledata.h:142
smash::DensityParameters
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:107
smash::ThermLatticeNode::ns
double ns() const
Get net strangeness density of the cell in the computational frame.
Definition: grandcan_thermalizer.h:96
smash::HadronClass::NegativeSMeson
Mesons with strangeness S < 0.
smash::ParticleData
Definition: particledata.h:52
smash::ThermLatticeNode::ThermLatticeNode
ThermLatticeNode()
Default constructor of thermal quantities on the lattice returning thermodynamic quantities in comput...
Definition: grandcan_thermalizer.cc:24
smash::HadronGasEos::partial_density
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.
Definition: hadgas_eos.cc:234
smash::HadronGasEos::net_strange_density
static double net_strange_density(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute net strangeness density.
Definition: hadgas_eos.cc:307
smash::ThermLatticeNode::Tmu0_
FourVector Tmu0_
Four-momentum flow of the cell.
Definition: grandcan_thermalizer.h:112
cxx14compat.h
smash::ThermLatticeNode::v
ThreeVector v() const
Get 3-velocity of the rest frame.
Definition: grandcan_thermalizer.h:102
smash::operator<<
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Definition: action.h:463
smash::GrandCanThermalizer::N_sorts_
const size_t N_sorts_
Number of different species to be sampled.
Definition: grandcan_thermalizer.h:498
smash::random::BesselSampler
The intention of this class is to efficiently sample from the Bessel distribution ,...
Definition: random.h:377
smash::HadronClass::NegativeQZeroSMeson
Non-strange mesons (S = 0) with electric cherge Q < 0.
smash::Angles::distribute_isotropically
void distribute_isotropically()
Populate the object with a new direction.
Definition: angles.h:188
smash::GrandCanThermalizer::algorithm_
const ThermalizationAlgorithm algorithm_
Algorithm to choose for sampling of particles obeying conservation laws.
Definition: grandcan_thermalizer.h:522
smash::ThreeVector::sqr
double sqr() const
Definition: threevector.h:259
smash::QuantumNumbers::add_values
void add_values(const ParticleData &p)
Add the quantum numbers of a single particle to the collection.
Definition: quantumnumbers.h:114
smash::ThermLatticeNode::T_
double T_
Temperature.
Definition: grandcan_thermalizer.h:124
smash::GrandCanThermalizer::thermalize
void thermalize(const Particles &particles, double time, int ntest)
Main thermalize function, that chooses the algorithm to follow (BF or mode sampling).
Definition: grandcan_thermalizer.cc:497
smash::GrandCanThermalizer::thermalize_BF_algo
void thermalize_BF_algo(QuantumNumbers &conserved_initial, double time, int ntest)
Samples particles according to the BF algorithm by making use of the.
Definition: grandcan_thermalizer.cc:291
smash::GrandCanThermalizer::print_statistics
void print_statistics(const Clock &clock) const
Generates standard output with information about the thermodynamic properties of the lattice,...
Definition: grandcan_thermalizer.cc:565
smash::ParticleData::set_4momentum
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
Definition: particledata.h:148
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
grandcan_thermalizer.h
smash::really_small
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
random.h
smash::ThermLatticeNode
The ThermLatticeNode class is intended to compute thermodynamical quantities in a cell given a set of...
Definition: grandcan_thermalizer.h:48
angles.h
ThermalizationAlgorithm::UnbiasedBF
smash::ThermLatticeNode::compute_rest_frame_quantities
void compute_rest_frame_quantities(HadronGasEos &eos)
Temperature, chemical potentials and rest frame velocity are calculated given the hadron gas equation...
Definition: grandcan_thermalizer.cc:41
smash::ThermLatticeNode::e
double e() const
Get energy density in the rest frame.
Definition: grandcan_thermalizer.h:98
forwarddeclarations.h
smash::HadronGasEos::is_tabulated
bool is_tabulated() const
Create an EoS table or not?
Definition: hadgas_eos.h:313
ThermalizationAlgorithm
ThermalizationAlgorithm
Defines the algorithm used for the forced thermalization.
Definition: forwarddeclarations.h:237
smash::ThreeVector
Definition: threevector.h:31
smash::QuantumNumbers::charge
int charge() const
Definition: quantumnumbers.h:140
smash::ThermLatticeNode::T
double T() const
Get the temperature.
Definition: grandcan_thermalizer.h:104
smash::ThermLatticeNode::p_
double p_
Pressure in the rest frame.
Definition: grandcan_thermalizer.h:120
smash::LatticeUpdate::EveryFixedInterval
smash::ParticleData::set_formation_time
void set_formation_time(const double &form_time)
Set the absolute formation time.
Definition: particledata.h:235
smash::ParticleData::boost_momentum
void boost_momentum(const ThreeVector &v)
Apply a Lorentz-boost to only the momentum.
Definition: particledata.h:316
smash::FourVector::x0
double x0() const
Definition: fourvector.h:303
smash::random::binomial
int binomial(const int N, const T &p)
Returns a binomially distributed random number.
Definition: random.h:238
smash::update_lattice
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.
Definition: density.h:401
smash::GrandCanThermalizer::BF_enforce_microcanonical_
const bool BF_enforce_microcanonical_
Enforce energy conservation as part of BF sampling algorithm or not.
Definition: grandcan_thermalizer.h:524
smash::random::BesselSampler::sample
std::pair< int, int > sample()
Sample two numbers from given Poissonians with a fixed difference.
Definition: random.cc:71
smash::GrandCanThermalizer::N_total_in_cells_
double N_total_in_cells_
Total number of particles over all cells in thermalization region.
Definition: grandcan_thermalizer.h:509
smash::HadronClass::ZeroQZeroSMeson
Neutral non-strange mesons.
smash::GrandCanThermalizer::get_class
HadronClass get_class(size_t typelist_index) const
Defines the class of hadrons by quantum numbers.
Definition: grandcan_thermalizer.h:458
smash::GrandCanThermalizer::uniform_in_cell
ThreeVector uniform_in_cell() const
Definition: grandcan_thermalizer.cc:144
distributions.h
smash::HadronClass::PositiveSMeson
Mesons with strangeness S > 0.
smash::HadronClass::PositiveQZeroSMeson
Non-strange mesons (S = 0) with electric cherge Q > 0.
smash::HadronGasEos::net_baryon_density
static double net_baryon_density(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute net baryon density.
Definition: hadgas_eos.cc:289
smash::ThermLatticeNode::set_rest_frame_quantities
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.
Definition: grandcan_thermalizer.cc:78
smash::GrandCanThermalizer::update_thermalizer_lattice
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.
Definition: grandcan_thermalizer.cc:123
smash::ThermLatticeNode::v_
ThreeVector v_
Velocity of the rest frame.
Definition: grandcan_thermalizer.h:122
smash::random::poisson
int poisson(const T &lam)
Returns a Poisson distributed random number.
Definition: random.h:226
smash::GrandCanThermalizer::renormalize_momenta
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.
Definition: grandcan_thermalizer.cc:153
smash::Clock
Clock tracks the time in the simulation.
Definition: clock.h:70
smash::GrandCanThermalizer::sample_in_random_cell_mode_algo
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...
Definition: grandcan_thermalizer.h:360
smash::FourVector::velocity
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:323
smash::EosTable::table_element
Define the data structure for one element of the table.
Definition: hadgas_eos.h:55
smash::GrandCanThermalizer::compute_N_in_cells_mode_algo
void compute_N_in_cells_mode_algo(F &&condition)
Computes average number of particles in each cell for the mode algorithm.
Definition: grandcan_thermalizer.h:329
ThermalizationAlgorithm::ModeSampling
smash::ThermLatticeNode::ns_
double ns_
Net strangeness density of the cell in the computational frame.
Definition: grandcan_thermalizer.h:116
smash::GrandCanThermalizer::sample_in_random_cell_BF_algo
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...
Definition: grandcan_thermalizer.cc:245
smash::ThermLatticeNode::mus
double mus() const
Get the net strangeness chemical potential.
Definition: grandcan_thermalizer.h:108
smash::GrandCanThermalizer::N_in_cells_
std::vector< double > N_in_cells_
Number of particles to be sampled in one cell.
Definition: grandcan_thermalizer.h:477
smash::GrandCanThermalizer::sampled_list_
ParticleList sampled_list_
Newly generated particles by thermalizer.
Definition: grandcan_thermalizer.h:487
smash::QuantumNumbers::baryon_number
int baryon_number() const
Definition: quantumnumbers.h:180
smash::GrandCanThermalizer::cells_to_sample_
std::vector< size_t > cells_to_sample_
Cells above critical energy density.
Definition: grandcan_thermalizer.h:479
smash::FourVector::abs
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:454
particles.h
ThermalizationAlgorithm::BiasedBF
smash::GrandCanThermalizer::mult_classes_
std::array< double, 7 > mult_classes_
The different hadron species according to the enum defined in.
Definition: grandcan_thermalizer.h:507
smash::HadronClass
HadronClass
Specifier to classify the different hadron species according to their quantum numbers.
Definition: grandcan_thermalizer.h:143
smash::Particles
Definition: particles.h:33
smash::DensityType
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:35
smash::QuantumNumbers::strangeness
int strangeness() const
Definition: quantumnumbers.h:156
smash::ThermLatticeNode::nb_
double nb_
Net baryon density of the cell in the computational frame.
Definition: grandcan_thermalizer.h:114
smash::GrandCanThermalizer::eos_
HadronGasEos eos_
Hadron gas equation of state.
Definition: grandcan_thermalizer.h:481
smash::GrandCanThermalizer::mult_sort_
std::vector< double > mult_sort_
Real number multiplicity for each particle type.
Definition: grandcan_thermalizer.h:500
smash::GrandCanThermalizer::mult_int_
std::vector< int > mult_int_
Integer multiplicity for each particle type.
Definition: grandcan_thermalizer.h:502
smash::Clock::current_time
virtual double current_time() const =0
smash::ThermLatticeNode::mub
double mub() const
Get the net baryon chemical potential.
Definition: grandcan_thermalizer.h:106
logging.h
smash::ParticleType::strangeness
int strangeness() const
Definition: particletype.h:209
smash::ThermLatticeNode::nb
double nb() const
Get net baryon density of the cell in the computational frame.
Definition: grandcan_thermalizer.h:94
smash::ThermLatticeNode::Tmu0
FourVector Tmu0() const
Get Four-momentum flow of the cell.
Definition: grandcan_thermalizer.h:92
smash::ParticleData::set_4position
void set_4position(const FourVector &pos)
Set the particle's 4-position directly.
Definition: particledata.h:193
smash::GrandCanThermalizer::eos_typelist_
const ParticleTypePtrList eos_typelist_
List of particle types from which equation of state is computed.
Definition: grandcan_thermalizer.h:496
smash::ThermLatticeNode::mus_
double mus_
Net strangeness chemical potential.
Definition: grandcan_thermalizer.h:128
smash::GrandCanThermalizer::mult_class
double mult_class(const HadronClass cl) const
Definition: grandcan_thermalizer.h:473
smash::GrandCanThermalizer::thermalize_mode_algo
void thermalize_mode_algo(QuantumNumbers &conserved_initial, double time)
Samples particles to the according to the mode algorithm.
Definition: grandcan_thermalizer.cc:396
smash::ThermLatticeNode::add_particle
void add_particle(const ParticleData &p, double factor)
Add particle contribution to Tmu0, nb and ns May look like unused at first glance,...
Definition: grandcan_thermalizer.cc:35
smash::FourVector
Definition: fourvector.h:33
S
#define S(x, n)
Definition: sha256.cc:54
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::Angles
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
smash::random::uniform
T uniform(T min, T max)
Definition: random.h:88
smash::DensityType::Hadron
smash::DensityType::Baryon
smash::sample_momenta_from_thermal
double sample_momenta_from_thermal(const double temperature, const double mass)
Samples a momentum from the Maxwell-Boltzmann (thermal) distribution in a faster way,...
Definition: distributions.cc:190
smash::GrandCanThermalizer::to_remove_
ParticleList to_remove_
Particles to be removed after this thermalization step.
Definition: grandcan_thermalizer.h:485
smash::HadronGasEos::pressure
static double pressure(double T, double mub, double mus, bool account_for_resonance_widths=false)
Compute pressure .
Definition: hadgas_eos.h:180
smash::ParticleData::type
const ParticleType & type() const
Get the type of the particle.
Definition: particledata.h:112
smash::QuantumNumbers
Definition: quantumnumbers.h:53
smash::FourVector::threevec
ThreeVector threevec() const
Definition: fourvector.h:319
smash::GrandCanThermalizer::e_crit_
const double e_crit_
Critical energy density above which cells are thermalized.
Definition: grandcan_thermalizer.h:516
smash::LGrandcanThermalizer
static constexpr int LGrandcanThermalizer
Definition: grandcan_thermalizer.cc:22
smash::GrandCanThermalizer::lat_
std::unique_ptr< RectangularLattice< ThermLatticeNode > > lat_
The lattice on which the thermodynamic quantities are calculated.
Definition: grandcan_thermalizer.h:483
smash::HadronClass::Antibaryon
All anti-baryons.
smash::ThermLatticeNode::e_
double e_
Energy density in the rest frame.
Definition: grandcan_thermalizer.h:118
smash::HadronGasEos::energy_density
static double energy_density(double T, double mub, double mus)
Compute energy density.
Definition: hadgas_eos.cc:244
smash::ParticleType::baryon_number
int baryon_number() const
Definition: particletype.h:206