ls1-MarDyn
ls1-MarDyn molecular dynamics code
ParticleIterator.h
1/*************************************************************************************
2 *
3 * \file ParticleIterator.h
4 *
5 * \brief Iterator class for cell based particle containers
6 *
7 * \author Wolfgang Hölzl (hoelzlw), hoelzlw AT in.tum.de
8 *
9 * \details This class implements a forward iterator for the cell based particle containers.
10 * It does a coarse iteration over the cells and, within each cell, a fine iteration over the particles.
11 *
12 **************************************************************************************/
13
14#pragma once
15
16#ifdef MARDYN_AUTOPAS
17// AUTOPAS WRAPPER
18#include "molecules/AutoPasSimpleMolecule.h"
19#include <autopas/iterators/ParticleIteratorWrapper.h>
20
24class ParticleIterator : public autopas::IteratorTraits<AutoPasSimpleMolecule>::iterator_t {
25public:
26
27 enum Type {
28 ALL_CELLS=0, /* iterates every cell */
29 ONLY_INNER_AND_BOUNDARY=1, /* iterates only inner and boundary cells, i.e. no halo cells */
30 };
31
32 ParticleIterator() = default;
33
34 ParticleIterator(const autopas::IteratorTraits<AutoPasSimpleMolecule>::iterator_t& parent)
35 : autopas::IteratorTraits<AutoPasSimpleMolecule>::iterator_t(parent) {}
36
37 size_t getCellIndex() {
38 return 0; // not yet implemented
39 }
40};
41
42#else
43#include <vector>
44#include <stdexcept>
45#include "utils/mardyn_assert.h"
46#include "SingleCellIterator.h"
47#include "ParticleCell.h"
48#include "WrapOpenMP.h"
49
51public:
52 enum Type {
53 ALL_CELLS=0, /* iterates every cell */
54 ONLY_INNER_AND_BOUNDARY=1, /* iterates only inner and boundary cells, i.e. no halo cells */
55 };
56
57 typedef std::vector<ParticleCell> CellContainer_T;
58 typedef CellContainer_T* CellContainer_T_ptr;
59 typedef size_t CellIndex_T;
60 typedef size_t MolIndex_T;
61
63 ParticleIterator (Type t_arg, CellContainer_T_ptr cells_arg, const CellIndex_T offset_arg, const CellIndex_T stride_arg, const bool initialize=true);
64 ParticleIterator& operator=(const ParticleIterator& other);
65
66 virtual ~~ParticleIterator(){}
67
68 Molecule& operator * () const;
69 Molecule* operator -> () const;
70
71 void deleteCurrentParticle();
72
73 CellIndex_T getCellIndex(){return _cell_index;}
74
75 bool isValid() const {
76 return _cells != nullptr and _cell_index < _cells->size() and _cell_iterator.isValid();
77 }
78
79 virtual void operator ++ ();
80
81protected:
82
83
85 Type _type;
86 CellContainer_T_ptr _cells;
87
88 CellIndex_T _cell_index;
89
90 const CellIndex_T _stride;
91
92 virtual void next_non_empty_cell();
93 virtual void updateCellIteratorCell();
94};
95
96
97inline ParticleIterator :: ParticleIterator () : _cell_iterator(), _type(ALL_CELLS), _cells (nullptr), _cell_index (0), _stride (1) {
98}
99
100inline ParticleIterator :: ParticleIterator (Type t_arg, CellContainer_T_ptr cells_arg, const CellIndex_T offset_arg, const CellIndex_T stride_arg, const bool initialize) :
101 _cell_iterator(&(cells_arg->front())), _type(t_arg), _cells (cells_arg), _cell_index (offset_arg), _stride (stride_arg) {
102 if ( !initialize ) {
103 return;
104 }
105
106#ifdef ENABLE_REDUCED_MEMORY_MODE
107 const unsigned long my_start = _cells->size() * mardyn_get_thread_num() / mardyn_get_num_threads();
108 _cell_index = static_cast<CellIndex_T>(my_start);
109#endif
110 updateCellIteratorCell();
111
112 mardyn_assert(_cells != nullptr);
113
114 const CellContainer_T& cells = *_cells;
115
116 if(_cell_index < cells.size()) {
117 if(cells.at(_cell_index).isEmpty() or (_type == ONLY_INNER_AND_BOUNDARY and cells.at(_cell_index).isHaloCell())) {
118 next_non_empty_cell();
119 }
120 /*
121 else {
122 // leave object as is
123 }
124 */
125 }
126}
127
128inline ParticleIterator& ParticleIterator::operator=(const ParticleIterator& other) {
129 mardyn_assert(_stride == other._stride);
130 _cell_iterator = other._cell_iterator;
131 _type = other._type;
132 _cells = other._cells;
133 _cell_index = other._cell_index;
134 return *this;
135}
136
137inline void ParticleIterator :: next_non_empty_cell() {
138 mardyn_assert(_cells != nullptr);
139
140 const CellContainer_T& cells = *_cells;
141 const CellIndex_T numCells = cells.size();
142
143 // find the next non-empty cell
144#ifndef ENABLE_REDUCED_MEMORY_MODE
145 for (_cell_index += _stride; _cell_index < numCells; _cell_index += _stride) {
146#else
147 const unsigned long my_end = _cells->size() * (mardyn_get_thread_num() + 1) / mardyn_get_num_threads();
148 for (_cell_index++; _cell_index < my_end; ++_cell_index) {
149#endif
150
151 const ParticleCellBase & c = cells.at(_cell_index);
152
153 // if we want only inner/boundary cells: check if it is a halo cell
154 if(_type == ONLY_INNER_AND_BOUNDARY and c.isHaloCell()){
155 continue;
156 }
157
158 // only use this cell if it is not empty
159 if(c.isNotEmpty()) {
160 updateCellIteratorCell();
161 break;
162 }
163 }
164}
165
166inline void ParticleIterator :: operator ++ () {
167
168 if (_cell_iterator.isValid()) {
169 ++_cell_iterator;
170 }
171
172 // don't merge into if-else, _cell_iterator may become invalid after ++
173
174 if (not _cell_iterator.isValid()) {
175 next_non_empty_cell();
176 }
177}
178
179inline Molecule& ParticleIterator :: operator * () const {
180 // .at method performs automatically an out-of-bounds check
181 mardyn_assert(&_cells->at(_cell_index) == dynamic_cast<const ParticleCell*>(_cell_iterator.getCell()));
182 return _cell_iterator.operator *();
183}
184
185// no clue why this returns a pointer
186inline Molecule* ParticleIterator:: operator -> () const {
187 return &(this->operator*());
188}
189
190inline void ParticleIterator :: deleteCurrentParticle () {
191 _cell_iterator.deleteCurrentParticle();
192}
193
194inline void ParticleIterator :: updateCellIteratorCell() {
195 if(_cell_index < _cells->size()) {
196 _cell_iterator = SingleCellIterator<ParticleCell>(&_cells->at(_cell_index));
197 }
198}
199#endif // MARDYN_AUTOPAS
Definition: AutoPasSimpleMolecule.h:18
FullMolecule modeled as LJ sphere with point polarities.
Definition: FullMolecule.h:18
FullParticleCell data structure. Renamed from ParticleCell.
Definition: FullParticleCell.h:49
ParticleCellBase defines the interface for cells used by the LinkedCells data structure to store mole...
Definition: ParticleCellBase.h:23
bool isNotEmpty() const
Check if current cell contains molecules.
Definition: ParticleCellBase.h:44
Definition: ParticleIterator.h:50
Definition: SingleCellIterator.h:14