Version: SMASH-2.2
hypersurfacecrossingaction.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019-2022
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
11 
12 #include "smash/logging.h"
13 #include "smash/quantumnumbers.h"
14 
15 namespace smash {
16 static constexpr int LHyperSurfaceCrossing = LogArea::HyperSurfaceCrossing::id;
17 
19  logg[LHyperSurfaceCrossing].debug("Process: Hypersurface Crossing. ");
20 
21  ParticleList empty_list;
22 
23  // check that there is only 1 incoming particle
24  assert(incoming_particles_.size() == 1);
25 
26  // Return empty list because we want to remove the incoming particle
27  outgoing_particles_ = empty_list;
28 }
29 
31  const uint32_t id_process) const {
34  if (before == after) {
35  // Conservation laws should not be conserved since particles are removed
36  // from the evolution
37  throw std::runtime_error(
38  "Conservation laws conserved in the hypersurface "
39  "crossing action. Particle was not properly removed in process: " +
40  std::to_string(id_process));
41  }
42 
43  if (outgoing_particles_.size() != 0) {
44  throw std::runtime_error(
45  "Particle was not removed successfully in "
46  "hypersurface crossing action.");
47  }
48 }
49 
51  const ParticleList &plist, double dt, const double,
52  const std::vector<FourVector> &beam_momentum) const {
53  std::vector<ActionPtr> actions;
54 
55  for (const ParticleData &p : plist) {
56  ParticleData pdata_before_propagation = p;
57  ParticleData pdata_after_propagation = p; // Will receive updated position
58  double t0 = p.position().x0();
59  double t_end = t0 + dt; // Time at the end of timestep
60 
61  // We don't want to remove particles before the nuclei have interacted
62  // because those would not yet be part of the newly-created medium.
63  if (t_end < 0.0) {
64  continue;
65  }
66 
67  // For frozen Fermi motion:
68  // Fermi momenta are only applied if particles interact. The particle
69  // properties p.velocity() and p.momentum() already contain the values
70  // corrected by Fermi motion, but those particles that have not yet
71  // interacted are propagated along the beam-axis with v = (0, 0, beam_v)
72  // (and not with p.velocity()).
73  // To identify the corresponding hypersurface crossings the finding for
74  // those paricles without prior interactions has to be performed with
75  // v = vbeam instead of p.velcocity().
76  // Note: The beam_momentum vector is empty in case frozen Fermi motion is
77  // not applied.
78  const bool no_prior_interactions =
79  (static_cast<uint64_t>(p.id()) < // particle from
80  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
81  (p.get_history().collisions_per_particle == 0);
82  ThreeVector v;
83  if (no_prior_interactions) {
84  const FourVector vbeam = beam_momentum[p.id()];
85  v = vbeam.velocity();
86  } else {
87  v = p.velocity();
88  }
89 
90  // propagate particles to position where they would be at the end of the
91  // time step (after dt)
92  const FourVector distance = FourVector(0.0, v * dt);
93  FourVector position = p.position() + distance;
94  position.set_x0(t_end);
95  // update coordinates to the position corresponding to t_end
96  pdata_after_propagation.set_4position(position);
97 
98  bool hypersurface_is_crossed = crosses_hypersurface(
99  pdata_before_propagation, pdata_after_propagation, prop_time_);
100 
101  /*
102  If rapidity or transverse momentum cut is to be employed; check if
103  particles are within the relevant region
104  Implementation explanation: The default for both cuts is 0.0, as a cut at
105  0 implies that not a single particle contributes to the initial
106  conditions. If the user specifies a value of 0.0 in the config, SMASH
107  crashes with a corresponding error message. The same applies to negtive
108  values.
109  */
110  bool is_within_y_cut = true;
111  // Check whether particle is in desired rapidity range
112  if (rap_cut_ > 0.0) {
113  const double rapidity =
114  0.5 * std::log((p.momentum().x0() + p.momentum().x3()) /
115  (p.momentum().x0() - p.momentum().x3()));
116  if (abs(rapidity) > rap_cut_) {
117  is_within_y_cut = false;
118  }
119  }
120 
121  bool is_within_pT_cut = true;
122  // Check whether particle is in desired pT range
123  if (pT_cut_ > 0.0) {
124  const double transverse_momentum =
125  sqrt(p.momentum().x1() * p.momentum().x1() +
126  p.momentum().x2() * p.momentum().x2());
127  if (transverse_momentum > pT_cut_) {
128  is_within_pT_cut = false;
129  }
130  }
131 
132  if (hypersurface_is_crossed && is_within_y_cut && is_within_pT_cut) {
133  // Get exact coordinates where hypersurface is crossed
134  FourVector crossing_position = coordinates_on_hypersurface(
135  pdata_before_propagation, pdata_after_propagation, prop_time_);
136 
137  double time_until_crossing = crossing_position[0] - t0;
138 
139  ParticleData outgoing_particle(p);
140  outgoing_particle.set_4position(crossing_position);
141  ActionPtr action = make_unique<HypersurfacecrossingAction>(
142  p, outgoing_particle, time_until_crossing);
143  actions.emplace_back(std::move(action));
144  }
145  }
146  return actions;
147 }
148 
150  ParticleData &pdata_before_propagation,
151  ParticleData &pdata_after_propagation, const double tau) const {
152  bool hypersurface_is_crossed = false;
153  const bool t_greater_z_before_prop =
154  (std::fabs(pdata_before_propagation.position().x0()) >
155  std::fabs(pdata_before_propagation.position().x3())
156  ? 1
157  : 0);
158  const bool t_greater_z_after_prop =
159  (std::fabs(pdata_after_propagation.position().x0()) >
160  std::fabs(pdata_after_propagation.position().x3())
161  ? 1
162  : 0);
163 
164  if (t_greater_z_before_prop && t_greater_z_after_prop) {
165  // proper time before and after propagation
166  const double tau_before = pdata_before_propagation.position().tau();
167  const double tau_after = pdata_after_propagation.position().tau();
168 
169  if (tau_before <= tau && tau <= tau_after) {
170  hypersurface_is_crossed = true;
171  }
172  } else if (!t_greater_z_before_prop && t_greater_z_after_prop) {
173  // proper time after propagation
174  const double tau_after = pdata_after_propagation.position().tau();
175  if (tau_after >= tau) {
176  hypersurface_is_crossed = true;
177  }
178  }
179 
180  return hypersurface_is_crossed;
181 }
182 
184  ParticleData &pdata_before_propagation,
185  ParticleData &pdata_after_propagation, const double tau) const {
186  // find t and z at start of propagation
187  const double t1 = pdata_before_propagation.position().x0();
188  const double z1 = pdata_before_propagation.position().x3();
189 
190  // find t and z after propagation
191  const double t2 = pdata_after_propagation.position().x0();
192  const double z2 = pdata_after_propagation.position().x3();
193 
194  // find slope and intercept of linear function that describes propagation on
195  // straight line
196  const double m = (z2 - z1) / (t2 - t1);
197  const double n = z1 - m * t1;
198 
199  // The equation to solve is a quadratic equation which provides two solutions,
200  // the latter is usually out of the t-interval we are looking at.
201  const double sol1 = n * m / (1 - m * m) +
202  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
203  const double sol2 = n * m / (1 - m * m) -
204  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
205 
206  SMASH_UNUSED(sol2); // only used in DEBUG output
207  assert((sol1 >= t1 && sol1 <= t2));
208  assert(!(sol2 >= t1 && sol2 <= t2));
209 
210  // Propagate to point where hypersurface is crossed
211  const ThreeVector v = pdata_before_propagation.velocity();
212  const FourVector distance = FourVector(0.0, v * (sol1 - t1));
213  FourVector crossing_position = pdata_before_propagation.position() + distance;
214  crossing_position.set_x0(sol1);
215 
216  return crossing_position;
217 }
218 
219 } // namespace smash
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:348
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:340
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double x3() const
Definition: fourvector.h:320
double x0() const
Definition: fourvector.h:308
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:328
void set_x0(double t)
Definition: fourvector.h:310
double tau() const
calculate the proper time from the given four vector
Definition: fourvector.h:473
const double prop_time_
Proper time of the hypersurface in fm.
FourVector coordinates_on_hypersurface(ParticleData &pdata_before_propagation, ParticleData &pdata_after_propagation, const double tau) const
Find the coordinates where particle crosses hypersurface.
const double rap_cut_
Rapidity (momentum space) cut for the particles contributing to the initial conditions for hydrodynam...
const double pT_cut_
Transverse momentum cut for the particles contributing to the initial conditions for hydrodynamics.
ActionList find_actions_in_cell(const ParticleList &plist, double dt, const double, const std::vector< FourVector > &beam_momentum) const override
Find the next hypersurface crossings for each particle that occur within the timestepless propagation...
bool crosses_hypersurface(ParticleData &pdata_before_propagation, ParticleData &pdata_after_propagation, const double tau) const
Determine whether particle crosses hypersurface within next timestep during propagation.
void generate_final_state() override
Generate the final state of the hypersurface crossing particles.
void check_conservation(const uint32_t id_process) const override
Check various conservation laws.
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
void set_4position(const FourVector &pos)
Set the particle's 4-position directly.
Definition: particledata.h:209
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:301
const FourVector & position() const
Get the particle's position in Minkowski space.
Definition: particledata.h:204
A container for storing conserved values.
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
#define SMASH_UNUSED(x)
Mark as unused, silencing compiler warnings.
Definition: macros.h:24
constexpr int p
Proton.
constexpr int n
Neutron.
Definition: action.h:24
static constexpr int LHyperSurfaceCrossing