Version: SMASH-1.7
hypersurfacecrossingaction.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019-2019
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
11 
12 #include "smash/logging.h"
13 #include "smash/particledata.h"
14 #include "smash/particles.h"
15 #include "smash/quantumnumbers.h"
16 
17 namespace smash {
18 
20  const auto &log = logger<LogArea::HyperSurfaceCrossing>();
21  log.debug("Process: Hypersurface Crossing. ");
22 
23  ParticleList empty_list;
24 
25  // check that there is only 1 incoming particle
26  assert(incoming_particles_.size() == 1);
27 
28  // Return empty list because we want to remove the incoming particle
29  outgoing_particles_ = empty_list;
30 }
31 
33  const uint32_t id_process) const {
36  if (before == after) {
37  // Conservation laws should not be conserved since particles are removed
38  // from the evolution
39  throw std::runtime_error(
40  "Conservation laws conserved in the hypersurface "
41  "crossing action. Particle was not properly removed in process: " +
42  std::to_string(id_process));
43  }
44 
45  if (outgoing_particles_.size() != 0) {
46  throw std::runtime_error(
47  "Particle was not removed successfully in "
48  "hypersurface crossing action.");
49  }
50 }
51 
53  const ParticleList &plist, double dt, const double,
54  const std::vector<FourVector> &beam_momentum) const {
55  std::vector<ActionPtr> actions;
56 
57  for (const ParticleData &p : plist) {
58  ParticleData pdata_before_propagation = p;
59  ParticleData pdata_after_propagation = p; // Will receive updated position
60  double t0 = p.position().x0();
61  double t_end = t0 + dt; // Time at the end of timestep
62 
63  // We don't want to remove particles before the nuclei have interacted
64  // because those would not yet be part of the newly-created medium.
65  if (t_end < 0.0) {
66  continue;
67  }
68 
69  // For frozen Fermi motion:
70  // Fermi momenta are only applied if particles interact. The particle
71  // properties p.velocity() and p.momentum() already contain the values
72  // corrected by Fermi motion, but those particles that have not yet
73  // interacted are propagated along the beam-axis with v = (0, 0, beam_v)
74  // (and not with p.velocity()).
75  // To identify the corresponding hypersurface crossings the finding for
76  // those paricles without prior interactions has to be performed with
77  // v = vbeam instead of p.velcocity().
78  // Note: The beam_momentum vector is empty in case frozen Fermi motion is
79  // not applied.
80  const bool no_prior_interactions =
81  (static_cast<uint64_t>(p.id()) < // particle from
82  static_cast<uint64_t>(beam_momentum.size())) && // initial nucleus
83  (p.get_history().collisions_per_particle == 0);
84  ThreeVector v;
85  if (no_prior_interactions) {
86  const FourVector vbeam = beam_momentum[p.id()];
87  v = vbeam.velocity();
88  } else {
89  v = p.velocity();
90  }
91 
92  // propagate particles to position where they would be at the end of the
93  // time step (after dt)
94  const FourVector distance = FourVector(0.0, v * dt);
95  FourVector position = p.position() + distance;
96  position.set_x0(t_end);
97  // update coordinates to the position corresponding to t_end
98  pdata_after_propagation.set_4position(position);
99 
100  bool hypersurface_is_crossed = crosses_hypersurface(
101  pdata_before_propagation, pdata_after_propagation, prop_time_);
102 
103  if (hypersurface_is_crossed) {
104  // Get exact coordinates where hypersurface is crossed
105  FourVector crossing_position = coordinates_on_hypersurface(
106  pdata_before_propagation, pdata_after_propagation, prop_time_);
107 
108  double time_until_crossing = crossing_position[0] - t0;
109 
110  ParticleData outgoing_particle(p);
111  outgoing_particle.set_4position(crossing_position);
112  ActionPtr action = make_unique<HypersurfacecrossingAction>(
113  p, outgoing_particle, time_until_crossing);
114  actions.emplace_back(std::move(action));
115  }
116  }
117  return actions;
118 }
119 
121  ParticleData &pdata_before_propagation,
122  ParticleData &pdata_after_propagation, const double tau) const {
123  bool hypersurface_is_crossed = false;
124  const bool t_greater_z_before_prop =
125  (fabs(pdata_before_propagation.position().x0()) >
126  fabs(pdata_before_propagation.position().x3())
127  ? 1
128  : 0);
129  const bool t_greater_z_after_prop =
130  (fabs(pdata_after_propagation.position().x0()) >
131  fabs(pdata_after_propagation.position().x3())
132  ? 1
133  : 0);
134 
135  if (t_greater_z_before_prop && t_greater_z_after_prop) {
136  // proper time before and after propagation
137  const double tau_before = pdata_before_propagation.position().tau();
138  const double tau_after = pdata_after_propagation.position().tau();
139 
140  if (tau_before <= tau && tau <= tau_after) {
141  hypersurface_is_crossed = true;
142  }
143  } else if (!t_greater_z_before_prop && t_greater_z_after_prop) {
144  // proper time after propagation
145  const double tau_after = pdata_after_propagation.position().tau();
146  if (tau_after >= tau) {
147  hypersurface_is_crossed = true;
148  }
149  }
150 
151  return hypersurface_is_crossed;
152 }
153 
155  ParticleData &pdata_before_propagation,
156  ParticleData &pdata_after_propagation, const double tau) const {
157  // find t and z at start of propagation
158  const double t1 = pdata_before_propagation.position().x0();
159  const double z1 = pdata_before_propagation.position().x3();
160 
161  // find t and z after propagation
162  const double t2 = pdata_after_propagation.position().x0();
163  const double z2 = pdata_after_propagation.position().x3();
164 
165  // find slope and intercept of linear function that describes propagation on
166  // straight line
167  const double m = (z2 - z1) / (t2 - t1);
168  const double n = z1 - m * t1;
169 
170  // The equation to solve is a quadratic equation which provides two solutions,
171  // the latter is usually out of the t-interval we are looking at.
172  const double sol1 = n * m / (1 - m * m) +
173  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
174  const double sol2 = n * m / (1 - m * m) -
175  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
176 
177  SMASH_UNUSED(sol2); // only used in DEBUG output
178  assert((sol1 >= t1 && sol1 <= t2));
179  assert(!(sol2 >= t1 && sol2 <= t2));
180 
181  // Propagate to point where hypersurface is crossed
182  const ThreeVector v = pdata_before_propagation.velocity();
183  const FourVector distance = FourVector(0.0, v * (sol1 - t1));
184  FourVector crossing_position = pdata_before_propagation.position() + distance;
185  crossing_position.set_x0(sol1);
186 
187  return crossing_position;
188 }
189 
190 } // namespace smash
void generate_final_state() override
Generate the final state of the hypersurface crossing particles.
#define SMASH_UNUSED(x)
Mark as unused, silencing compiler warnings.
Definition: macros.h:24
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
const FourVector & position() const
Get the particle&#39;s position in Minkowski space.
Definition: particledata.h:185
void check_conservation(const uint32_t id_process) const override
Check various conservation laws.
double tau() const
calculate the proper time from the given four vector
Definition: fourvector.h:468
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:282
double x0() const
Definition: fourvector.h:303
void set_x0(double t)
Definition: fourvector.h:305
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:311
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:323
double x3() const
Definition: fourvector.h:315
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:303
A container for storing conserved values.
constexpr int p
Proton.
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 set_4position(const FourVector &pos)
Set the particle&#39;s 4-position directly.
Definition: particledata.h:190
FourVector coordinates_on_hypersurface(ParticleData &pdata_before_propagation, ParticleData &pdata_after_propagation, const double tau) const
Find the coordinates where particle crosses hypersurface.
constexpr int n
Neutron.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
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...
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:52
Definition: action.h:24