Version: SMASH-2.0
hypersurfacecrossingaction.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019-2020
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  if (hypersurface_is_crossed) {
102  // Get exact coordinates where hypersurface is crossed
103  FourVector crossing_position = coordinates_on_hypersurface(
104  pdata_before_propagation, pdata_after_propagation, prop_time_);
105 
106  double time_until_crossing = crossing_position[0] - t0;
107 
108  ParticleData outgoing_particle(p);
109  outgoing_particle.set_4position(crossing_position);
110  ActionPtr action = make_unique<HypersurfacecrossingAction>(
111  p, outgoing_particle, time_until_crossing);
112  actions.emplace_back(std::move(action));
113  }
114  }
115  return actions;
116 }
117 
119  ParticleData &pdata_before_propagation,
120  ParticleData &pdata_after_propagation, const double tau) const {
121  bool hypersurface_is_crossed = false;
122  const bool t_greater_z_before_prop =
123  (std::fabs(pdata_before_propagation.position().x0()) >
124  std::fabs(pdata_before_propagation.position().x3())
125  ? 1
126  : 0);
127  const bool t_greater_z_after_prop =
128  (std::fabs(pdata_after_propagation.position().x0()) >
129  std::fabs(pdata_after_propagation.position().x3())
130  ? 1
131  : 0);
132 
133  if (t_greater_z_before_prop && t_greater_z_after_prop) {
134  // proper time before and after propagation
135  const double tau_before = pdata_before_propagation.position().tau();
136  const double tau_after = pdata_after_propagation.position().tau();
137 
138  if (tau_before <= tau && tau <= tau_after) {
139  hypersurface_is_crossed = true;
140  }
141  } else if (!t_greater_z_before_prop && t_greater_z_after_prop) {
142  // proper time after propagation
143  const double tau_after = pdata_after_propagation.position().tau();
144  if (tau_after >= tau) {
145  hypersurface_is_crossed = true;
146  }
147  }
148 
149  return hypersurface_is_crossed;
150 }
151 
153  ParticleData &pdata_before_propagation,
154  ParticleData &pdata_after_propagation, const double tau) const {
155  // find t and z at start of propagation
156  const double t1 = pdata_before_propagation.position().x0();
157  const double z1 = pdata_before_propagation.position().x3();
158 
159  // find t and z after propagation
160  const double t2 = pdata_after_propagation.position().x0();
161  const double z2 = pdata_after_propagation.position().x3();
162 
163  // find slope and intercept of linear function that describes propagation on
164  // straight line
165  const double m = (z2 - z1) / (t2 - t1);
166  const double n = z1 - m * t1;
167 
168  // The equation to solve is a quadratic equation which provides two solutions,
169  // the latter is usually out of the t-interval we are looking at.
170  const double sol1 = n * m / (1 - m * m) +
171  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
172  const double sol2 = n * m / (1 - m * m) -
173  std::sqrt((1 - m * m) * tau * tau + n * n) / (1 - m * m);
174 
175  SMASH_UNUSED(sol2); // only used in DEBUG output
176  assert((sol1 >= t1 && sol1 <= t2));
177  assert(!(sol2 >= t1 && sol2 <= t2));
178 
179  // Propagate to point where hypersurface is crossed
180  const ThreeVector v = pdata_before_propagation.velocity();
181  const FourVector distance = FourVector(0.0, v * (sol1 - t1));
182  FourVector crossing_position = pdata_before_propagation.position() + distance;
183  crossing_position.set_x0(sol1);
184 
185  return crossing_position;
186 }
187 
188 } // namespace smash
smash::HyperSurfaceCrossActionsFinder::find_actions_in_cell
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...
Definition: hypersurfacecrossingaction.cc:50
smash
Definition: action.h:24
smash::Action::incoming_particles_
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:326
quantumnumbers.h
smash::ParticleData
Definition: particledata.h:52
hypersurfacecrossingaction.h
smash::HypersurfacecrossingAction::generate_final_state
void generate_final_state() override
Generate the final state of the hypersurface crossing particles.
Definition: hypersurfacecrossingaction.cc:18
smash::FourVector::x3
double x3() const
Definition: fourvector.h:315
smash::FourVector::set_x0
void set_x0(double t)
Definition: fourvector.h:305
smash::HypersurfacecrossingAction::check_conservation
void check_conservation(const uint32_t id_process) const override
Check various conservation laws.
Definition: hypersurfacecrossingaction.cc:30
smash::HyperSurfaceCrossActionsFinder::prop_time_
const double prop_time_
Proper time of the hypersurface in fm.
Definition: hypersurfacecrossingaction.h:104
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::ThreeVector
Definition: threevector.h:31
smash::HyperSurfaceCrossActionsFinder::crosses_hypersurface
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.
Definition: hypersurfacecrossingaction.cc:118
smash::FourVector::x0
double x0() const
Definition: fourvector.h:303
smash::FourVector::tau
double tau() const
calculate the proper time from the given four vector
Definition: fourvector.h:468
smash::ParticleData::position
const FourVector & position() const
Get the particle's position in Minkowski space.
Definition: particledata.h:198
smash::LHyperSurfaceCrossing
static constexpr int LHyperSurfaceCrossing
Definition: hypersurfacecrossingaction.cc:16
smash::HyperSurfaceCrossActionsFinder::coordinates_on_hypersurface
FourVector coordinates_on_hypersurface(ParticleData &pdata_before_propagation, ParticleData &pdata_after_propagation, const double tau) const
Find the coordinates where particle crosses hypersurface.
Definition: hypersurfacecrossingaction.cc:152
smash::FourVector::velocity
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
Definition: fourvector.h:323
SMASH_UNUSED
#define SMASH_UNUSED(x)
Mark as unused, silencing compiler warnings.
Definition: macros.h:24
smash::Action::outgoing_particles_
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:334
logging.h
smash::ParticleData::set_4position
void set_4position(const FourVector &pos)
Set the particle's 4-position directly.
Definition: particledata.h:203
smash::FourVector
Definition: fourvector.h:33
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::pdg::n
constexpr int n
Neutron.
Definition: pdgcode_constants.h:30
smash::ParticleData::velocity
ThreeVector velocity() const
Get the velocity 3-vector.
Definition: particledata.h:295
smash::QuantumNumbers
Definition: quantumnumbers.h:53