ls1-MarDyn
ls1-MarDyn molecular dynamics code
RegionParticleIterator.h
1/**************************************************************************************
2 *
3 * \file RegionParticleIterator.h
4 *
5 * \brief Iterator class for cell based particle containers
6 *
7 * \author Andrei Costinescu (costines), costines 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 in a specific region and, within each cell, a fine iteration over the particles.
11 *
12 **************************************************************************************/
13
14#pragma once
15
16#ifdef MARDYN_AUTOPAS
17
18#include "ParticleIterator.h"
20public:
21 RegionParticleIterator() = default;
22 explicit RegionParticleIterator(const autopas::IteratorTraits<AutoPasSimpleMolecule>::iterator_t& parent)
23 : ParticleIterator(parent){};
24};
25
26#else
27
28#include <vector>
29#include <stdexcept>
30#include "utils/mardyn_assert.h"
31#include "ParticleIterator.h"
32
34 public:
36 RegionParticleIterator (Type t, CellContainer_T_ptr cells_arg, const CellIndex_T offset_arg, const CellIndex_T stride_arg, const int startCellIndex_arg, const int regionDimensions_arg[3], const int globalDimensions_arg[3], const double startRegion_arg[3], const double endRegion_arg[3]);
37 RegionParticleIterator& operator=(const RegionParticleIterator& other);
38
39 void operator++() override;
40 private:
41
42 CellIndex_T getGlobalCellIndex();
43 void next_non_empty_cell() override;
44
45 CellIndex_T _baseX;
46 CellIndex_T _baseY;
47 CellIndex_T _baseZ;
48 CellIndex_T _localCellIndex;
49 CellIndex_T _regionDimensions[3];
50 CellIndex_T _globalDimensions[3];
51
52 double _startRegion[3];
53 double _endRegion[3];
54};
55
56inline RegionParticleIterator :: RegionParticleIterator () : ParticleIterator(), _localCellIndex(0) {
57}
58
59inline RegionParticleIterator :: RegionParticleIterator (Type t, CellContainer_T_ptr cells_arg, const CellIndex_T offset_arg, const CellIndex_T stride_arg, const int startCellIndex_arg, const int regionDimensions_arg[3], const int globalDimensions_arg[3], const double startRegion_arg[3], const double endRegion_arg[3]) :
60 ParticleIterator(t, cells_arg, offset_arg, stride_arg, false), _localCellIndex (offset_arg) {
61
62#ifdef ENABLE_REDUCED_MEMORY_MODE
63 _cell_index = offset_arg;
64#endif
65
66 for (int d = 0; d < 3; d++) {
67 _regionDimensions[d] = regionDimensions_arg[d];
68 _globalDimensions[d] = globalDimensions_arg[d];
69 _startRegion[d] = startRegion_arg[d];
70 _endRegion[d] = endRegion_arg[d];
71 }
72
73 _baseZ = startCellIndex_arg / (_globalDimensions[0] * _globalDimensions[1]);
74 _baseY = (startCellIndex_arg % (_globalDimensions[0] * _globalDimensions[1])) / _globalDimensions[0];
75 _baseX = (startCellIndex_arg % (_globalDimensions[0] * _globalDimensions[1])) % _globalDimensions[0];
76
77 _cell_index = getGlobalCellIndex();
78 updateCellIteratorCell();
79
80 mardyn_assert(_cells != nullptr);
81
82 const CellContainer_T& cells = *_cells;
83 const CellIndex_T numCellsInRegion = _regionDimensions[2] * _regionDimensions[1] * _regionDimensions[0]; //cells.size();
84
85 // if _cell_index is out of the region => invalid <=> (_localCellIndex >= numCellsInRegion)
86 if (_localCellIndex < numCellsInRegion) {
87 /*
88 if (cells[_cell_index].isEmpty()) {
89 next_non_empty_cell();
90 }
91 */
92// _currentParticleDeleted = true;
93
94 if (cells[_cell_index].isNotEmpty() and (this->operator*()).inBox(_startRegion, _endRegion)) {
95 // if the particle is good, leave it
96 } else {
97 // else, find a particle in the box
98 this->operator++();
99 }
100 } else {
101 // set to invalid
102 _cells = nullptr;
103 }
104}
105
106inline RegionParticleIterator& RegionParticleIterator::operator=(const RegionParticleIterator& other) {
107 mardyn_assert(_stride == other._stride);
108 _cells = other._cells;
109 _cell_index = other._cell_index;
110 _cell_iterator = other._cell_iterator;
111 _baseX = other._baseX;
112 _baseY = other._baseY;
113 _baseZ = other._baseZ;
114 _localCellIndex = other._localCellIndex;
115 for(int d = 0; d < 3; d++){
116 _regionDimensions[d] = other._regionDimensions[d];
117 _globalDimensions[d] = other._globalDimensions[d];
118 _startRegion[d] = other._startRegion[d];
119 _endRegion[d] = other._endRegion[d];
120 }
121 return *this;
122}
123
124inline void RegionParticleIterator :: operator ++() {
125 do{
126 ParticleIterator :: operator++();
127 } while (isValid() and !(this->operator*()).inBox(_startRegion, _endRegion));
128}
129
130inline void RegionParticleIterator :: next_non_empty_cell() {
131 //cellIndex should always be the index in the cell array (_cells member variable in LinkedCells)
132 mardyn_assert(_cells != nullptr);
133
134 const CellContainer_T& cells = *_cells;
135 const CellIndex_T numCellsInRegion = _regionDimensions[2] * _regionDimensions[1] * _regionDimensions[0];
136
137 // find the next non-empty cell
138 for (_localCellIndex += _stride; _localCellIndex < numCellsInRegion; _localCellIndex += _stride) {
139
140 const ParticleCellBase & c = cells.at(getGlobalCellIndex());
141
142 if (c.isNotEmpty() and (_type == ALL_CELLS or not c.isHaloCell())) {
143 _cell_index = getGlobalCellIndex();
144 updateCellIteratorCell();
145 break;
146 }
147 }
148}
149
150inline ParticleIterator::CellIndex_T RegionParticleIterator :: getGlobalCellIndex() {
151 CellIndex_T dz = _localCellIndex / (_regionDimensions[0] * _regionDimensions[1]);
152 CellIndex_T dy = (_localCellIndex % (_regionDimensions[0] * _regionDimensions[1])) / _regionDimensions[0];
153 CellIndex_T dx = (_localCellIndex % (_regionDimensions[0] * _regionDimensions[1])) % _regionDimensions[0];
154 return (_baseX + dx) + (_baseY + dy) * _globalDimensions[0] + (_baseZ + dz) * _globalDimensions[0] * _globalDimensions[1];
155}
156
157#endif // MARDYN_AUTOPAS
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: RegionParticleIterator.h:33