Version: SMASH-3.1
particles.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2015,2017-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/particles.h"
11 
12 #include <iomanip>
13 #include <iostream>
14 
15 namespace smash {
16 
17 Particles::Particles() : data_(new ParticleData[data_capacity_]) {
18  for (unsigned i = 0; i < data_capacity_; ++i) {
19  data_[i].index_ = i;
20  }
21 }
22 
23 inline void Particles::ensure_capacity(unsigned to_add) {
24  if (data_size_ + to_add >= data_capacity_) {
25  increase_capacity((data_capacity_ + to_add) * 2u);
26  assert(data_size_ + to_add < data_capacity_);
27  }
28 }
29 
30 void Particles::increase_capacity(unsigned new_capacity) {
31  assert(new_capacity > data_capacity_);
32  data_capacity_ = new_capacity;
33  std::unique_ptr<ParticleData[]> new_memory(new ParticleData[data_capacity_]);
34  unsigned i = 0;
35  for (; i < data_size_; ++i) {
36  new_memory[i] = data_[i];
37  }
38  for (; i < data_capacity_; ++i) {
39  new_memory[i].index_ = i;
40  }
41  std::swap(data_, new_memory);
42 }
43 
44 inline void Particles::copy_in(ParticleData &to, const ParticleData &from) {
45  to.id_ = ++id_max_;
46  to.type_ = from.type_;
47  from.copy_to(to);
48 }
49 
51  if (likely(dirty_.empty())) {
52  ensure_capacity(1);
53  ParticleData &in_vector = data_[data_size_];
54  copy_in(in_vector, p);
55  ++data_size_;
56  return in_vector;
57  } else {
58  const auto offset = dirty_.back();
59  dirty_.pop_back();
60  copy_in(data_[offset], p);
61  data_[offset].hole_ = false;
62  return data_[offset];
63  }
64 }
65 
66 void Particles::create(size_t number, PdgCode pdg) {
67  const ParticleData pd(ParticleType::find(pdg));
68  while (number && !dirty_.empty()) {
69  const auto offset = dirty_.back();
70  dirty_.pop_back();
71  pd.copy_to(data_[offset]);
72  data_[offset].id_ = ++id_max_;
73  data_[offset].type_ = pd.type_;
74  data_[offset].hole_ = false;
75  --number;
76  }
77  if (number) {
78  ensure_capacity(number);
79  const auto end_ptr = &data_[data_size_ + number];
80  for (auto ptr = &data_[data_size_]; ptr < end_ptr; ++ptr) {
81  pd.copy_to(*ptr);
82  ptr->id_ = ++id_max_;
83  ptr->type_ = pd.type_;
84  }
85  data_size_ += number;
86  }
87 }
88 
90  const ParticleData pd(ParticleType::find(pdg));
91  ParticleData *ptr;
92  if (likely(dirty_.empty())) {
93  ensure_capacity(1);
94  ptr = &data_[data_size_];
95  ++data_size_;
96  } else {
97  const auto offset = dirty_.back();
98  dirty_.pop_back();
99  ptr = &data_[offset];
100  ptr->hole_ = false;
101  }
102  pd.copy_to(*ptr);
103  ptr->id_ = ++id_max_;
104  ptr->type_ = pd.type_;
105  return *ptr;
106 }
107 
109  assert(is_valid(p));
110  const unsigned index = p.index_;
111  if (index == data_size_ - 1) {
112  --data_size_;
113  } else {
114  data_[index].set_id(-1);
115  data_[index].hole_ = true;
116  dirty_.push_back(index);
117  }
118 }
119 
120 void Particles::replace(const ParticleList &to_remove, ParticleList &to_add) {
121  std::size_t i = 0;
122  for (; i < std::min(to_remove.size(), to_add.size()); ++i) {
123  assert(is_valid(to_remove[i]));
124  const auto index = to_remove[i].index_;
125  copy_in(data_[index], to_add[i]);
126  to_add[i].id_ = data_[index].id_;
127  to_add[i].index_ = index;
128  }
129  for (; i < to_remove.size(); ++i) {
130  remove(to_remove[i]);
131  }
132  for (; i < to_add.size(); ++i) {
133  const ParticleData &p = insert(to_add[i]);
134  to_add[i].id_ = p.id_;
135  to_add[i].index_ = p.index_;
136  }
137 }
138 
140  id_max_ = -1;
141  data_size_ = 0;
142  for (auto index : dirty_) {
143  data_[index].hole_ = false;
144  }
145  dirty_.clear();
146 }
147 
148 std::ostream &operator<<(std::ostream &out, const Particles &particles) {
149  out << particles.size() << " Particles:\n";
150  for (unsigned i = 0; i < particles.data_size_; ++i) {
151  const auto &p = particles.data_[i];
152  if (p.id() < 0) {
153  out << "------ ";
154  } else {
155  out << std::setw(5) << std::setprecision(3) << p.momentum().abs3()
156  << p.type().name();
157  }
158  if ((i & 15) == 0) {
159  out << '\n';
160  }
161  }
162  return out;
163 }
164 
165 } // namespace smash
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:58
int32_t id_
Each particle has a unique identifier.
Definition: particledata.h:420
bool hole_
If true, the object is an entry in Particles::data_ and does not hold valid particle data.
Definition: particledata.h:450
void copy_to(ParticleData &dst) const
Copies some information of the particle to the given particle dst.
Definition: particledata.h:402
ParticleTypePtr type_
A reference to the ParticleType object for this particle (this contains all the static information).
Definition: particledata.h:436
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
std::unique_ptr< ParticleData[]> data_
Points to a dynamically allocated array of ParticleData objects.
Definition: particles.h:498
size_t size() const
Definition: particles.h:87
void reset()
Reset the state of the Particles object to an empty list and a new id counter.
Definition: particles.cc:139
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
std::vector< unsigned > dirty_
Stores the indexes in data_ that do not hold valid particle data and should be reused when new partic...
Definition: particles.h:504
unsigned data_size_
Definition: particles.h:487
void copy_in(ParticleData &to, const ParticleData &from)
Definition: particles.cc:44
int id_max_
Highest id of a given particle.
Definition: particles.h:446
void ensure_capacity(unsigned to_add)
Definition: particles.cc:23
Particles()
Creates a new (empty) Particles object.
Definition: particles.cc:17
void replace(const ParticleList &to_remove, ParticleList &to_add)
Replace the particles in to_remove with the particles in to_add in the list of current particles.
Definition: particles.cc:120
unsigned data_capacity_
Definition: particles.h:492
const ParticleData & insert(const ParticleData &p)
Inserts the particle into the list of particles.
Definition: particles.cc:50
void create(size_t n, PdgCode pdg)
Add n particles of the same type (pdg) to the list.
Definition: particles.cc:66
void increase_capacity(unsigned new_capacity)
Definition: particles.cc:30
void remove(const ParticleData &p)
Remove the given particle p from the list.
Definition: particles.cc:108
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:111
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:547
#define likely(x)
Tell the branch predictor that this expression is likely true.
Definition: macros.h:14
constexpr int p
Proton.
Definition: action.h:24