Version: SMASH-2.0
propagation.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2020
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/propagation.h"
11 
12 #include "smash/boxmodus.h"
13 #include "smash/collidermodus.h"
14 #include "smash/listmodus.h"
15 #include "smash/logging.h"
16 #include "smash/spheremodus.h"
17 
18 namespace smash {
19 static constexpr int LPropagation = LogArea::Propagation::id;
20 
21 double calc_hubble(double time, const ExpansionProperties &metric) {
22  double h; // Hubble parameter
23 
24  switch (metric.mode_) {
26  h = 0.;
27  break;
29  h = metric.b_ / (2 * (metric.b_ * time + 1));
30  break;
32  h = 2 * metric.b_ / (3 * (metric.b_ * time + 1));
33  break;
35  h = metric.b_ * time;
36  break;
37  default:
38  h = 0.;
39  }
40 
41  return h;
42 }
43 
44 double propagate_straight_line(Particles *particles, double to_time,
45  const std::vector<FourVector> &beam_momentum) {
46  bool negative_dt_error = false;
47  double dt = 0.0;
48  for (ParticleData &data : *particles) {
49  const double t0 = data.position().x0();
50  dt = to_time - t0;
51  if (dt < 0.0 && !negative_dt_error) {
52  // Print error message once, not for every particle
53  negative_dt_error = true;
54  logg[LPropagation].error("propagate_straight_line - negative dt = ", dt);
55  }
56  assert(dt >= 0.0);
57  /* "Frozen Fermi motion": Fermi momenta are only used for collisions,
58  * but not for propagation. This is done to avoid nucleus flying apart
59  * even if potentials are off. Initial nucleons before the first collision
60  * are propagated only according to beam momentum.
61  * Initial nucleons are distinguished by data.id() < the size of
62  * beam_momentum, which is by default zero except for the collider modus
63  * with the fermi motion == frozen.
64  * todo(m. mayer): improve this condition (see comment #11 issue #4213)*/
65  assert(data.id() >= 0);
66  const bool avoid_fermi_motion =
67  (static_cast<uint64_t>(data.id()) <
68  static_cast<uint64_t>(beam_momentum.size())) &&
69  (data.get_history().collisions_per_particle == 0);
70  ThreeVector v;
71  if (avoid_fermi_motion) {
72  const FourVector vbeam = beam_momentum[data.id()];
73  v = vbeam.velocity();
74  } else {
75  v = data.velocity();
76  }
77  const FourVector distance = FourVector(0.0, v * dt);
78  logg[LPropagation].debug("Particle ", data, " motion: ", distance);
79  FourVector position = data.position() + distance;
80  position.set_x0(to_time);
81  data.set_4position(position);
82  }
83  return dt;
84 }
85 
86 void expand_space_time(Particles *particles,
87  const ExperimentParameters &parameters,
88  const ExpansionProperties &metric) {
89  const double dt = parameters.labclock->timestep_duration();
90  for (ParticleData &data : *particles) {
91  // Momentum and position modification to ensure appropriate expansion
92  const double h = calc_hubble(parameters.labclock->current_time(), metric);
93  FourVector delta_mom = FourVector(0.0, h * data.momentum().threevec() * dt);
94  FourVector expan_dist =
95  FourVector(0.0, h * data.position().threevec() * dt);
96 
97  logg[LPropagation].debug("Particle ", data,
98  " expansion motion: ", expan_dist);
99  // New position and momentum
100  FourVector position = data.position() + expan_dist;
101  FourVector momentum = data.momentum() - delta_mom;
102 
103  // set the new momentum and position variables
104  data.set_4position(position);
105  data.set_4momentum(momentum);
106  // force the on shell condition to ensure correct energy
107  data.set_4momentum(data.pole_mass(), data.momentum().threevec());
108  }
109 }
110 
112  Particles *particles, double dt, const Potentials &pot,
113  RectangularLattice<std::pair<ThreeVector, ThreeVector>> *FB_lat,
114  RectangularLattice<std::pair<ThreeVector, ThreeVector>> *FI3_lat) {
115  // Copy particles before propagation to calculate potentials from them
116  const ParticleList plist = particles->copy_to_vector();
117 
118  bool possibly_use_lattice =
119  (pot.use_skyrme() ? (FB_lat != nullptr) : true) &&
120  (pot.use_symmetry() ? (FI3_lat != nullptr) : true);
121  std::pair<ThreeVector, ThreeVector> FB, FI3;
122  double min_time_scale = std::numeric_limits<double>::infinity();
123 
124  for (ParticleData &data : *particles) {
125  // Only baryons and nuclei will be affected by the potentials
126  if (!(data.is_baryon() || data.is_nucleus())) {
127  continue;
128  }
129  const auto scale = pot.force_scale(data.type());
130  const ThreeVector r = data.position().threevec();
131  /* Lattices can be used for calculation if 1-2 are fulfilled:
132  * 1) Required lattices are not nullptr - possibly_use_lattice
133  * 2) r is not out of required lattices */
134  const bool use_lattice =
135  possibly_use_lattice &&
136  (pot.use_skyrme() ? FB_lat->value_at(r, FB) : true) &&
137  (pot.use_symmetry() ? FI3_lat->value_at(r, FI3) : true);
138  if (!pot.use_skyrme()) {
139  FB = std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
140  }
141  if (!pot.use_symmetry()) {
142  FI3 = std::make_pair(ThreeVector(0., 0., 0.), ThreeVector(0., 0., 0.));
143  }
144  if (!use_lattice) {
145  const auto tmp = pot.all_forces(r, plist);
146  FB = std::make_pair(std::get<0>(tmp), std::get<1>(tmp));
147  FI3 = std::make_pair(std::get<2>(tmp), std::get<3>(tmp));
148  }
149  const ThreeVector Force =
150  scale.first *
151  (FB.first + data.momentum().velocity().cross_product(FB.second)) +
152  scale.second * data.type().isospin3_rel() *
153  (FI3.first + data.momentum().velocity().cross_product(FI3.second));
154  logg[LPropagation].debug("Update momenta: F [GeV/fm] = ", Force);
155  data.set_4momentum(data.effective_mass(),
156  data.momentum().threevec() + Force * dt);
157 
158  // calculate the time scale of the change in momentum
159  const double Force_abs = Force.abs();
160  if (Force_abs < really_small) {
161  continue;
162  }
163  const double time_scale = data.momentum().x0() / Force_abs;
164  if (time_scale < min_time_scale) {
165  min_time_scale = time_scale;
166  }
167  }
168 
169  // warn if the time step is too big
170  constexpr double safety_factor = 0.1;
171  if (dt > safety_factor * min_time_scale) {
172  logg[LPropagation].warn()
173  << "The time step size is too large for an accurate propagation "
174  << "with potentials. Maximum safe value: "
175  << safety_factor * min_time_scale << " fm/c.";
176  }
177 }
178 
179 } // namespace smash
smash
Definition: action.h:24
smash::expand_space_time
void expand_space_time(Particles *particles, const ExperimentParameters &parameters, const ExpansionProperties &metric)
Modifies positions and momentum of all particles to account for space-time deformation.
Definition: propagation.cc:86
smash::ParticleData
Definition: particledata.h:52
smash::Potentials::force_scale
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:164
ExpansionMode::NoExpansion
ExpansionMode::Exponential
smash::FourVector::set_x0
void set_x0(double t)
Definition: fourvector.h:305
smash::Potentials::all_forces
virtual std::tuple< ThreeVector, ThreeVector, ThreeVector, ThreeVector > all_forces(const ThreeVector &r, const ParticleList &plist) const
Evaluates the electrical and magnetic components of the forces at point r.
Definition: potentials.cc:229
propagation.h
smash::Potentials::use_symmetry
virtual bool use_symmetry() const
Definition: potentials.h:193
smash::Potentials::use_skyrme
virtual bool use_skyrme() const
Definition: potentials.h:191
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
smash::really_small
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
smash::ExpansionProperties::mode_
ExpansionMode mode_
Type of metric used.
Definition: propagation.h:28
smash::ThreeVector
Definition: threevector.h:31
smash::LPropagation
static constexpr int LPropagation
Definition: propagation.cc:19
boxmodus.h
spheremodus.h
smash::Particles::copy_to_vector
ParticleList copy_to_vector() const
Definition: particles.h:44
smash::RectangularLattice
A container class to hold all the arrays on the lattice and access them.
Definition: lattice.h:47
smash::Potentials
A class that stores parameters of potentials, calculates potentials and their gradients.
Definition: potentials.h:32
ExpansionMode::MassiveFRW
collidermodus.h
smash::calc_hubble
double calc_hubble(double time, const ExpansionProperties &metric)
Calculate the Hubble parameter , which describes how large the expansion flow is.
Definition: propagation.cc:21
ExpansionMode::MasslessFRW
smash::FourVector::velocity
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:323
smash::ExperimentParameters::labclock
std::unique_ptr< Clock > labclock
System clock (for simulation time keeping in the computational frame)
Definition: experimentparameters.h:26
smash::ThreeVector::abs
double abs() const
Definition: threevector.h:261
smash::Particles
Definition: particles.h:33
smash::ExpansionProperties::b_
double b_
Expansion parameter in the metric (faster expansion for larger values)
Definition: propagation.h:30
logging.h
listmodus.h
smash::ExperimentParameters
Helper structure for Experiment.
Definition: experimentparameters.h:24
smash::FourVector
Definition: fourvector.h:33
smash::propagate_straight_line
double propagate_straight_line(Particles *particles, double to_time, const std::vector< FourVector > &beam_momentum)
Propagates the positions of all particles on a straight line to a given moment.
Definition: propagation.cc:44
smash::ExpansionProperties
Struct containing the type of the metric and the expansion parameter of the metric.
Definition: propagation.h:26
smash::update_momenta
void update_momenta(Particles *particles, double dt, const Potentials &pot, RectangularLattice< std::pair< ThreeVector, ThreeVector >> *FB_lat, RectangularLattice< std::pair< ThreeVector, ThreeVector >> *FI3_lat)
Updates the momenta of all particles at the current time step according to the equations of motion:
Definition: propagation.cc:111