Version: SMASH-3.1
smash::Particles Class Reference

#include <particles.h>

The Particles class abstracts the storage and manipulation of particles.

There is one Particles object per Experiment. It stores the data about all existing particles in the experiment (ParticleData).

Note
The Particles object cannot be copied, because it does not make sense semantically. Move semantics make sense and can be implemented when needed.

Definition at line 33 of file particles.h.

Classes

class  GenericIterator
 

Public Types

using iterator = GenericIterator< ParticleData >
 An alias to the GenericIterator class of ParticleData. More...
 
using const_iterator = GenericIterator< const ParticleData >
 An alias to the GenericIterator class of const ParticleData. More...
 

Public Member Functions

 Particles ()
 Creates a new (empty) Particles object. More...
 
 Particles (const Particles &)=delete
 Cannot be copied. More...
 
Particlesoperator= (const Particles &)=delete
 Cannot be copied. More...
 
ParticleList copy_to_vector () const
 
const ParticleDatainsert (const ParticleData &p)
 Inserts the particle into the list of particles. More...
 
void create (size_t n, PdgCode pdg)
 Add n particles of the same type (pdg) to the list. More...
 
ParticleDatacreate (const PdgCode pdg)
 Add one particle of the given pdg code. More...
 
size_t size () const
 
bool is_empty () const
 
double time () const
 Returns the time of the computational frame. More...
 
void reset ()
 Reset the state of the Particles object to an empty list and a new id counter. More...
 
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. More...
 
void remove (const ParticleData &p)
 Remove the given particle p from the list. More...
 
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. More...
 
const ParticleDataupdate_particle (const ParticleData &p, const ParticleData &new_state)
 Updates the particle identified by p with the state stored in new_state. More...
 
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. More...
 
const ParticleDatalookup (const ParticleData &old_state) const
 Returns the particle that is currently stored in this object given an old copy of that particle. More...
 
ParticleDatafront ()
 
const ParticleDatafront () const
 const overload of &front() More...
 
ParticleDataback ()
 
const ParticleDataback () const
 const overload of &back() More...
 
iterator begin ()
 
const_iterator begin () const
 const overload of begin() More...
 
iterator end ()
 
const_iterator end () const
 const overload of end() More...
 
const_iterator cbegin () const
 
const_iterator cend () const
 

Private Member Functions

void increase_capacity (unsigned new_capacity)
 
void ensure_capacity (unsigned to_add)
 
void copy_in (ParticleData &to, const ParticleData &from)
 

Private Attributes

int id_max_ = -1
 Highest id of a given particle. More...
 
unsigned data_size_ = 0u
 
unsigned data_capacity_ = 100u
 
std::unique_ptr< ParticleData[]> data_
 Points to a dynamically allocated array of ParticleData objects. More...
 
std::vector< unsigned > dirty_
 Stores the indexes in data_ that do not hold valid particle data and should be reused when new particles are added. More...
 

Friends

std::ostream & operator<< (std::ostream &out, const Particles &particles)
 Print effective mass and type name for all particles to the stream. More...
 

Member Typedef Documentation

◆ iterator

An alias to the GenericIterator class of ParticleData.

Definition at line 369 of file particles.h.

◆ const_iterator

An alias to the GenericIterator class of const ParticleData.

Definition at line 371 of file particles.h.

Constructor & Destructor Documentation

◆ Particles() [1/2]

smash::Particles::Particles ( )

Creates a new (empty) Particles object.

Definition at line 17 of file particles.cc.

17  : data_(new ParticleData[data_capacity_]) {
18  for (unsigned i = 0; i < data_capacity_; ++i) {
19  data_[i].index_ = i;
20  }
21 }
std::unique_ptr< ParticleData[]> data_
Points to a dynamically allocated array of ParticleData objects.
Definition: particles.h:498
unsigned data_capacity_
Definition: particles.h:492

◆ Particles() [2/2]

smash::Particles::Particles ( const Particles )
delete

Cannot be copied.

Member Function Documentation

◆ operator=()

Particles& smash::Particles::operator= ( const Particles )
delete

Cannot be copied.

◆ copy_to_vector()

ParticleList smash::Particles::copy_to_vector ( ) const
inline
Returns
a copy of all particles as a std::vector<ParticleData>.

Definition at line 44 of file particles.h.

44  {
45  if (dirty_.empty()) {
46  return {&data_[0], &data_[data_size_]};
47  }
48  return {begin(), end()};
49  }
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
iterator begin()
Definition: particles.h:395
iterator end()
Definition: particles.h:419

◆ insert()

const ParticleData & smash::Particles::insert ( const ParticleData p)

Inserts the particle into the list of particles.

The argument will afterwards not be a valid copy of a particle of the internal list. I.e.

ParticleData particle(type);
particles.insert(particle);
particles.is_valid(particle); // returns false
Parameters
[in]pThe data to be added. The id will not be copied. Instead a new unique id is generated by the function.
Returns
An immutable reference to the new ParticleData object in the Particles list. This is a valid copy (i.e. Particles::is_valid returns true).

Definition at line 50 of file particles.cc.

50  {
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 }
void copy_in(ParticleData &to, const ParticleData &from)
Definition: particles.cc:44
void ensure_capacity(unsigned to_add)
Definition: particles.cc:23
#define likely(x)
Tell the branch predictor that this expression is likely true.
Definition: macros.h:14
constexpr int p
Proton.

◆ create() [1/2]

void smash::Particles::create ( size_t  n,
PdgCode  pdg 
)

Add n particles of the same type (pdg) to the list.

Parameters
[in]nThe number of the added particles
[in]pdgPDG code of the added particles

Definition at line 66 of file particles.cc.

66  {
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 }
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
int id_max_
Highest id of a given particle.
Definition: particles.h:446

◆ create() [2/2]

ParticleData & smash::Particles::create ( const PdgCode  pdg)

Add one particle of the given pdg code.

Parameters
[in]pdgPDG code of the added particle
Returns
a reference to the added particle

Definition at line 89 of file particles.cc.

89  {
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 }

◆ size()

size_t smash::Particles::size ( ) const
inline
Returns
the number of particles in the list.

Definition at line 87 of file particles.h.

87 { return data_size_ - dirty_.size(); }

◆ is_empty()

bool smash::Particles::is_empty ( ) const
inline
Returns
whether the list of particles is empty.

Definition at line 90 of file particles.h.

90 { return data_size_ == 0; }

◆ time()

double smash::Particles::time ( ) const
inline

Returns the time of the computational frame.

Returns
computation time which is reduced by the start up time
Note
This function may only be called if the list of particles is not empty.

Definition at line 100 of file particles.h.

100  {
101  assert(!is_empty());
102  return front().position().x0();
103  }
double x0() const
Definition: fourvector.h:313
const FourVector & position() const
Get the particle's position in Minkowski space.
Definition: particledata.h:204
ParticleData & front()
Definition: particles.h:374
bool is_empty() const
Definition: particles.h:90

◆ reset()

void smash::Particles::reset ( )

Reset the state of the Particles object to an empty list and a new id counter.

The object is thus in the same state as right after construction.

Definition at line 139 of file particles.cc.

139  {
140  id_max_ = -1;
141  data_size_ = 0;
142  for (auto index : dirty_) {
143  data_[index].hole_ = false;
144  }
145  dirty_.clear();
146 }

◆ is_valid()

bool smash::Particles::is_valid ( const ParticleData copy) const
inline

Check whether the ParticleData copy is still a valid copy of the one stored in the Particles object.

Parameters
[in]copyParticleData copy whose validity is going to be checked
Returns
whether ParticleData copy is still valid. If not, then the particle either never was a valid copy or it has interacted (e.g. scatter, decay) since it was copied.

Definition at line 120 of file particles.h.

120  {
121  if (data_size_ <= copy.index_) {
122  return false;
123  }
124  /* Check if the particles still exists. If it decayed
125  * or scattered inelastically it is gone. */
126  return data_[copy.index_].id() == copy.id()
127  /* If the particle has scattered
128  * elastically, its id_process has
129  * changed and we consider it invalid. */
130  && data_[copy.index_].id_process() == copy.id_process();
131  }

◆ remove()

void smash::Particles::remove ( const ParticleData p)

Remove the given particle p from the list.

The argument p must be a valid copy obtained from Particles, i.e. a call to is_valid must return true.

Parameters
[in]pParticle which is going to be removed
Note
The validity of p is only enforced in DEBUG builds.

Definition at line 108 of file particles.cc.

108  {
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 }
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

◆ replace()

void smash::Particles::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.

The particles in to_remove must be valid copies obtained from Particles. The particles in to_add are adjusted to be valid copies of the new particles in the Particles list.

Parameters
[in]to_removeA list of particles which are valid copies out of the Particles list. They identify the entries in Particles to be replaced.
[in]to_addA list of (invalid) ParticleData objects to be placed into the Particles list.
Note
The validity of to_remove is only enforced in DEBUG builds.

Definition at line 120 of file particles.cc.

120  {
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 }
const ParticleData & insert(const ParticleData &p)
Inserts the particle into the list of particles.
Definition: particles.cc:50
void remove(const ParticleData &p)
Remove the given particle p from the list.
Definition: particles.cc:108

◆ update_particle()

const ParticleData& smash::Particles::update_particle ( const ParticleData p,
const ParticleData new_state 
)
inline

Updates the particle identified by p with the state stored in new_state.

A reference to the resulting ParticleData object in the list is subsequently returned.

The state update copies the id_process, momentum, and position from new_state.

This function expects p to be a valid copy (i.e. is_valid returns true) and it expects the ParticleType of p and new_state to be equal. This is enforced in DEBUG builds.

Parameters
[in]pThe particle which is going to be updated.
[in]new_stateThe new state of the particle.
Returns
Updated particle

Definition at line 175 of file particles.h.

176  {
177  assert(is_valid(p));
178  assert(p.type() == new_state.type());
179  ParticleData &original = data_[p.index_];
180  new_state.copy_to(original);
181  return original;
182  }

◆ update()

void smash::Particles::update ( const ParticleList &  old_state,
ParticleList &  new_state,
bool  do_replace 
)
inline

Updates the Particles object, replacing the particles in old_state with the particles in new_state.

The third parameter do_replace determines whether the particles are actually replaced (so that they get new IDs etc) or if the old particles are kept and just updated with new properties (e.g. in an elastic collision).

This function expects old_state to be a valid copy (i.e. is_valid returns true). This is enforced in DEBUG builds.

Parameters
[in]old_stateParticles of old states
[in]new_stateNew states of these particles
[in]do_replaceWhether to replace the old states by the new ones

Definition at line 200 of file particles.h.

201  {
202  if (do_replace) {
203  replace(old_state, new_state);
204  } else {
205  for (std::size_t i = 0; i < old_state.size(); ++i) {
206  new_state[i] = update_particle(old_state[i], new_state[i]);
207  }
208  }
209  }
const ParticleData & update_particle(const ParticleData &p, const ParticleData &new_state)
Updates the particle identified by p with the state stored in new_state.
Definition: particles.h:175
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

◆ lookup()

const ParticleData& smash::Particles::lookup ( const ParticleData old_state) const
inline

Returns the particle that is currently stored in this object given an old copy of that particle.

This function expects old_state to be a valid copy (i.e. is_valid returns true). This is enforced in DEBUG builds.

Parameters
[in]old_stateA copy of old state particle. We need its index to know where it's stored in the particles list.
Returns
The currrent state of the particle which is searched.

Definition at line 222 of file particles.h.

222  {
223  assert(is_valid(old_state));
224  return data_[old_state.index_];
225  }

◆ front() [1/2]

ParticleData& smash::Particles::front ( )
inline
Returns
a reference to the first particle in the list.

Definition at line 374 of file particles.h.

374 { return *begin(); }

◆ front() [2/2]

const ParticleData& smash::Particles::front ( ) const
inline

const overload of &front()

Returns
a reference to the first particle in the list.

Definition at line 380 of file particles.h.

380 { return *begin(); }

◆ back() [1/2]

ParticleData& smash::Particles::back ( )
inline
Returns
a reference to the last particle in the list.

Definition at line 383 of file particles.h.

383 { return *(--end()); }

◆ back() [2/2]

const ParticleData& smash::Particles::back ( ) const
inline

const overload of &back()

Returns
a reference to the last particle in the list.

Definition at line 389 of file particles.h.

389 { return *(--end()); }

◆ begin() [1/2]

iterator smash::Particles::begin ( )
inline
Returns
an iterator pointing to the first particle in the list. Use it to iterate over all particles in the list.

Definition at line 395 of file particles.h.

395  {
396  ParticleData *first = &data_[0];
397  while (first->hole_) {
398  ++first;
399  }
400  return first;
401  }

◆ begin() [2/2]

const_iterator smash::Particles::begin ( ) const
inline

const overload of begin()

Returns
an iterator pointing to the first particle in the list.

Definition at line 407 of file particles.h.

407  {
408  ParticleData *first = &data_[0];
409  while (first->hole_) {
410  ++first;
411  }
412  return first;
413  }

◆ end() [1/2]

iterator smash::Particles::end ( )
inline
Returns
an iterator pointing behind the last particle in the list. Use it to iterate over all particles in the list.

Definition at line 419 of file particles.h.

419 { return &data_[data_size_]; }

◆ end() [2/2]

const_iterator smash::Particles::end ( ) const
inline

const overload of end()

Returns
an iterator pointing behind the last particle in the list.

Definition at line 425 of file particles.h.

425 { return &data_[data_size_]; }

◆ cbegin()

const_iterator smash::Particles::cbegin ( ) const
inline
Returns
a const begin iterator.

Definition at line 428 of file particles.h.

428 { return begin(); }

◆ cend()

const_iterator smash::Particles::cend ( ) const
inline
Returns
a const end iterator.

Definition at line 430 of file particles.h.

430 { return end(); }

◆ increase_capacity()

void smash::Particles::increase_capacity ( unsigned  new_capacity)
private

Increases the capacity of data_ to new_capacity.

Parameters
[in]new_capacitynew capacity which is expected to be larger than data_capacity_. This is enforced in DEBUG builds.

Definition at line 30 of file particles.cc.

30  {
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 }

◆ ensure_capacity()

void smash::Particles::ensure_capacity ( unsigned  to_add)
inlineprivate

Ensure that the capacity of data_ is large enough to hold to_add more entries. If the capacity does not sufficient increase_capacity is called.

Parameters
[in]to_addNumber of particles which is going to be added to the list.

Definition at line 23 of file particles.cc.

23  {
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 }
void increase_capacity(unsigned new_capacity)
Definition: particles.cc:30

◆ copy_in()

void smash::Particles::copy_in ( ParticleData to,
const ParticleData from 
)
inlineprivate

Common implementation for copying the relevant data of a ParticleData object into data_. This does not implement a 1:1 copy, instead:

  • The particle id in data_ is set to the next id for a new particle.
  • The id_process, type, momentum, and position are copied from from.
  • The ParticleData::index_ members is not modified since it already has the correct value
  • The ParticleData::hole_ member is not modified and might need adjustment in the calling code.
Parameters
[out]toThe copied version of the particle added to the end of the to particle list.
[in]fromthe original particle that will be copied.

Definition at line 44 of file particles.cc.

44  {
45  to.id_ = ++id_max_;
46  to.type_ = from.type_;
47  from.copy_to(to);
48 }

Member Data Documentation

◆ id_max_

int smash::Particles::id_max_ = -1
private

Highest id of a given particle.

The first particle added to data_ will have id 0.

Definition at line 446 of file particles.h.

◆ data_size_

unsigned smash::Particles::data_size_ = 0u
private

The number of elements in data_ (including holes, but excluding entries behind the last valid particle)

Definition at line 487 of file particles.h.

◆ data_capacity_

unsigned smash::Particles::data_capacity_ = 100u
private

The capacity of the memory pointed to by data_.

Definition at line 492 of file particles.h.

◆ data_

std::unique_ptr<ParticleData[]> smash::Particles::data_
private

Points to a dynamically allocated array of ParticleData objects.

The allocated size is stored in data_capacity_ and the used range (starting from index 0) is stored in data_size_.

Definition at line 498 of file particles.h.

◆ dirty_

std::vector<unsigned> smash::Particles::dirty_
private

Stores the indexes in data_ that do not hold valid particle data and should be reused when new particles are added.

Definition at line 504 of file particles.h.


The documentation for this class was generated from the following files: