Version: SMASH-1.8
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 static constexpr int LHyperSurfaceCrossing = LogArea::HyperSurfaceCrossing::id;
19 
21  logg[LHyperSurfaceCrossing].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
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:52
smash
Definition: action.h:24
smash::Action::incoming_particles_
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:304
quantumnumbers.h
particledata.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:20
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:32
smash::HyperSurfaceCrossActionsFinder::prop_time_
const double prop_time_
Proper time of the hypersurface in fm.
Definition: hypersurfacecrossingaction.h:102
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:120
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:188
smash::LHyperSurfaceCrossing
static constexpr int LHyperSurfaceCrossing
Definition: hypersurfacecrossingaction.cc:18
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:154
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:312
particles.h
logging.h
smash::ParticleData::set_4position
void set_4position(const FourVector &pos)
Set the particle's 4-position directly.
Definition: particledata.h:193
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:285
smash::QuantumNumbers
Definition: quantumnumbers.h:53