Version: SMASH-2.1
action.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2021
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/logging.h"
19 #include "smash/pauliblocking.h"
21 #include "smash/quantumnumbers.h"
22 
23 namespace smash {
25 Action::~Action() = default;
26 static constexpr int LPauliBlocking = LogArea::PauliBlocking::id;
27 
28 bool Action::is_valid(const Particles &particles) const {
29  return std::all_of(
31  [&particles](const ParticleData &p) { return particles.is_valid(p); });
32 }
33 
34 bool Action::is_pauli_blocked(const std::vector<Particles> &ensembles,
35  const PauliBlocker &p_bl) const {
36  // Wall-crossing actions should never be blocked: currently
37  // if the action is blocked, a particle continues to propagate in a straight
38  // line. This would simply bring it out of the box.
40  return false;
41  }
42  for (const auto &p : outgoing_particles_) {
43  if (p.is_baryon()) {
44  const auto f =
45  p_bl.phasespace_dens(p.position().threevec(), p.momentum().threevec(),
46  ensembles, p.pdgcode(), incoming_particles_);
47  if (f > random::uniform(0., 1.)) {
48  logg[LPauliBlocking].debug("Action ", *this,
49  " is pauli-blocked with f = ", f);
50  return true;
51  }
52  }
53  }
54  return false;
55 }
56 
57 const ParticleList &Action::incoming_particles() const {
58  return incoming_particles_;
59 }
60 
61 void Action::update_incoming(const Particles &particles) {
62  for (auto &p : incoming_particles_) {
63  p = particles.lookup(p);
64  }
65 }
66 
68  // Estimate for the interaction point in the calculational frame
69  FourVector interaction_point = FourVector(0., 0., 0., 0.);
70  for (const auto &part : incoming_particles_) {
71  interaction_point += part.position();
72  }
73  interaction_point /= incoming_particles_.size();
74  /*
75  * In case of periodic boundaries interaction point is not necessarily
76  * (x1 + x2)/2. Consider only one dimension, e.g. x, the rest are analogous.
77  * Instead of x, there can be x + k * L, where k is any integer and L
78  * is period.Interaction point is either. Therefore, interaction point is
79  * (x1 + k * L + x2 + m * L) / 2 = (x1 + x2) / 2 + n * L / 2. We need
80  * this interaction point to be with [0, L], so n can be {-1, 0, 1}.
81  * Which n to choose? Our guiding principle is that n should be such that
82  * interaction point is closest to interacting particles.
83  */
84  if (box_length_ > 0 && stochastic_position_idx_ < 0) {
85  assert(incoming_particles_.size() == 2);
86  const FourVector r1 = incoming_particles_[0].position(),
87  r2 = incoming_particles_[1].position(), r = r1 - r2;
88  for (int i = 1; i < 4; i++) {
89  const double d = std::abs(r[i]);
90  if (d > 0.5 * box_length_) {
91  if (interaction_point[i] >= 0.5 * box_length_) {
92  interaction_point[i] -= 0.5 * box_length_;
93  } else {
94  interaction_point[i] += 0.5 * box_length_;
95  }
96  }
97  }
98  }
99  /* In case of scatterings via the stochastic criterion, use postion of random
100  * incoming particle to prevent density hotspots in grid cell centers. */
101  if (stochastic_position_idx_ >= 0) {
102  interaction_point =
104  }
105  return interaction_point;
106 }
107 
108 std::pair<FourVector, FourVector> Action::get_potential_at_interaction_point()
109  const {
111  FourVector UB = FourVector();
112  FourVector UI3 = FourVector();
113  /* Check:
114  * Lattice is turned on. */
115  if (UB_lat_pointer != nullptr) {
116  UB_lat_pointer->value_at(r, UB);
117  }
118  if (UI3_lat_pointer != nullptr) {
119  UI3_lat_pointer->value_at(r, UI3);
120  }
121  return std::make_pair(UB, UI3);
122 }
123 
124 void Action::perform(Particles *particles, uint32_t id_process) {
125  assert(id_process != 0);
126 
128  // store the history info
130  p.set_history(p.get_history().collisions_per_particle + 1, id_process,
132  }
133  }
134 
135  /* For elastic collisions and box wall crossings it is not necessary to remove
136  * particles from the list and insert new ones, it is enough to update their
137  * properties. */
141 
142  logg[LAction].debug("Particle map now has ", particles->size(), " elements.");
143 
144  /* Check the conservation laws if the modifications of the total kinetic
145  * energy of the outgoing particles by the mean field potentials are not
146  * taken into account. */
147  if (UB_lat_pointer == nullptr && UI3_lat_pointer == nullptr) {
148  check_conservation(id_process);
149  }
150 }
151 
153  const auto potentials = get_potential_at_interaction_point();
154  /* scale_B returns the difference of the total force scales of the skyrme
155  * potential between the initial and final states. */
156  double scale_B = 0.0;
157  /* scale_I3 returns the difference of the total force scales of the symmetry
158  * potential between the initial and final states. */
159  double scale_I3 = 0.0;
160  for (const auto &p_in : incoming_particles_) {
161  // Get the force scale of the incoming particle.
162  const auto scale =
163  ((pot_pointer != nullptr) ? pot_pointer->force_scale(p_in.type())
164  : std::make_pair(0.0, 0));
165  scale_B += scale.first;
166  scale_I3 += scale.second * p_in.type().isospin3_rel();
167  }
168  for (const auto &p_out : outgoing_particles_) {
169  // Get the force scale of the outgoing particle.
170  const auto scale = ((pot_pointer != nullptr)
172  : std::make_pair(0.0, 0));
173  scale_B -= scale.first;
174  scale_I3 -= scale.second * type_of_pout(p_out).isospin3_rel();
175  }
176  /* Rescale to get the potential difference between the
177  * initial and final state, and thus get the total momentum
178  * of the outgoing particles*/
179  return total_momentum() + potentials.first * scale_B +
180  potentials.second * scale_I3;
181 }
182 
184  /* Find incoming particle with largest formation time i.e. the last formed
185  * incoming particle. If all particles form at the same time, take the one
186  * with the lowest cross section scaling factor */
187  ParticleList::iterator last_formed_in_part;
188  bool all_incoming_same_formation_time =
190  [&](const ParticleData &data_comp) {
191  return std::abs(incoming_particles_[0].formation_time() -
192  data_comp.formation_time()) < really_small;
193  });
194  if (all_incoming_same_formation_time) {
195  last_formed_in_part =
196  std::min_element(incoming_particles_.begin(), incoming_particles_.end(),
197  [](const ParticleData &a, const ParticleData &b) {
198  return a.initial_xsec_scaling_factor() <
199  b.initial_xsec_scaling_factor();
200  });
201  } else {
202  last_formed_in_part =
203  std::max_element(incoming_particles_.begin(), incoming_particles_.end(),
204  [](const ParticleData &a, const ParticleData &b) {
205  return a.formation_time() < b.formation_time();
206  });
207  }
208 
209  const double form_time_begin = last_formed_in_part->begin_formation_time();
210  const double sc = last_formed_in_part->initial_xsec_scaling_factor();
211 
212  if (last_formed_in_part->formation_time() > time_of_execution_) {
213  for (ParticleData &new_particle : outgoing_particles_) {
214  if (new_particle.initial_xsec_scaling_factor() < 1.0) {
215  /* The new cross section scaling factor will be the product of the
216  * cross section scaling factor of the ingoing particles and of the
217  * outgoing ones (since the outgoing ones are also string fragments
218  * and thus take time to form). */
219  double sc_out = new_particle.initial_xsec_scaling_factor();
220  new_particle.set_cross_section_scaling_factor(sc * sc_out);
221  if (last_formed_in_part->formation_time() >
222  new_particle.formation_time()) {
223  /* If the unformed incoming particles' formation time is larger than
224  * the current outgoing particle's formation time, then the latter
225  * is overwritten by the former*/
226  new_particle.set_slow_formation_times(
227  time_of_execution_, last_formed_in_part->formation_time());
228  }
229  } else {
230  // not a string product
231  new_particle.set_slow_formation_times(
232  form_time_begin, last_formed_in_part->formation_time());
233  new_particle.set_cross_section_scaling_factor(sc);
234  }
235  }
236  } else {
237  for (ParticleData &new_particle : outgoing_particles_) {
238  if (new_particle.initial_xsec_scaling_factor() == 1.0) {
239  new_particle.set_formation_time(time_of_execution_);
240  }
241  }
242  }
243 }
244 
245 std::pair<double, double> Action::sample_masses(
246  const double kinetic_energy_cm) const {
247  const ParticleType &t_a = outgoing_particles_[0].type();
248  const ParticleType &t_b = outgoing_particles_[1].type();
249  // start with pole masses
250  std::pair<double, double> masses = {t_a.mass(), t_b.mass()};
251 
252  if (kinetic_energy_cm < t_a.min_mass_kinematic() + t_b.min_mass_kinematic()) {
253  const std::string reaction = incoming_particles_[0].type().name() +
254  incoming_particles_[1].type().name() + "→" +
255  t_a.name() + t_b.name();
257  reaction + ": not enough energy, " + std::to_string(kinetic_energy_cm) +
258  " < " + std::to_string(t_a.min_mass_kinematic()) + " + " +
259  std::to_string(t_b.min_mass_kinematic()));
260  }
261 
262  /* If one of the particles is a resonance, sample its mass. */
263  if (!t_a.is_stable() && t_b.is_stable()) {
264  masses.first = t_a.sample_resonance_mass(t_b.mass(), kinetic_energy_cm);
265  } else if (!t_b.is_stable() && t_a.is_stable()) {
266  masses.second = t_b.sample_resonance_mass(t_a.mass(), kinetic_energy_cm);
267  } else if (!t_a.is_stable() && !t_b.is_stable()) {
268  // two resonances in final state
269  masses = t_a.sample_resonance_masses(t_b, kinetic_energy_cm);
270  }
271  return masses;
272 }
273 
274 void Action::sample_angles(std::pair<double, double> masses,
275  const double kinetic_energy_cm) {
278 
279  const double pcm = pCM(kinetic_energy_cm, masses.first, masses.second);
280  if (!(pcm > 0.0)) {
281  logg[LAction].warn("Particle: ", p_a->pdgcode(), " radial momentum: ", pcm);
282  logg[LAction].warn("Ektot: ", kinetic_energy_cm, " m_a: ", masses.first,
283  " m_b: ", masses.second);
284  }
285  /* Here we assume an isotropic angular distribution. */
286  Angles phitheta;
287  phitheta.distribute_isotropically();
288 
289  p_a->set_4momentum(masses.first, phitheta.threevec() * pcm);
290  p_b->set_4momentum(masses.second, -phitheta.threevec() * pcm);
291  /* Debug message is printed before boost, so that p_a and p_b are
292  * the momenta in the center of mass frame and thus opposite to
293  * each other.*/
294  logg[LAction].debug("p_a: ", *p_a, "\np_b: ", *p_b);
295 }
296 
298  /* This function only operates on 2-particle final states. */
299  assert(outgoing_particles_.size() == 2);
301  const double cm_kin_energy = p_tot.abs();
302  // first sample the masses
303  const std::pair<double, double> masses = sample_masses(cm_kin_energy);
304  // after the masses are fixed (and thus also pcm), sample the angles
305  sample_angles(masses, cm_kin_energy);
306 }
307 
309  assert(outgoing_particles_.size() == 3);
310  if (!outgoing_particles_[0].type().is_stable() ||
311  !outgoing_particles_[1].type().is_stable() ||
312  !outgoing_particles_[2].type().is_stable()) {
313  throw std::invalid_argument(
314  "sample_3body_phasespace: Found resonance in to be sampled outgoing "
315  "particles, but assumes stable particles.");
316  }
317 
318  const double m_a = outgoing_particles_[0].type().mass(),
319  m_b = outgoing_particles_[1].type().mass(),
320  m_c = outgoing_particles_[2].type().mass();
321  const double sqrts = sqrt_s();
322 
323  // sample mab from pCM(sqrt, mab, mc) pCM (mab, ma, mb) <= sqrts^2/4
324  double mab, r, probability, pcm_ab, pcm;
325  do {
326  mab = random::uniform(m_a + m_b, sqrts - m_c);
327  r = random::canonical();
328  pcm = pCM(sqrts, mab, m_c);
329  pcm_ab = pCM(mab, m_a, m_b);
330  probability = pcm * pcm_ab * 4 / (sqrts * sqrts);
331  } while (r > probability);
332  Angles phitheta;
333  phitheta.distribute_isotropically();
334  outgoing_particles_[2].set_4momentum(m_c, pcm * phitheta.threevec());
335  const ThreeVector beta_cm =
336  pcm * phitheta.threevec() / std::sqrt(pcm * pcm + mab * mab);
337 
338  phitheta.distribute_isotropically();
339  outgoing_particles_[0].set_4momentum(m_a, pcm_ab * phitheta.threevec());
340  outgoing_particles_[1].set_4momentum(m_b, -pcm_ab * phitheta.threevec());
341  outgoing_particles_[0].boost_momentum(beta_cm);
342  outgoing_particles_[1].boost_momentum(beta_cm);
343 }
344 
346  assert(outgoing_particles_.size() == 5);
347  if (!outgoing_particles_[0].type().is_stable() ||
348  !outgoing_particles_[1].type().is_stable() ||
349  !outgoing_particles_[2].type().is_stable() ||
350  !outgoing_particles_[3].type().is_stable() ||
351  !outgoing_particles_[4].type().is_stable()) {
352  throw std::invalid_argument(
353  "sample_5body_phasespace: Found resonance in to be sampled outgoing "
354  "particles, but assumes stable particles.");
355  }
356  const double m_a = outgoing_particles_[0].type().mass(),
357  m_b = outgoing_particles_[1].type().mass(),
358  m_c = outgoing_particles_[2].type().mass(),
359  m_d = outgoing_particles_[3].type().mass(),
360  m_e = outgoing_particles_[4].type().mass();
361  const double sqrts = sqrt_s();
362 
363  // Sample 2-body PS for 1+2+3 and 4+5
364  const double mde = random::uniform(
365  m_d + m_e, sqrts - m_a - m_b - m_c); // invariant mass of 4+5 pair
366  const double mabc = sqrts - mde; // invariant mass of 1+2+3 pair
367 
368  const double pcm = pCM(sqrts, mabc, mde);
369 
370  Angles phitheta;
371  phitheta.distribute_isotropically();
372  const ThreeVector beta_cm123 =
373  pcm * phitheta.threevec() / std::sqrt(pcm * pcm + mabc * mabc);
374  const ThreeVector beta_cm45 =
375  pcm * phitheta.threevec() / std::sqrt(pcm * pcm + mde * mde);
376 
377  // Sample 3-body PS for 1,2 and 3
378  double mab, r, probability, pcm_ab, pcm_abc;
379  do {
380  mab = random::uniform(m_a + m_b, mabc - m_c);
381  r = random::canonical();
382  pcm_abc = pCM(mabc, mab, m_c);
383  pcm_ab = pCM(mab, m_a, m_b);
384  probability = pcm_abc * pcm_ab * 4 / (mabc * mabc);
385  } while (r > probability);
386  phitheta.distribute_isotropically();
387  outgoing_particles_[2].set_4momentum(m_c, pcm_abc * phitheta.threevec());
388  const ThreeVector beta_cm =
389  pcm_abc * phitheta.threevec() / std::sqrt(pcm_abc * pcm_abc + mab * mab);
390 
391  phitheta.distribute_isotropically();
392  outgoing_particles_[0].set_4momentum(m_a, pcm_ab * phitheta.threevec());
393  outgoing_particles_[1].set_4momentum(m_b, -pcm_ab * phitheta.threevec());
394  outgoing_particles_[0].boost_momentum(beta_cm);
395  outgoing_particles_[1].boost_momentum(beta_cm);
396 
397  // Sample 2-body PS for 4 and 5
398  const double pcm_de = pCM(mde, m_d, m_e);
399 
400  phitheta.distribute_isotropically();
401  outgoing_particles_[3].set_4momentum(m_d, pcm_de * phitheta.threevec());
402  outgoing_particles_[4].set_4momentum(m_e, -pcm_de * phitheta.threevec());
403 
404  // Boost according to intial 1+2+3 and 4+5 sampling
405  outgoing_particles_[3].boost_momentum(beta_cm45);
406  outgoing_particles_[4].boost_momentum(beta_cm45);
407 
408  outgoing_particles_[0].boost_momentum(-beta_cm123);
409  outgoing_particles_[1].boost_momentum(-beta_cm123);
410  outgoing_particles_[2].boost_momentum(-beta_cm123);
411 }
412 
413 void Action::check_conservation(const uint32_t id_process) const {
416  if (before != after) {
417  std::stringstream particle_names;
418  for (const auto &p : incoming_particles_) {
419  particle_names << p.type().name();
420  }
421  particle_names << " vs. ";
422  for (const auto &p : outgoing_particles_) {
423  particle_names << p.type().name();
424  }
425  particle_names << "\n";
426  std::string err_msg = before.report_deviations(after);
427  logg[LAction].error() << particle_names.str() << err_msg;
428  /* Pythia does not conserve energy and momentum at high energy, so we just
429  * print the error and continue. */
432  return;
433  }
434  if (id_process == ID_PROCESS_PHOTON) {
435  throw std::runtime_error("Conservation laws violated in photon process");
436  } else {
437  throw std::runtime_error("Conservation laws violated in process " +
438  std::to_string(id_process));
439  }
440  }
441 }
442 
443 std::ostream &operator<<(std::ostream &out, const ActionList &actions) {
444  out << "ActionList {\n";
445  for (const auto &a : actions) {
446  out << "- " << a << '\n';
447  }
448  return out << '}';
449 }
450 
451 } // namespace smash
Thrown for example when ScatterAction is called to perform with a wrong number of final-state particl...
Definition: action.h:325
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:297
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
Definition: action.cc:152
void assign_formation_time_to_outgoing_particles()
Assign the formation time to the outgoing particles.
Definition: action.cc:183
virtual ~Action()
Virtual Destructor.
virtual void sample_5body_phasespace()
Sample the full 5-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:345
int stochastic_position_idx_
This stores a randomly-chosen index to an incoming particle.
Definition: action.h:362
std::pair< FourVector, FourVector > get_potential_at_interaction_point() const
Get the skyrme and asymmetry potential at the interaction point.
Definition: action.cc:108
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:274
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
Definition: action.h:339
const ParticleType & type_of_pout(const ParticleData &p_out) const
Get the type of a given particle.
Definition: action.h:491
FourVector total_momentum() const
Sum of 4-momenta of incoming particles.
Definition: action.h:365
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:345
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:61
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:57
virtual void perform(Particles *particles, uint32_t id_process)
Actually perform the action, e.g.
Definition: action.cc:124
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
Definition: action.h:266
double box_length_
Box length: needed to determine coordinates of collision correctly in case of collision through the w...
Definition: action.h:355
ParticleList incoming_particles_
List with data of incoming particles.
Definition: action.h:331
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:67
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:245
virtual void sample_3body_phasespace()
Sample the full 3-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
Definition: action.cc:308
ProcessType process_type_
type of process
Definition: action.h:348
virtual void check_conservation(const uint32_t id_process) const
Check various conservation laws.
Definition: action.cc:413
bool is_valid(const Particles &particles) const
Check whether the action still applies.
Definition: action.cc:28
bool is_pauli_blocked(const std::vector< Particles > &ensembles, const PauliBlocker &p_bl) const
Check if the action is Pauli-blocked.
Definition: action.cc:34
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
Definition: angles.h:59
ThreeVector threevec() const
Definition: angles.h:268
void distribute_isotropically()
Populate the object with a new direction.
Definition: angles.h:188
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double abs() const
calculate the lorentz invariant absolute value
Definition: fourvector.h:459
ThreeVector threevec() const
Definition: fourvector.h:324
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
PdgCode pdgcode() const
Get the pdgcode of the particle.
Definition: particledata.h:87
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
Definition: particledata.h:164
Particle type contains the static properties of a particle species.
Definition: particletype.h:97
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 'this') and one ...
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
const std::string & name() const
Definition: particletype.h:141
bool is_stable() const
Definition: particletype.h:239
double isospin3_rel() const
Definition: particletype.h:179
double mass() const
Definition: particletype.h:144
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.
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
size_t size() const
Definition: particles.h:87
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
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
A class that stores parameters needed for Pauli blocking, tabulates necessary integrals and computes ...
Definition: pauliblocking.h:38
double phasespace_dens(const ThreeVector &r, const ThreeVector &p, const std::vector< Particles > &ensembles, const PdgCode pdg, const ParticleList &disregard) const
Calculate phase-space density of a particle species at the point (r,p).
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
Definition: potentials.cc:318
A container for storing conserved values.
std::string report_deviations(const std::vector< Particles > &ensembles) const
Checks if the current particle list has still the same values and reports about differences.
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
Collection of useful constants that are known at compile time.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:529
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
constexpr int p
Proton.
T uniform(T min, T max)
Definition: random.h:88
T canonical()
Definition: random.h:113
Definition: action.h:24
static constexpr int LPauliBlocking
Definition: action.cc:26
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
constexpr std::uint32_t ID_PROCESS_PHOTON
Process ID for any photon process.
Definition: constants.h:124
static constexpr int LAction
Definition: action.h:25
@ Wall
box wall crossing
@ Elastic
elastic scattering: particles remain the same, only momenta change
@ StringHard
hard string process involving 2->2 QCD process by PYTHIA.
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80
Potentials * pot_pointer
Pointer to a Potential class.
RectangularLattice< FourVector > * UB_lat_pointer
Pointer to the skyrme potential on the lattice.
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
RectangularLattice< FourVector > * UI3_lat_pointer
Pointer to the symmmetry potential on the lattice.