21   ParticleList empty_list;
 
   31     const uint32_t id_process)
 const {
 
   34   if (before == after) {
 
   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));
 
   44     throw std::runtime_error(
 
   45         "Particle was not removed successfully in " 
   46         "hypersurface crossing action.");
 
   51     const ParticleList &plist, 
double dt, 
const double,
 
   52     const std::vector<FourVector> &beam_momentum)
 const {
 
   53   std::vector<ActionPtr> actions;
 
   58     double t0 = 
p.position().x0();
 
   59     double t_end = t0 + dt;  
 
   78     const bool no_prior_interactions =
 
   79         (static_cast<uint64_t>(
p.id()) <                  
 
   80          static_cast<uint64_t>(beam_momentum.size())) &&  
 
   81         (
p.get_history().collisions_per_particle == 0);
 
   83     if (no_prior_interactions) {
 
   99         pdata_before_propagation, pdata_after_propagation, 
prop_time_);
 
  101     if (hypersurface_is_crossed) {
 
  104           pdata_before_propagation, pdata_after_propagation, 
prop_time_);
 
  106       double time_until_crossing = crossing_position[0] - t0;
 
  110       ActionPtr action = make_unique<HypersurfacecrossingAction>(
 
  111           p, outgoing_particle, time_until_crossing);
 
  112       actions.emplace_back(std::move(action));
 
  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())
 
  127   const bool t_greater_z_after_prop =
 
  128       (std::fabs(pdata_after_propagation.
position().
x0()) >
 
  129                std::fabs(pdata_after_propagation.
position().
x3())
 
  133   if (t_greater_z_before_prop && t_greater_z_after_prop) {
 
  135     const double tau_before = pdata_before_propagation.
position().
tau();
 
  136     const double tau_after = pdata_after_propagation.
position().
tau();
 
  138     if (tau_before <= tau && tau <= tau_after) {
 
  139       hypersurface_is_crossed = 
true;
 
  141   } 
else if (!t_greater_z_before_prop && t_greater_z_after_prop) {
 
  143     const double tau_after = pdata_after_propagation.
position().
tau();
 
  144     if (tau_after >= tau) {
 
  145       hypersurface_is_crossed = 
true;
 
  149   return hypersurface_is_crossed;
 
  154     ParticleData &pdata_after_propagation, 
const double tau)
 const {
 
  156   const double t1 = pdata_before_propagation.
position().
x0();
 
  157   const double z1 = pdata_before_propagation.
position().
x3();
 
  160   const double t2 = pdata_after_propagation.
position().
x0();
 
  161   const double z2 = pdata_after_propagation.
position().
x3();
 
  165   const double m = (z2 - z1) / (t2 - t1);
 
  166   const double n = z1 - m * t1;
 
  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);
 
  176   assert((sol1 >= t1 && sol1 <= t2));
 
  177   assert(!(sol2 >= t1 && sol2 <= t2));
 
  183   crossing_position.
set_x0(sol1);
 
  185   return crossing_position;