Version: SMASH-3.1
hypersurfacecrossingaction.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019-2020,2022-2023
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  return 0.;
49 }
50 
52  const ParticleList &plist, double dt, const double,
53  const std::vector<FourVector> &beam_momentum) const {
54  std::vector<ActionPtr> actions;
55 
56  for (const ParticleData &p : plist) {
57  ParticleData pdata_before_propagation = p;
58  ParticleData pdata_after_propagation = p; // Will receive updated position
59  double t0 = p.position().x0();
60  double t_end = t0 + dt; // Time at the end of timestep
61 
62  // We don't want to remove particles before the nuclei have interacted
63  // because those would not yet be part of the newly-created medium.
64  if (t_end < 0.0) {
65  continue;
66  }
67 
68  // For frozen Fermi motion:
69  // Fermi momenta are only applied if particles interact. The particle
70  // properties p.velocity() and p.momentum() already contain the values
71  // corrected by Fermi motion, but those particles that have not yet
72  // interacted are propagated along the beam-axis with v = (0, 0, beam_v)
73  // (and not with p.velocity()).
74  // To identify the corresponding hypersurface crossings the finding for
75  // those paricles without prior interactions has to be performed with
76  // v = vbeam instead of p.velcocity().
77  // Note: The beam_momentum vector is empty in case frozen Fermi motion is
78  // not applied.
79  const bool no_prior_interactions =
80  (static_cast<uint64_t>(p.id()) < // particle from
81  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
82  (p.get_history().collisions_per_particle == 0);
83  ThreeVector v;
84  if (no_prior_interactions) {
85  const FourVector vbeam = beam_momentum[p.id()];
86  v = vbeam.velocity();
87  } else {
88  v = p.velocity();
89  }
90 
91  // propagate particles to position where they would be at the end of the
92  // time step (after dt)
93  const FourVector distance = FourVector(0.0, v * dt);
94  FourVector position = p.position() + distance;
95  position.set_x0(t_end);
96  // update coordinates to the position corresponding to t_end
97  pdata_after_propagation.set_4position(position);
98 
99  bool hypersurface_is_crossed = crosses_hypersurface(
100  pdata_before_propagation, pdata_after_propagation, prop_time_);
101 
102  /*
103  If rapidity or transverse momentum cut is to be employed; check if
104  particles are within the relevant region
105  Implementation explanation: The default for both cuts is 0.0, as a cut at
106  0 implies that not a single particle contributes to the initial
107  conditions. If the user specifies a value of 0.0 in the config, SMASH
108  crashes with a corresponding error message. The same applies to negtive
109  values.
110  */
111  bool is_within_y_cut = true;
112  // Check whether particle is in desired rapidity range
113  if (rap_cut_ > 0.0) {
114  const double rapidity =
115  0.5 * std::log((p.momentum().x0() + p.momentum().x3()) /
116  (p.momentum().x0() - p.momentum().x3()));
117  if (std::fabs(rapidity) > rap_cut_) {
118  is_within_y_cut = false;
119  }
120  }
121 
122  bool is_within_pT_cut = true;
123  // Check whether particle is in desired pT range
124  if (pT_cut_ > 0.0) {
125  const double transverse_momentum =
126  std::sqrt(p.momentum().x1() * p.momentum().x1() +
127  p.momentum().x2() * p.momentum().x2());
128  if (transverse_momentum > pT_cut_) {
129  is_within_pT_cut = false;
130  }
131  }
132 
133  if (hypersurface_is_crossed && is_within_y_cut && is_within_pT_cut) {
134  // Get exact coordinates where hypersurface is crossed
135  FourVector crossing_position = coordinates_on_hypersurface(
136  pdata_before_propagation, pdata_after_propagation, prop_time_);
137 
138  double time_until_crossing = crossing_position[0] - t0;
139 
140  ParticleData outgoing_particle(p);
141  outgoing_particle.set_4position(crossing_position);
142  ActionPtr action = std::make_unique<HypersurfacecrossingAction>(
143  p, outgoing_particle, time_until_crossing);
144  actions.emplace_back(std::move(action));
145  }
146  }
147  return actions;
148 }
149 
151  ParticleData &pdata_before_propagation,
152  ParticleData &pdata_after_propagation, const double tau) const {
153  bool hypersurface_is_crossed = false;
154  const bool t_greater_z_before_prop =
155  (std::fabs(pdata_before_propagation.position().x0()) >
156  std::fabs(pdata_before_propagation.position().x3())
157  ? true
158  : false);
159  const bool t_greater_z_after_prop =
160  (std::fabs(pdata_after_propagation.position().x0()) >
161  std::fabs(pdata_after_propagation.position().x3())
162  ? true
163  : false);
164 
165  if (t_greater_z_before_prop && t_greater_z_after_prop) {
166  // proper time before and after propagation
167  const double tau_before = pdata_before_propagation.position().tau();
168  const double tau_after = pdata_after_propagation.position().tau();
169 
170  if (tau_before <= tau && tau <= tau_after) {
171  hypersurface_is_crossed = true;
172  }
173  } else if (!t_greater_z_before_prop && t_greater_z_after_prop) {
174  // proper time after propagation
175  const double tau_after = pdata_after_propagation.position().tau();
176  if (tau_after >= tau) {
177  hypersurface_is_crossed = true;
178  }
179  }
180 
181  return hypersurface_is_crossed;
182 }
183 
185  ParticleData &pdata_before_propagation,
186  ParticleData &pdata_after_propagation, const double tau) const {
187  // find t and z at start of propagation
188  const double t1 = pdata_before_propagation.position().x0();
189  const double z1 = pdata_before_propagation.position().x3();
190 
191  // find t and z after propagation
192  const double t2 = pdata_after_propagation.position().x0();
193  const double z2 = pdata_after_propagation.position().x3();
194 
195  // find slope and intercept of linear function that describes propagation on
196  // straight line
197  const double m = (z2 - z1) / (t2 - t1);
198  const double n = z1 - m * t1;
199 
200  // The equation to solve is a quadratic equation which provides two solutions,
201  // the latter is usually out of the t-interval we are looking at.
202  const double sol1 = n * m / (1 - m * m) +
203  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
204  [[maybe_unused]] const double sol2 = // only used in DEBUG output
205  n * m / (1 - m * m) -
206  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
207 
208  assert((sol1 >= t1 && sol1 <= t2));
209  assert(!(sol2 >= t1 && sol2 <= t2));
210 
211  // Propagate to point where hypersurface is crossed
212  const ThreeVector v = pdata_before_propagation.velocity();
213  const FourVector distance = FourVector(0.0, v * (sol1 - t1));
214  FourVector crossing_position = pdata_before_propagation.position() + distance;
215  crossing_position.set_x0(sol1);
216 
217  return crossing_position;
218 }
219 
220 } // namespace smash
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:363
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:355
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double x3() const
Definition: fourvector.h:325
double x0() const
Definition: fourvector.h:313
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:333
void set_x0(double t)
Definition: fourvector.h:315
double tau() const
calculate the proper time from the given four vector
Definition: fourvector.h:478
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.
double check_conservation(const uint32_t id_process) const override
Check various conservation laws.
void generate_final_state() override
Generate the final state of the hypersurface crossing particles.
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
constexpr int p
Proton.
constexpr int n
Neutron.
Definition: action.h:24
static constexpr int LHyperSurfaceCrossing
Definition: binaryoutput.cc:22