Version: SMASH-1.5
action.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/action.h"
11 
12 #include <assert.h>
13 #include <algorithm>
14 #include <sstream>
15 
16 #include "smash/angles.h"
17 #include "smash/constants.h"
18 #include "smash/kinematics.h"
19 #include "smash/logging.h"
20 #include "smash/pauliblocking.h"
22 #include "smash/processbranch.h"
23 #include "smash/quantumnumbers.h"
24 
25 namespace smash {
27 Action::~Action() = default;
28 
29 bool Action::is_valid(const Particles &particles) const {
30  return std::all_of(
32  [&particles](const ParticleData &p) { return particles.is_valid(p); });
33 }
34 
35 bool Action::is_pauli_blocked(const Particles &particles,
36  const PauliBlocker &p_bl) const {
37  // Wall-crossing actions should never be blocked: currently
38  // if the action is blocked, a particle continues to propagate in a straight
39  // line. This would simply bring it out of the box.
41  return false;
42  }
43  const auto &log = logger<LogArea::PauliBlocking>();
44  for (const auto &p : outgoing_particles_) {
45  if (p.is_baryon()) {
46  const auto f =
47  p_bl.phasespace_dens(p.position().threevec(), p.momentum().threevec(),
48  particles, p.pdgcode(), incoming_particles_);
49  if (f > random::uniform(0., 1.)) {
50  log.debug("Action ", *this, " is pauli-blocked with f = ", f);
51  return true;
52  }
53  }
54  }
55  return false;
56 }
57 
58 const ParticleList &Action::incoming_particles() const {
59  return incoming_particles_;
60 }
61 
62 void Action::update_incoming(const Particles &particles) {
63  for (auto &p : incoming_particles_) {
64  p = particles.lookup(p);
65  }
66 }
67 
69  // Estimate for the interaction point in the calculational frame
70  FourVector interaction_point = FourVector(0., 0., 0., 0.);
71  for (const auto &part : incoming_particles_) {
72  interaction_point += part.position();
73  }
74  interaction_point /= incoming_particles_.size();
75  return interaction_point;
76 }
77 
78 std::pair<FourVector, FourVector> Action::get_potential_at_interaction_point()
79  const {
81  FourVector UB = FourVector();
82  FourVector UI3 = FourVector();
83  /* Check:
84  * Lattice is turned on. */
85  if (UB_lat_pointer != nullptr) {
86  UB_lat_pointer->value_at(r, UB);
87  }
88  if (UI3_lat_pointer != nullptr) {
89  UI3_lat_pointer->value_at(r, UI3);
90  }
91  return std::make_pair(UB, UI3);
92 }
93 
94 void Action::perform(Particles *particles, uint32_t id_process) {
95  assert(id_process != 0);
96  const auto &log = logger<LogArea::Action>();
97 
99  // store the history info
101  p.set_history(p.get_history().collisions_per_particle + 1, id_process,
103  }
104  }
105 
106  /* For elastic collisions and box wall crossings it is not necessary to remove
107  * particles from the list and insert new ones, it is enough to update their
108  * properties. */
112 
113  log.debug("Particle map now has ", particles->size(), " elements.");
114 
115  /* Check the conservation laws if the modifications of the total kinetic
116  * energy of the outgoing particles by the mean field potentials are not
117  * taken into account. */
118  if (UB_lat_pointer == nullptr && UI3_lat_pointer == nullptr) {
119  check_conservation(id_process);
120  }
121 }
122 
124  const auto potentials = get_potential_at_interaction_point();
125  /* scale_B returns the difference of the total force scales of the skyrme
126  * potential between the initial and final states. */
127  double scale_B = 0.0;
128  /* scale_I3 returns the difference of the total force scales of the symmetry
129  * potential between the initial and final states. */
130  double scale_I3 = 0.0;
131  for (const auto &p_in : incoming_particles_) {
132  // Get the force scale of the incoming particle.
133  const auto scale =
134  ((pot_pointer != nullptr) ? pot_pointer->force_scale(p_in.type())
135  : std::make_pair(0.0, 0));
136  scale_B += scale.first;
137  scale_I3 += scale.second * p_in.type().isospin3_rel();
138  }
139  for (const auto &p_out : outgoing_particles_) {
140  // Get the force scale of the outgoing particle.
141  const auto scale = ((pot_pointer != nullptr)
143  : std::make_pair(0.0, 0));
144  scale_B -= scale.first;
145  scale_I3 -= scale.second * type_of_pout(p_out).isospin3_rel();
146  }
147  /* Rescale to get the potential difference between the
148  * initial and final state, and thus get the total momentum
149  * of the outgoing particles*/
150  return total_momentum() + potentials.first * scale_B +
151  potentials.second * scale_I3;
152 }
153 
154 std::pair<double, double> Action::sample_masses(
155  const double kinetic_energy_cm) const {
156  const ParticleType &t_a = outgoing_particles_[0].type();
157  const ParticleType &t_b = outgoing_particles_[1].type();
158  // start with pole masses
159  std::pair<double, double> masses = {t_a.mass(), t_b.mass()};
160 
161  if (kinetic_energy_cm < t_a.min_mass_kinematic() + t_b.min_mass_kinematic()) {
162  const std::string reaction = incoming_particles_[0].type().name() +
163  incoming_particles_[1].type().name() + "→" +
164  t_a.name() + t_b.name();
166  reaction + ": not enough energy, " + std::to_string(kinetic_energy_cm) +
167  " < " + std::to_string(t_a.min_mass_kinematic()) + " + " +
168  std::to_string(t_b.min_mass_kinematic()));
169  }
170 
171  /* If one of the particles is a resonance, sample its mass. */
172  if (!t_a.is_stable() && t_b.is_stable()) {
173  masses.first = t_a.sample_resonance_mass(t_b.mass(), kinetic_energy_cm);
174  } else if (!t_b.is_stable() && t_a.is_stable()) {
175  masses.second = t_b.sample_resonance_mass(t_a.mass(), kinetic_energy_cm);
176  } else if (!t_a.is_stable() && !t_b.is_stable()) {
177  // two resonances in final state
178  masses = t_a.sample_resonance_masses(t_b, kinetic_energy_cm);
179  }
180  return masses;
181 }
182 
183 void Action::sample_angles(std::pair<double, double> masses,
184  const double kinetic_energy_cm) {
185  const auto &log = logger<LogArea::Action>();
186 
189 
190  const double pcm = pCM(kinetic_energy_cm, masses.first, masses.second);
191  if (!(pcm > 0.0)) {
192  log.warn("Particle: ", p_a->pdgcode(), " radial momentum: ", pcm);
193  log.warn("Ektot: ", kinetic_energy_cm, " m_a: ", masses.first,
194  " m_b: ", masses.second);
195  }
196  /* Here we assume an isotropic angular distribution. */
197  Angles phitheta;
198  phitheta.distribute_isotropically();
199 
200  p_a->set_4momentum(masses.first, phitheta.threevec() * pcm);
201  p_b->set_4momentum(masses.second, -phitheta.threevec() * pcm);
202  /* Debug message is printed before boost, so that p_a and p_b are
203  * the momenta in the center of mass frame and thus opposite to
204  * each other.*/
205  log.debug("p_a: ", *p_a, "\np_b: ", *p_b);
206 }
207 
209  /* This function only operates on 2-particle final states. */
210  assert(outgoing_particles_.size() == 2);
212  const double cm_kin_energy = p_tot.abs();
213  // first sample the masses
214  const std::pair<double, double> masses = sample_masses(cm_kin_energy);
215  // after the masses are fixed (and thus also pcm), sample the angles
216  sample_angles(masses, cm_kin_energy);
217 }
218 
219 void Action::check_conservation(const uint32_t id_process) const {
222  if (before != after) {
223  std::stringstream particle_names;
224  for (const auto &p : incoming_particles_) {
225  particle_names << p.type().name();
226  }
227  particle_names << " vs. ";
228  for (const auto &p : outgoing_particles_) {
229  particle_names << p.type().name();
230  }
231  particle_names << "\n";
232  const auto &log = logger<LogArea::Action>();
233  std::string err_msg = before.report_deviations(after);
234  log.error() << particle_names.str() << err_msg;
235  /* Pythia does not conserve energy and momentum at high energy, so we just
236  * print the error and continue. */
239  return;
240  }
241  if (id_process == ID_PROCESS_PHOTON) {
242  throw std::runtime_error("Conservation laws violated in photon process");
243  } else {
244  throw std::runtime_error("Conservation laws violated in process " +
245  std::to_string(id_process));
246  }
247  }
248 }
249 
250 std::ostream &operator<<(std::ostream &out, const ActionList &actions) {
251  out << "ActionList {\n";
252  for (const auto &a : actions) {
253  out << "- " << a << '\n';
254  }
255  return out << '}';
256 }
257 
258 } // namespace smash
Potentials * pot_pointer
Pointer to a Potential class.
double mass() const
Definition: particletype.h:134
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:30
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:68
double sample_resonance_mass(const double mass_stable, const double cms_energy, int L=0) const
Resonance mass sampling for 2-particle final state with one resonance (type given by &#39;this&#39;) and one ...
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
double phasespace_dens(const ThreeVector &r, const ThreeVector &p, const Particles &particles, const PdgCode pdg, const ParticleList &disregard) const
Calculate phase-space density of a particle species at the point (r,p).
constexpr std::uint32_t ID_PROCESS_PHOTON
Process ID for any photon process.
Definition: constants.h:128
RectangularLattice< FourVector > * UI3_lat_pointer
Pointer to the symmmetry potential on the lattice.
ProcessType process_type_
type of process
Definition: action.h:320
Collection of useful constants that are known at compile time.
const ParticleData & lookup(const ParticleData &old_state) const
Returns the particle that is currently stored in this object given an old copy of that particle...
Definition: particles.h:222
ThreeVector threevec() const
Definition: angles.h:268
FourVector total_momentum() const
Sum of 4-momenta of incoming particles.
Definition: action.h:323
bool is_valid(const Particles &particles) const
Check whether the action still applies.
Definition: action.cc:29
bool is_valid(const ParticleData &copy) const
Check whether the ParticleData copy is still a valid copy of the one stored in the Particles object...
Definition: particles.h:120
void update_incoming(const Particles &particles)
Update the incoming particles that are stored in this action to the state they have in the global par...
Definition: action.cc:62
std::pair< double, int > force_scale(const ParticleType &data) const
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:135
virtual void sample_angles(std::pair< double, double > masses, double kinetic_energy_cm)
Sample final-state momenta in general X->2 processes (here: using an isotropical angular distribution...
Definition: action.cc:183
double isospin3_rel() const
Definition: particletype.h:169
void update(const ParticleList &old_state, ParticleList &new_state, bool do_replace)
Updates the Particles object, replacing the particles in old_state with the particles in new_state...
Definition: particles.h:200
size_t size() const
Definition: particles.h:87
RectangularLattice< FourVector > * UB_lat_pointer
Pointer to the skyrme potential on the lattice.
ThreeVector threevec() const
Definition: fourvector.h:306
elastic scattering: particles remain the same, only momenta change
std::string report_deviations(const Particles &particles) const
Checks if the current particle list has still the same values and reports about differences.
Thrown for example when ScatterAction is called to perform with a wrong number of final-state particl...
Definition: action.h:297
bool is_stable() const
Definition: particletype.h:226
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:311
Particle type contains the static properties of a particle species.
Definition: particletype.h:87
void set_4momentum(const FourVector &momentum_vector)
Set the particle&#39;s 4-momentum directly.
Definition: particledata.h:145
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:303
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:58
A container for storing conserved values.
hard string process involving 2->2 QCD process by PYTHIA.
std::pair< FourVector, FourVector > get_potential_at_interaction_point() const
Get the skyrme and asymmetry potential at the interaction point.
Definition: action.cc:78
box wall crossing
const ParticleType & type_of_pout(const ParticleData &p_out) const
Get the type of a given particle.
Definition: action.h:419
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:123
T uniform(T min, T max)
Definition: random.h:85
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80
A class that stores parameters needed for Pauli blocking, tabulates necessary integrals and computes ...
Definition: pauliblocking.h:36
virtual std::pair< double, double > sample_masses(double kinetic_energy_cm) const
Sample final-state masses in general X->2 processes (thus also fixing the absolute c...
Definition: action.cc:154
std::pair< double, double > sample_resonance_masses(const ParticleType &t2, const double cms_energy, int L=0) const
Resonance mass sampling for 2-particle final state with two resonances.
constexpr int p
Proton.
void sample_2body_phasespace()
Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:208
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
void distribute_isotropically()
Populate the object with a new direction.
Definition: angles.h:188
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
bool is_pauli_blocked(const Particles &particles, const PauliBlocker &p_bl) const
Check if the action is Pauli-blocked.
Definition: action.cc:35
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:457
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:32
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:52
void check_conservation(const uint32_t id_process) const
Check various conservation laws.
Definition: action.cc:219
virtual ~Action()
Virtual Destructor.
Definition: action.h:24
const double time_of_execution_
Time at which the action is supposed to be performed (absolute time in the lab frame in fm/c)...
Definition: action.h:317
virtual void perform(Particles *particles, uint32_t id_process)
Actually perform the action, e.g.
Definition: action.cc:94
const std::string & name() const
Definition: particletype.h:131