Version: SMASH-1.5.1
scatteractionsfinder.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 
11 
12 #include <algorithm>
13 #include <map>
14 #include <vector>
15 
16 #include "smash/configuration.h"
17 #include "smash/constants.h"
18 #include "smash/crosssections.h"
19 #include "smash/cxx14compat.h"
20 #include "smash/decaymodes.h"
22 #include "smash/isoparticletype.h"
23 #include "smash/logging.h"
24 #include "smash/macros.h"
25 #include "smash/particles.h"
26 #include "smash/scatteraction.h"
28 #include "smash/stringfunctions.h"
29 
30 namespace smash {
194  Configuration config, const ExperimentParameters& parameters,
195  const std::vector<bool>& nucleon_has_interacted, int N_tot, int N_proj)
196  : elastic_parameter_(
197  config.take({"Collision_Term", "Elastic_Cross_Section"}, -1.)),
198  testparticles_(parameters.testparticles),
199  isotropic_(config.take({"Collision_Term", "Isotropic"}, false)),
200  two_to_one_(parameters.two_to_one),
201  incl_set_(parameters.included_2to2),
202  low_snn_cut_(parameters.low_snn_cut),
203  strings_switch_(parameters.strings_switch),
204  use_AQM_(parameters.use_AQM),
205  strings_with_probability_(parameters.strings_with_probability),
206  nnbar_treatment_(parameters.nnbar_treatment),
207  nucleon_has_interacted_(nucleon_has_interacted),
208  N_tot_(N_tot),
209  N_proj_(N_proj),
210  string_formation_time_(config.take(
211  {"Collision_Term", "String_Parameters", "Formation_Time"}, 1.)) {
212  if (is_constant_elastic_isotropic()) {
213  const auto& log = logger<LogArea::FindScatter>();
214  log.info("Constant elastic isotropic cross-section mode:", " using ",
215  elastic_parameter_, " mb as maximal cross-section.");
216  }
217  if (strings_switch_) {
218  auto subconfig = config["Collision_Term"]["String_Parameters"];
219  string_process_interface_ = make_unique<StringProcess>(
220  subconfig.take({"String_Tension"}, 1.0), string_formation_time_,
221  subconfig.take({"Gluon_Beta"}, 0.5),
222  subconfig.take({"Gluon_Pmin"}, 0.001),
223  subconfig.take({"Quark_Alpha"}, 2.0),
224  subconfig.take({"Quark_Beta"}, 5.0),
225  subconfig.take({"Strange_Supp"}, 0.12),
226  subconfig.take({"Diquark_Supp"}, 0.03),
227  subconfig.take({"Sigma_Perp"}, 0.42),
228  subconfig.take({"Leading_Frag_Mean"}, 1.0),
229  subconfig.take({"Leading_Frag_Width"}, 0.6),
230  subconfig.take({"StringZ_A"}, 0.68), subconfig.take({"StringZ_B"}, 0.3),
231  subconfig.take({"String_Sigma_T"}, 0.5),
232  subconfig.take({"Form_Time_Factor"}, 1.0),
233  subconfig.take({"Use_Yoyo_Model"}, true),
234  subconfig.take({"Prob_proton_to_d_uu"}, 1. / 3.));
235  }
236 }
237 
239  const ParticleData& data_b,
240  double dt) const {
241 #ifndef NDEBUG
242  const auto& log = logger<LogArea::FindScatter>();
243 #endif
244 
245  // just collided with this particle
246  if (data_a.id_process() > 0 && data_a.id_process() == data_b.id_process()) {
247 #ifndef NDEBUG
248  log.debug("Skipping collided particles at time ", data_a.position().x0(),
249  " due to process ", data_a.id_process(), "\n ", data_a,
250  "\n<-> ", data_b);
251 #endif
252  return nullptr;
253  }
254  /* If the two particles
255  * 1) belong to the two colliding nuclei
256  * 2) are within the same nucleus
257  * 3) both of them have never experienced any collisons,
258  * then the collision between them are banned. */
259  assert(data_a.id() >= 0);
260  assert(data_b.id() >= 0);
261  if (data_a.id() < N_tot_ && data_b.id() < N_tot_ &&
262  ((data_a.id() < N_proj_ && data_b.id() < N_proj_) ||
263  (data_a.id() >= N_proj_ && data_b.id() >= N_proj_)) &&
264  !(nucleon_has_interacted_[data_a.id()] ||
265  nucleon_has_interacted_[data_b.id()])) {
266  return nullptr;
267  }
268 
269  // Determine time of collision.
270  const double time_until_collision = collision_time(data_a, data_b);
271 
272  // Check that collision happens in this timestep.
273  if (time_until_collision < 0. || time_until_collision >= dt) {
274  return nullptr;
275  }
276 
277  // Create ScatterAction object.
278  ScatterActionPtr act = make_unique<ScatterAction>(
279  data_a, data_b, time_until_collision, isotropic_, string_formation_time_);
280  if (strings_switch_) {
281  act->set_string_interface(string_process_interface_.get());
282  }
283 
284  const double distance_squared = act->transverse_distance_sqr();
285 
286  // Don't calculate cross section if the particles are very far apart.
287  if (distance_squared >= max_transverse_distance_sqr(testparticles_)) {
288  return nullptr;
289  }
290 
291  // Add various subprocesses.
292  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
295 
296  // Cross section for collision criterion
297  double cross_section_criterion = act->cross_section() * fm2_mb * M_1_PI /
298  static_cast<double>(testparticles_);
299  // Take cross section scaling factors into account
300  cross_section_criterion *= data_a.xsec_scaling_factor(time_until_collision);
301  cross_section_criterion *= data_b.xsec_scaling_factor(time_until_collision);
302 
303  // distance criterion according to cross_section
304  if (distance_squared >= cross_section_criterion) {
305  return nullptr;
306  }
307 
308 #ifndef NDEBUG
309  log.debug("particle distance squared: ", distance_squared, "\n ", data_a,
310  "\n<-> ", data_b);
311 #endif
312 
313  return std::move(act);
314 }
315 
317  const ParticleList& search_list, double dt) const {
318  std::vector<ActionPtr> actions;
319  for (const ParticleData& p1 : search_list) {
320  for (const ParticleData& p2 : search_list) {
321  if (p1.id() < p2.id()) {
322  // Check if a collision is possible.
323  ActionPtr act = check_collision(p1, p2, dt);
324  if (act) {
325  actions.push_back(std::move(act));
326  }
327  }
328  }
329  }
330  return actions;
331 }
332 
334  const ParticleList& search_list, const ParticleList& neighbors_list,
335  double dt) const {
336  std::vector<ActionPtr> actions;
337  for (const ParticleData& p1 : search_list) {
338  for (const ParticleData& p2 : neighbors_list) {
339  assert(p1.id() != p2.id());
340  // Check if a collision is possible.
341  ActionPtr act = check_collision(p1, p2, dt);
342  if (act) {
343  actions.push_back(std::move(act));
344  }
345  }
346  }
347  return actions;
348 }
349 
351  const ParticleList& search_list, const Particles& surrounding_list,
352  double dt) const {
353  std::vector<ActionPtr> actions;
354  for (const ParticleData& p2 : surrounding_list) {
355  /* don't look for collisions if the particle from the surrounding list is
356  * also in the search list */
357  auto result = std::find_if(
358  search_list.begin(), search_list.end(),
359  [&p2](const ParticleData& p) { return p.id() == p2.id(); });
360  if (result != search_list.end()) {
361  continue;
362  }
363  for (const ParticleData& p1 : search_list) {
364  // Check if a collision is possible.
365  ActionPtr act = check_collision(p1, p2, dt);
366  if (act) {
367  actions.push_back(std::move(act));
368  }
369  }
370  }
371  return actions;
372 }
373 
375  constexpr double time = 0.0;
376 
377  const size_t N_isotypes = IsoParticleType::list_all().size();
378  const size_t N_pairs = N_isotypes * (N_isotypes - 1) / 2;
379 
380  std::cout << N_isotypes << " iso-particle types." << std::endl;
381  std::cout << "They can make " << N_pairs << " pairs." << std::endl;
382  std::vector<double> momentum_scan_list = {0.1, 0.3, 0.5, 1.0,
383  2.0, 3.0, 5.0, 10.0};
384  for (const IsoParticleType& A_isotype : IsoParticleType::list_all()) {
385  for (const IsoParticleType& B_isotype : IsoParticleType::list_all()) {
386  if (&A_isotype > &B_isotype) {
387  continue;
388  }
389  bool any_nonzero_cs = false;
390  std::vector<std::string> r_list;
391  for (const ParticleTypePtr A_type : A_isotype.get_states()) {
392  for (const ParticleTypePtr B_type : B_isotype.get_states()) {
393  if (A_type > B_type) {
394  continue;
395  }
396  ParticleData A(*A_type), B(*B_type);
397  for (auto mom : momentum_scan_list) {
398  A.set_4momentum(A.pole_mass(), mom, 0.0, 0.0);
399  B.set_4momentum(B.pole_mass(), -mom, 0.0, 0.0);
400  ScatterActionPtr act = make_unique<ScatterAction>(
401  A, B, time, isotropic_, string_formation_time_);
402  if (strings_switch_) {
403  act->set_string_interface(string_process_interface_.get());
404  }
405  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
409  const double total_cs = act->cross_section();
410  if (total_cs <= 0.0) {
411  continue;
412  }
413  any_nonzero_cs = true;
414  for (const auto& channel : act->collision_channels()) {
415  const auto type = channel->get_type();
416  std::string r;
417  if (is_string_soft_process(type) ||
418  type == ProcessType::StringHard) {
419  r = A_type->name() + B_type->name() + std::string(" → strings");
420  } else {
421  std::string r_type =
422  (type == ProcessType::Elastic)
423  ? std::string(" (el)")
424  : (channel->get_type() == ProcessType::TwoToTwo)
425  ? std::string(" (inel)")
426  : std::string(" (?)");
427  r = A_type->name() + B_type->name() + std::string(" → ") +
428  channel->particle_types()[0]->name() +
429  channel->particle_types()[1]->name() + r_type;
430  }
431  isoclean(r);
432  r_list.push_back(r);
433  }
434  }
435  }
436  }
437  std::sort(r_list.begin(), r_list.end());
438  r_list.erase(std::unique(r_list.begin(), r_list.end()), r_list.end());
439  if (any_nonzero_cs) {
440  for (auto r : r_list) {
441  std::cout << r;
442  if (r_list.back() != r) {
443  std::cout << ", ";
444  }
445  }
446  std::cout << std::endl;
447  }
448  }
449  }
450 }
451 
455  std::string name_;
456 
459 
461  double mass_;
462 
471  FinalStateCrossSection(const std::string& name, double cross_section,
472  double mass)
473  : name_(name), cross_section_(cross_section), mass_(mass) {}
474 };
475 
476 namespace decaytree {
477 
489 struct Node {
490  public:
492  std::string name_;
493 
495  double weight_;
496 
498  ParticleTypePtrList initial_particles_;
499 
501  ParticleTypePtrList final_particles_;
502 
504  ParticleTypePtrList state_;
505 
507  std::vector<Node> children_;
508 
510  Node(const Node&) = delete;
512  Node(Node&&) = default;
513 
524  Node(const std::string& name, double weight,
525  ParticleTypePtrList&& initial_particles,
526  ParticleTypePtrList&& final_particles, ParticleTypePtrList&& state,
527  std::vector<Node>&& children)
528  : name_(name),
529  weight_(weight),
530  initial_particles_(std::move(initial_particles)),
531  final_particles_(std::move(final_particles)),
532  state_(std::move(state)),
533  children_(std::move(children)) {}
534 
546  Node& add_action(const std::string& name, double weight,
547  ParticleTypePtrList&& initial_particles,
548  ParticleTypePtrList&& final_particles) {
549  // Copy parent state and update it.
550  ParticleTypePtrList state(state_);
551  for (const auto& p : initial_particles) {
552  state.erase(std::find(state.begin(), state.end(), p));
553  }
554  for (const auto& p : final_particles) {
555  state.push_back(p);
556  }
557  // Sort the state to normalize the output.
558  std::sort(state.begin(), state.end(),
560  return a->name() < b->name();
561  });
562  // Push new node to children.
563  Node new_node(name, weight, std::move(initial_particles),
564  std::move(final_particles), std::move(state), {});
565  children_.emplace_back(std::move(new_node));
566  return children_.back();
567  }
568 
570  void print() const { print_helper(0); }
571 
575  std::vector<FinalStateCrossSection> final_state_cross_sections() const {
576  std::vector<FinalStateCrossSection> result;
577  final_state_cross_sections_helper(0, result, "", 1.);
578  return result;
579  }
580 
581  private:
588  void print_helper(uint64_t depth) const {
589  for (uint64_t i = 0; i < depth; i++) {
590  std::cout << " ";
591  }
592  std::cout << name_ << " " << weight_ << std::endl;
593  for (const auto& child : children_) {
594  child.print_helper(depth + 1);
595  }
596  }
597 
610  uint64_t depth, std::vector<FinalStateCrossSection>& result,
611  const std::string& name, double weight,
612  bool show_intermediate_states = false) const {
613  // The first node corresponds to the total cross section and has to be
614  // ignored. The second node corresponds to the partial cross section. All
615  // further nodes correspond to branching ratios.
616  if (depth > 0) {
617  weight *= weight_;
618  }
619 
620  std::string new_name;
621  double mass = 0.;
622 
623  if (show_intermediate_states) {
624  new_name = name;
625  if (!new_name.empty()) {
626  new_name += "->";
627  }
628  new_name += name_;
629  new_name += "{";
630  } else {
631  new_name = "";
632  }
633  for (const auto& s : state_) {
634  new_name += s->name();
635  mass += s->mass();
636  }
637  if (show_intermediate_states) {
638  new_name += "}";
639  }
640 
641  if (children_.empty()) {
642  result.emplace_back(FinalStateCrossSection(new_name, weight, mass));
643  return;
644  }
645  for (const auto& child : children_) {
646  child.final_state_cross_sections_helper(depth + 1, result, new_name,
647  weight, show_intermediate_states);
648  }
649  }
650 };
651 
660 static std::string make_decay_name(const std::string& res_name,
661  const DecayBranchPtr& decay,
662  ParticleTypePtrList& final_state) {
663  std::stringstream name;
664  name << "[" << res_name << "->";
665  for (const auto& p : decay->particle_types()) {
666  name << p->name();
667  final_state.push_back(p);
668  }
669  name << "]";
670  return name.str();
671 }
672 
679 static void add_decays(Node& node) {
680  // If there is more than one unstable particle in the current state, then
681  // there will be redundant paths in the decay tree, corresponding to
682  // reorderings of the decays. To avoid double counting, we normalize by the
683  // number of possible decay orderings. Normalizing by the number of unstable
684  // particles recursively corresponds to normalizing by the factorial that
685  // gives the number of reorderings.
686  //
687  // Ideally, the redundant paths should never be added to the decay tree, but
688  // we never have more than two redundant paths, so it probably does not matter
689  // much.
690  uint32_t n_unstable = 0;
691  for (const ParticleTypePtr ptype : node.state_) {
692  if (!ptype->is_stable()) {
693  n_unstable += 1;
694  }
695  }
696  const double norm =
697  n_unstable != 0 ? 1. / static_cast<double>(n_unstable) : 1.;
698 
699  for (const ParticleTypePtr ptype : node.state_) {
700  if (!ptype->is_stable()) {
701  for (const auto& decay : ptype->decay_modes().decay_mode_list()) {
702  ParticleTypePtrList parts;
703  const auto name = make_decay_name(ptype->name(), decay, parts);
704  auto& new_node = node.add_action(name, norm * decay->weight(), {ptype},
705  std::move(parts));
706  add_decays(new_node);
707  }
708  }
709  }
710 }
711 
712 } // namespace decaytree
713 
719 static void deduplicate(std::vector<FinalStateCrossSection>& final_state_xs) {
720  std::sort(final_state_xs.begin(), final_state_xs.end(),
721  [](const FinalStateCrossSection& a,
722  const FinalStateCrossSection& b) { return a.name_ < b.name_; });
723  auto current = final_state_xs.begin();
724  while (current != final_state_xs.end()) {
725  auto adjacent = std::adjacent_find(
726  current, final_state_xs.end(),
727  [](const FinalStateCrossSection& a, const FinalStateCrossSection& b) {
728  return a.name_ == b.name_;
729  });
730  current = adjacent;
731  if (adjacent != final_state_xs.end()) {
732  adjacent->cross_section_ += (adjacent + 1)->cross_section_;
733  final_state_xs.erase(adjacent + 1);
734  }
735  }
736 }
737 
739  const ParticleType& b,
740  double m_a, double m_b,
741  bool final_state) const {
742  typedef std::vector<std::pair<double, double>> xs_saver;
743  std::map<std::string, xs_saver> xs_dump;
744  std::map<std::string, double> outgoing_total_mass;
745 
746  ParticleData a_data(a), b_data(b);
747  constexpr int n_momentum_points = 200;
748  constexpr double momentum_step = 0.02;
749  for (int i = 1; i < n_momentum_points + 1; i++) {
750  const double momentum = momentum_step * i;
751  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
752  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
753  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
754  const ParticleList incoming = {a_data, b_data};
755  ScatterActionPtr act = make_unique<ScatterAction>(
756  a_data, b_data, 0., isotropic_, string_formation_time_);
757  if (strings_switch_) {
758  act->set_string_interface(string_process_interface_.get());
759  }
760  act->add_all_scatterings(elastic_parameter_, two_to_one_, incl_set_,
763  decaytree::Node tree(a.name() + b.name(), act->cross_section(), {&a, &b},
764  {&a, &b}, {&a, &b}, {});
765  const CollisionBranchList& processes = act->collision_channels();
766  for (const auto& process : processes) {
767  const double xs = process->weight();
768  if (xs <= 0.0) {
769  continue;
770  }
771  if (!final_state) {
772  std::stringstream process_description_stream;
773  process_description_stream << *process;
774  const std::string& description = process_description_stream.str();
775  double m_tot = 0.0;
776  for (const auto& ptype : process->particle_types()) {
777  m_tot += ptype->mass();
778  }
779  outgoing_total_mass[description] = m_tot;
780  if (!xs_dump[description].empty() &&
781  std::abs(xs_dump[description].back().first - sqrts) <
782  really_small) {
783  xs_dump[description].back().second += xs;
784  } else {
785  xs_dump[description].push_back(std::make_pair(sqrts, xs));
786  }
787  } else {
788  std::stringstream process_description_stream;
789  process_description_stream << *process;
790  const std::string& description = process_description_stream.str();
791  ParticleTypePtrList initial_particles = {&a, &b};
792  ParticleTypePtrList final_particles = process->particle_types();
793  auto& process_node =
794  tree.add_action(description, xs, std::move(initial_particles),
795  std::move(final_particles));
796  decaytree::add_decays(process_node);
797  }
798  }
799  xs_dump["total"].push_back(std::make_pair(sqrts, act->cross_section()));
800  // Total cross-section should be the first in the list -> negative mass
801  outgoing_total_mass["total"] = -1.0;
802  if (final_state) {
803  // tree.print();
804  auto final_state_xs = tree.final_state_cross_sections();
805  deduplicate(final_state_xs);
806  for (const auto& p : final_state_xs) {
807  outgoing_total_mass[p.name_] = p.mass_;
808  xs_dump[p.name_].push_back(std::make_pair(sqrts, p.cross_section_));
809  }
810  }
811  }
812 
813  // Nice ordering of channels by summed pole mass of products
814  std::vector<std::string> all_channels;
815  for (const auto channel : xs_dump) {
816  all_channels.push_back(channel.first);
817  }
818  std::sort(all_channels.begin(), all_channels.end(),
819  [&](const std::string& str_a, const std::string& str_b) {
820  return outgoing_total_mass[str_a] < outgoing_total_mass[str_b];
821  });
822 
823  // Print header
824  std::cout << "# Dumping partial " << a.name() << b.name()
825  << " cross-sections in mb, energies in GeV" << std::endl;
826  std::cout << " sqrt_s";
827  // Align everything to 16 unicode characters.
828  // This should be enough for the longest channel name (7 final-state
829  // particles).
830  for (const auto channel : all_channels) {
831  std::cout << utf8::fill_left(channel, 16, ' ');
832  }
833  std::cout << std::endl;
834 
835  // Print out all partial cross-sections in mb
836  for (int i = 1; i < n_momentum_points; i++) {
837  const double momentum = momentum_step * i;
838  a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
839  b_data.set_4momentum(m_b, -momentum, 0.0, 0.0);
840  const double sqrts = (a_data.momentum() + b_data.momentum()).abs();
841  printf("%9.5f", sqrts);
842  for (const auto channel : all_channels) {
843  const xs_saver energy_and_xs = xs_dump[channel];
844  size_t j = 0;
845  for (; j < energy_and_xs.size() && energy_and_xs[j].first < sqrts; j++) {
846  }
847  double xs = 0.0;
848  if (j < energy_and_xs.size() &&
849  std::abs(energy_and_xs[j].first - sqrts) < really_small) {
850  xs = energy_and_xs[j].second;
851  }
852  printf("%16.6f", xs); // Same alignment as in the header.
853  }
854  printf("\n");
855  }
856 }
857 
858 } // namespace smash
void print_helper(uint64_t depth) const
Internal helper function for print, to be called recursively to print all nodes.
Node(const Node &)=delete
Cannot be copied.
std::string name_
Name of the final state.
static double collision_time(const ParticleData &p1, const ParticleData &p2)
Determine the collision time of the two particles.
double mass_
Total mass of final state particles.
static void deduplicate(std::vector< FinalStateCrossSection > &final_state_xs)
Deduplicate the final-state cross sections by summing.
const int testparticles_
Number of test particles.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:34
const ReactionsBitSet incl_set_
List of included 2<->2 reactions.
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
const bool two_to_one_
Enable 2->1 processes.
static std::string make_decay_name(const std::string &res_name, const DecayBranchPtr &decay, ParticleTypePtrList &final_state)
Generate name for decay and update final state.
const double low_snn_cut_
Elastic collsions between two nucleons with sqrt_s below low_snn_cut_ are excluded.
const double string_formation_time_
Parameter for formation time.
void isoclean(std::string &s)
Remove ⁺, ⁻, ⁰ from string.
Collection of useful constants that are known at compile time.
double pole_mass() const
Get the particle&#39;s pole mass ("on-shell").
Definition: particledata.h:96
const bool strings_with_probability_
Decide whether to implement string fragmentation based on a probability.
STL namespace.
double max_transverse_distance_sqr(int testparticles) const
The maximal distance over which particles can interact, related to the number of test particles and t...
ActionPtr check_collision(const ParticleData &data_a, const ParticleData &data_b, double dt) const
Check for a single pair of particles (id_a, id_b) if a collision will happen in the next timestep and...
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Definition: constants.h:28
2->2 inelastic scattering
std::vector< Node > children_
Possible actions after this action.
const FourVector & momentum() const
Get the particle&#39;s 4-momentum.
Definition: particledata.h:139
const std::vector< bool > & nucleon_has_interacted_
Parameter to record whether the nucleon has experienced a collision or not.
Represent a final-state cross section.
Interface to the SMASH configuration files.
std::string fill_left(const std::string &s, size_t width, char fill=' ')
Fill string with characters to the left until the given width is reached.
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
double x0() const
Definition: fourvector.h:290
const bool strings_switch_
Switch to turn off string excitation.
ParticleTypePtrList initial_particles_
Initial-state particle types in this action.
ActionList find_actions_in_cell(const ParticleList &search_list, double dt) const override
Search for all the possible collisions within one cell.
std::string name_
Name for printing.
elastic scattering: particles remain the same, only momenta change
double weight_
Weight (cross section or branching ratio).
void final_state_cross_sections_helper(uint64_t depth, std::vector< FinalStateCrossSection > &result, const std::string &name, double weight, bool show_intermediate_states=false) const
Internal helper function for final_state_cross_sections, to be called recursively to calculate all fi...
bool is_stable() const
Definition: particletype.h:226
const FourVector & position() const
Get the particle&#39;s position in Minkowski space.
Definition: particledata.h:185
Particle type contains the static properties of a particle species.
Definition: particletype.h:87
ScatterActionsFinder(Configuration config, const ExperimentParameters &parameters, const std::vector< bool > &nucleon_has_interacted, int N_tot, int N_proj)
Constructor of the finder with the given parameters.
void dump_cross_sections(const ParticleType &a, const ParticleType &b, double m_a, double m_b, bool final_state) const
Print out partial cross-sections of all processes that can occur in the collision of a(mass = m_a) an...
void set_4momentum(const FourVector &momentum_vector)
Set the particle&#39;s 4-momentum directly.
Definition: particledata.h:145
IsoParticleType is a class to represent isospin multiplets.
const NNbarTreatment nnbar_treatment_
Switch for NNbar reactions.
uint32_t id_process() const
Get the id of the last action.
Definition: particledata.h:115
hard string process involving 2->2 QCD process by PYTHIA.
FinalStateCrossSection(const std::string &name, double cross_section, double mass)
Construct a final-state cross section.
ParticleTypePtrList final_particles_
Final-state particle types in this action.
void dump_reactions() const
Prints out all the 2-> n (n > 1) reactions with non-zero cross-sections between all possible pairs of...
std::vector< FinalStateCrossSection > final_state_cross_sections() const
const DecayModes & decay_modes() const
constexpr int p
Proton.
const bool use_AQM_
Switch to control whether to use AQM or not.
const int N_proj_
Record the number of the nucleons in the projectile.
const bool isotropic_
Do all collisions isotropically.
const int N_tot_
Record the total number of the nucleons in the two colliding nuclei.
void print() const
Print the decay tree starting with this node.
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:660
static void add_decays(Node &node)
Add nodes for all decays possible from the given node and all of its children.
Node of a decay tree, representing a possible action (2-to-2 or 1-to-2).
ParticleTypePtrList state_
Particle types corresponding to the global state after this action.
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
int id() const
Get the id of the particle.
Definition: particledata.h:70
Node(const std::string &name, double weight, ParticleTypePtrList &&initial_particles, ParticleTypePtrList &&final_particles, ParticleTypePtrList &&state, std::vector< Node > &&children)
double cross_section_
Corresponding cross section in mb.
Node & add_action(const std::string &name, double weight, ParticleTypePtrList &&initial_particles, ParticleTypePtrList &&final_particles)
Add an action to the children of this node.
ActionList find_actions_with_surrounding_particles(const ParticleList &search_list, const Particles &surrounding_list, double dt) const override
Search for all the possible secondary collisions between the outgoing particles and the rest...
Helper structure for Experiment.
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:52
const double elastic_parameter_
Elastic cross section parameter (in mb).
Definition: action.h:24
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
ActionList find_actions_with_neighbors(const ParticleList &search_list, const ParticleList &neighbors_list, double dt) const override
Search for all the possible collisions among the neighboring cells.
const DecayBranchList & decay_mode_list() const
Definition: decaymodes.h:63
const std::string & name() const
Definition: particletype.h:131