Molecular Dynamics Simulation  1.0
PeriodicBoundaryType.cpp
Go to the documentation of this file.
1 #include "PeriodicBoundaryType.h"
2 
3 #include "io/logger/Logger.h"
5 #include "utils/ArrayUtils.h"
6 #include "utils/Enums.h"
7 
9  if (container.boundary_types[0] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
10  for (Cell* cell : container.left_halo_cell_references) {
11  for (Particle* p : cell->getParticleReferences()) {
12  p->setX(p->getX() + std::array<double, 3>{container.domain_size[0], 0, 0});
13  }
14  }
15  }
16 
17  if (container.boundary_types[1] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
18  for (Cell* cell : container.right_halo_cell_references) {
19  for (Particle* p : cell->getParticleReferences()) {
20  p->setX(p->getX() + std::array<double, 3>{-container.domain_size[0], 0, 0});
21  }
22  }
23  }
24 
25  if (container.boundary_types[2] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
26  for (Cell* cell : container.bottom_halo_cell_references) {
27  for (Particle* p : cell->getParticleReferences()) {
28  p->setX(p->getX() + std::array<double, 3>{0, container.domain_size[1], 0});
29  }
30  }
31  }
32 
33  if (container.boundary_types[3] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
34  for (Cell* cell : container.top_halo_cell_references) {
35  for (Particle* p : cell->getParticleReferences()) {
36  p->setX(p->getX() + std::array<double, 3>{0, -container.domain_size[1], 0});
37  }
38  }
39  }
40 
41  if (container.boundary_types[4] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
42  for (Cell* cell : container.back_halo_cell_references) {
43  for (Particle* p : cell->getParticleReferences()) {
44  p->setX(p->getX() + std::array<double, 3>{0, 0, container.domain_size[2]});
45  }
46  }
47  }
48 
49  if (container.boundary_types[5] == LinkedCellsContainer::LinkedCellsContainer::BoundaryCondition::PERIODIC) {
50  for (Cell* cell : container.front_halo_cell_references) {
51  for (Particle* p : cell->getParticleReferences()) {
52  p->setX(p->getX() + std::array<double, 3>{0, 0, -container.domain_size[2]});
53  }
54  }
55  }
56 }
57 
59  // Add Halo Particles for each side of the domain
60  size_t original_size = container.particles.size();
61 
63  addPeriodicHaloParticlesForSide(container, container.left_boundary_cell_references, {container.domain_size[0], 0, 0});
64  }
65 
67  addPeriodicHaloParticlesForSide(container, container.right_boundary_cell_references, {-container.domain_size[0], 0, 0});
68  }
69 
71  addPeriodicHaloParticlesForSide(container, container.bottom_boundary_cell_references, {0, container.domain_size[1], 0});
72  }
73 
75  addPeriodicHaloParticlesForSide(container, container.top_boundary_cell_references, {0, -container.domain_size[1], 0});
76  }
77 
79  addPeriodicHaloParticlesForSide(container, container.back_boundary_cell_references, {0, 0, container.domain_size[2]});
80  }
81 
83  addPeriodicHaloParticlesForSide(container, container.front_boundary_cell_references, {0, 0, -container.domain_size[2]});
84  }
85 
86  // Add Halo Particles for each edge of the domain
89  addPeriodicHaloParticlesForEdge(container, 2, {container.domain_size[0], container.domain_size[1], 0});
90  }
91 
94  addPeriodicHaloParticlesForEdge(container, 2, {container.domain_size[0], -container.domain_size[1], 0});
95  }
96 
99  addPeriodicHaloParticlesForEdge(container, 2, {-container.domain_size[0], container.domain_size[1], 0});
100  }
101 
104  addPeriodicHaloParticlesForEdge(container, 2, {-container.domain_size[0], -container.domain_size[1], 0});
105  }
106 
109  addPeriodicHaloParticlesForEdge(container, 1, {container.domain_size[0], 0, container.domain_size[2]});
110  }
111 
114  addPeriodicHaloParticlesForEdge(container, 1, {container.domain_size[0], 0, -container.domain_size[2]});
115  }
116 
119  addPeriodicHaloParticlesForEdge(container, 1, {-container.domain_size[0], 0, container.domain_size[2]});
120  }
121 
124  addPeriodicHaloParticlesForEdge(container, 1, {-container.domain_size[0], 0, -container.domain_size[2]});
125  }
126 
129  addPeriodicHaloParticlesForEdge(container, 0, {0, container.domain_size[1], container.domain_size[2]});
130  }
131 
134  addPeriodicHaloParticlesForEdge(container, 0, {0, container.domain_size[1], -container.domain_size[2]});
135  }
136 
139  addPeriodicHaloParticlesForEdge(container, 0, {0, -container.domain_size[1], container.domain_size[2]});
140  }
141 
144  addPeriodicHaloParticlesForEdge(container, 0, {0, -container.domain_size[1], -container.domain_size[2]});
145  }
146 
147  // Add Halo Particles for each corner of the domain
151  addPeriodicHaloParticlesForCorner(container, {container.domain_size[0], container.domain_size[1], container.domain_size[2]});
152  }
153 
157  addPeriodicHaloParticlesForCorner(container, {container.domain_size[0], container.domain_size[1], -container.domain_size[2]});
158  }
159 
163  addPeriodicHaloParticlesForCorner(container, {container.domain_size[0], -container.domain_size[1], container.domain_size[2]});
164  }
165 
169  addPeriodicHaloParticlesForCorner(container, {container.domain_size[0], -container.domain_size[1], -container.domain_size[2]});
170  }
171 
175  addPeriodicHaloParticlesForCorner(container, {-container.domain_size[0], container.domain_size[1], container.domain_size[2]});
176  }
177 
181  addPeriodicHaloParticlesForCorner(container, {-container.domain_size[0], container.domain_size[1], -container.domain_size[2]});
182  }
183 
187  addPeriodicHaloParticlesForCorner(container, {-container.domain_size[0], -container.domain_size[1], container.domain_size[2]});
188  }
189 
193  addPeriodicHaloParticlesForCorner(container, {-container.domain_size[0], -container.domain_size[1], -container.domain_size[2]});
194  }
195 
196  return original_size;
197 }
198 
199 void PeriodicBoundaryType::addPeriodicHaloParticlesForSide(LinkedCellsContainer& container, const std::vector<Cell*>& side_cell_references,
200  const std::array<double, 3>& offset) {
201  for (Cell* cell : side_cell_references) {
202  for (Particle* p : cell->getParticleReferences()) {
203  Particle ghost_particle = Particle(*p);
204  ghost_particle.setLocked(LockState::LOCKED);
205  ghost_particle.setX(p->getX() + offset);
206  container.addParticle(ghost_particle);
207  }
208  }
209 }
210 
212  const std::array<double, 3>& offset) {
213  std::array<int, 3> running_array{0, 0, 0};
214  running_array[0] = (offset[0] < 0) ? container.domain_num_cells[0] - 1 : 0;
215  running_array[1] = (offset[1] < 0) ? container.domain_num_cells[1] - 1 : 0;
216  running_array[2] = (offset[2] < 0) ? container.domain_num_cells[2] - 1 : 0;
217 
218  for (int c = 0; c < container.domain_num_cells[free_dimension]; ++c) {
219  Cell* cell = &container.cells.at(container.cellCoordToCellIndex(running_array[0], running_array[1], running_array[2]));
220  for (Particle* p : cell->getParticleReferences()) {
221  Particle ghost_particle = Particle(*p);
222  ghost_particle.setLocked(LockState::LOCKED);
223  ghost_particle.setX(p->getX() + offset);
224  container.addParticle(ghost_particle);
225  }
226  running_array[free_dimension] += 1;
227  }
228 }
229 
230 void PeriodicBoundaryType::addPeriodicHaloParticlesForCorner(LinkedCellsContainer& container, const std::array<double, 3>& offset) {
231  std::array<int, 3> cell_coords{0, 0, 0};
232  cell_coords[0] = (offset[0] < 0) ? container.domain_num_cells[0] - 1 : 0;
233  cell_coords[1] = (offset[1] < 0) ? container.domain_num_cells[1] - 1 : 0;
234  cell_coords[2] = (offset[2] < 0) ? container.domain_num_cells[2] - 1 : 0;
235 
236  Cell* cell = &container.cells.at(container.cellCoordToCellIndex(cell_coords[0], cell_coords[1], cell_coords[2]));
237  for (Particle* p : cell->getParticleReferences()) {
238  Particle ghost_particle = Particle(*p);
239  ghost_particle.setLocked(LockState::LOCKED);
240  ghost_particle.setX(p->getX() + offset);
241  container.addParticle(ghost_particle);
242  }
243 }
Class representing a cell in the linked cells algorithm.
Definition: Cell.h:12
std::vector< Particle * > & getParticleReferences()
Get the reference vector for the particles the cell contains.
Definition: Cell.cpp:7
Extension of the ParticleContainer class using a linked cells data structure for improved performance...
std::vector< Cell * > right_halo_cell_references
References to the halo cells on the right (x = domain_num_cells[0])
std::vector< Cell * > bottom_boundary_cell_references
References to the boundary cells on the bottom (y = 0)
std::vector< Cell * > top_boundary_cell_references
References to the boundary cells on the top (y = domain_num_cells[1]-1)
void addParticle(const Particle &p) override
Adds a particle to the container.
std::vector< Cell * > front_halo_cell_references
References to the halo cells on the front (z = domain_num_cells[2])
std::vector< Cell * > bottom_halo_cell_references
References to the halo cells on the bottom (y = -1)
std::array< double, 3 > domain_size
Domain size in each dimension.
int cellCoordToCellIndex(int cx, int cy, int cz) const
Maps the cell coordinates to the corresponding index in the internal cell vector.
std::vector< Cell * > left_halo_cell_references
References to the halo cells on the left (x = -1)
std::array< int, 3 > domain_num_cells
Number of cells in each dimension.
std::vector< Cell > cells
Internal data structure for the cells.
std::vector< Cell * > right_boundary_cell_references
References to the boundary cells on the right (x = domain_num_cells[0]-1)
std::vector< Cell * > top_halo_cell_references
References to the halo cells on the top (y = domain_num_cells[1])
std::vector< Cell * > left_boundary_cell_references
References to the boundary cells on the left (x = 0)
std::vector< Cell * > back_halo_cell_references
References to the halo cells on the back (z = -1)
std::vector< Cell * > back_boundary_cell_references
References to the boundary cells on the back (z = 0)
std::vector< Cell * > front_boundary_cell_references
References to the boundary cells on the front (z = domain_num_cells[2]-1)
std::array< BoundaryCondition, 6 > boundary_types
The boundary types for each side of the domain (order in array: left, right, bottom,...
std::vector< Particle > particles
Internal data structure for the particles.
Class to represent a particle.
Definition: Particle.h:26
void setX(const std::array< double, 3 > &x)
Sets the position of the particle.
Definition: Particle.h:109
void setLocked(LockState new_lock_state)
Set wheter the particle is locked in space.
Definition: Particle.h:197
static size_t applyBoundaryConditions(LinkedCellsContainer &container)
Applies the boundary conditions for the periodic boundary condition.
static void addPeriodicHaloParticlesForSide(LinkedCellsContainer &container, const std::vector< Cell * > &side_cell_references, const std::array< double, 3 > &offset)
Adds the periodic halo particles for the given side of the container to the other side of the contain...
static void pre(LinkedCellsContainer &container)
Applies the preconditioning step for the periodic boundary condition.
static void addPeriodicHaloParticlesForEdge(LinkedCellsContainer &container, int free_dimension, const std::array< double, 3 > &offset)
Adds the periodic halo particles for the given edge of the container to the diagonally opposite edge ...
static void addPeriodicHaloParticlesForCorner(LinkedCellsContainer &container, const std::array< double, 3 > &offset)
Adds the periodic halo particles for the given corner of the container to the diagonally opposite cor...