Molecular Dynamics  v0.4
Project for the Practical hosted by the Scientific Computing Chair
Public Member Functions | Private Member Functions | Private Attributes | List of all members
LinkedCellsContainer Class Reference

Container to store the particles for simulation using the linked cells algorithm. More...

#include <LinkedCellsContainer.h>

Inheritance diagram for LinkedCellsContainer:
Inheritance graph
Collaboration diagram for LinkedCellsContainer:
Collaboration graph

Public Member Functions

 LinkedCellsContainer (std::array< double, 3 > domainSize, double rCutOff, BoundarySet boundarySet)
 Constructor of the LinkedCellsContainer class. More...
 
int calcCellIndex (const std::array< double, 3 > &position)
 Calculate the index of the cell to which a particle decided by its position belongs. More...
 
void add (Particle &p) override
 Add a particle to this container. More...
 
int threeDToOneD (int x, int y, int z) const
 Convert 3 dimensional coordinates to one dimensional coordinates. More...
 
int threeDToOneDDomain (int x, int y, int z) const
 
std::array< int, 3 > oneDToThreeD (int index) const
 Convert a one dimensional coordinate to three dimensional coordinates. More...
 
void updateCells ()
 Assign each particle to its correct cell after there positions have been changed. More...
 
void clearHaloCells (Side side)
 Delete all particles in all halo cells being part of a specific size. More...
 
void applyToEachParticle (const std::function< void(Particle &)> &function) override
 Iterate over all particles in this container and apply a lambda function to them. More...
 
void applyToEachParticleInDomain (const std::function< void(Particle &)> &function) override
 Iterate over all particles that are part of the domain and apply a lambda function to them. More...
 
void applyToAllUniquePairsInDomain (const std::function< void(Particle &, Particle &)> &function) override
 Iterate over all unique pairs of particles being part of the simulation domain and apply a lambda function to them. More...
 
void applyToAllUniquePairsInDomainOptimized (const std::function< void(Particle &, Particle &, std::array< double, 3 >, double)> &function)
 Implements the optimization we presented as our second idea. At the moment this is dead code, because we did not have time yet to make it compatible with our current program structure and only integrated it once when doing the time measurements. More...
 
void applyToAllBoundaryParticles (const std::function< void(Particle &, std::array< double, 3 > &)> &function, Side boundary)
 Iterate over all particles in the boundary cells of a specific side which have a distance to that side that is smaller or equal than the threshold. More...
 
size_t size () const override
 Get the number of particles stored in this container. More...
 
std::array< double, 3 > fromLowToHigh (const std::array< double, 3 > &position, int dimension)
 Move a particle along a certain dimension that underflows the domain int that dimension to the opposite side of the domain in that dimension. More...
 
std::array< double, 3 > fromHighToLow (const std::array< double, 3 > &position, int dimension)
 Move a particle along a certain dimension that overflows the domain int that dimension to the opposite side of the domain in that dimension. More...
 
void teleportParticlesToOppositeSide (Side sideStart)
 Moves particles along a certain dimension from the halo cells back into the simulation domain. More...
 
void applyForcesFromOppositeSide (Side side)
 Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles on the specified cell on the specified side. More...
 
std::vector< std::vector< Particle > > & getCells ()
 
std::array< std::vector< int >, 6 > & getHaloCells ()
 
std::array< std::vector< int >, 6 > & getBoundaries ()
 
std::vector< std::vector< int > > & getDomainCellIterationScheme ()
 
int getNX () const
 
int getNY () const
 
int getNZ () const
 
double getCellSizeX () const
 
double getCellSizeY () const
 
double getCellSizeZ () const
 
double getRCutOff () const
 
bool isTwoD () const
 
std::array< double, 3 > getDomainSize () const
 
- Public Member Functions inherited from ParticleContainer
virtual ~ParticleContainer ()=default
 Virtual default constructor to guarantee appropriate memory clean up. More...
 

Private Member Functions

void calculateHaloCellIndices ()
 Pre-calculation of all halo cell indices. More...
 
void calculateBoundaryCellIndices ()
 Pre-calculation of all boundary cell indices. More...
 
void calculateDomainCellsIterationScheme ()
 Pre-calculation of the indices defining the processing order of cells. More...
 
void calculateScheduleParallelSophisticatedHelper (int xStart, int yStart, int zStart)
 
void calculateScheduleNaive ()
 
void calculateScheduleParallelSophisticated ()
 
double calcDistanceFromBoundary (Particle &p, Side side)
 Calculate the distance that a particle has to a specific side of the domain. In 2D the distance to sides top and bottom is always 0. More...
 
std::array< double, 3 > calcGhostParticle (Particle &p, Side side)
 Calculate the position of the ghost particle with respect to a specific side used for reflective boundaries. More...
 
void teleportParticlesToOppositeSideHelper (Side sideStart, int dimension, int modus)
 Moves particles along a certain dimension from the halo cells back into the simulation domain. More...
 
void applyForceToOppositeCellsHelper (Side side, std::array< int, 3 > cellToProcess)
 Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles on the specified cell on the specified side. More...
 
void applyForceToOppositeEdgeHelper (std::array< int, 3 > cellToProcess, std::array< int, 3 > offsetCell, std::array< double, 3 > offsetPosition, int dim)
 Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles of the specified cell. More...
 
bool isCellInDomain (std::array< int, 3 > cell) const
 Checks, if the specified cell is part of the domain. More...
 
bool isParticleInDomain (const std::array< double, 3 > &position) const
 Checks, if the specified particle is inside the domain. More...
 
void applyForcesBetweenTwoCells (int cellTarget, int cellSource, std::array< double, 3 > offsetSource)
 Calculates the forces that particles in the cell source apply to the particles in cell target. More...
 

Private Attributes

std::vector< std::vector< Particle > > cells
 
size_t currentSize
 
std::array< std::vector< int >, 6 > haloCells
 
std::array< std::vector< int >, 6 > boundaries
 
std::vector< std::vector< int > > domainCellIterationScheme
 
std::vector< int > scheduleParallelNaive
 
std::vector< int > scheduleParallelSophisticated
 
int nX
 
int nY
 
int nZ
 
int baseY
 
int baseZ
 
int baseYDomain
 
int baseZDomain
 
double cellSizeX
 
double cellSizeY
 
double cellSizeZ
 
double rCutOff
 
bool twoD
 
std::array< double, 3 > domainSize
 
outputWriter::VTKWriter vtk_writer
 
LennardJonesForce lJF
 
BoundarySet boundariesSet
 

Detailed Description

Container to store the particles for simulation using the linked cells algorithm.

Constructor & Destructor Documentation

◆ LinkedCellsContainer()

LinkedCellsContainer::LinkedCellsContainer ( std::array< double, 3 >  domainSize,
double  rCutOff,
BoundarySet  boundarySet 
)

Constructor of the LinkedCellsContainer class.

Constructor and methods

Parameters
domainSizeSize of the simulation domain. Syntax {x, y, z}. Front lower left corner is by definition (0,0,0).
rCutOffThe cut-off radius
Here is the call graph for this function:

Member Function Documentation

◆ add()

void LinkedCellsContainer::add ( Particle p)
overridevirtual

Add a particle to this container.

Parameters
pParticle to be added.

If the simulation environment is 2D, only particles living in 2D space are accepted. Try adding particles living in 3D space to 2D simulation environment will lead to the termination of the program.

Implements ParticleContainer.

Here is the call graph for this function:

◆ applyForcesBetweenTwoCells()

void LinkedCellsContainer::applyForcesBetweenTwoCells ( int  cellTarget,
int  cellSource,
std::array< double, 3 >  offsetSource 
)
private

Calculates the forces that particles in the cell source apply to the particles in cell target.

Parameters
cellTargetIndex of the cell containing the particles to which the force is applied.
cellSourceIndex of the cell containing the particles which exert the force.
offsetSourceOffset to move the particles of the cell source in the right position for force calculations.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyForcesFromOppositeSide()

void LinkedCellsContainer::applyForcesFromOppositeSide ( Side  side)

Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles on the specified cell on the specified side.

Parameters
sideSide on which the force is exerted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyForceToOppositeCellsHelper()

void LinkedCellsContainer::applyForceToOppositeCellsHelper ( Side  side,
std::array< int, 3 >  cellToProcess 
)
private

Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles on the specified cell on the specified side.

Parameters
sideSide on which the force is exerted.
cellToProcessSpecific cell of that side.
Here is the caller graph for this function:

◆ applyForceToOppositeEdgeHelper()

void LinkedCellsContainer::applyForceToOppositeEdgeHelper ( std::array< int, 3 >  cellToProcess,
std::array< int, 3 >  offsetCell,
std::array< double, 3 >  offsetPosition,
int  dim 
)
private

Used for periodic boundaries to calculate the force that all particles from the opposite edge exert on the particles of the specified cell.

Parameters
cellToProcessCell on which particles the force is exerted.
offsetCellOffset to reach the cell of the opposite edge.
offsetPositionOffset to move the particles of the opposite edge to the current edge for proper force calculation.
dimDimension in which the edge is living.
Here is the caller graph for this function:

◆ applyToAllBoundaryParticles()

void LinkedCellsContainer::applyToAllBoundaryParticles ( const std::function< void(Particle &, std::array< double, 3 > &)> &  function,
Side  boundary 
)

Iterate over all particles in the boundary cells of a specific side which have a distance to that side that is smaller or equal than the threshold.

Parameters
functionLambda function that is applied to each particle fulfilling the requirements.
boundarySide to which the boundary cells belong.

Additionally, the position of the corresponding ghost particle of each particle is calculated and passed in the lambda function as second input. This information makes the implementation of reflective boundaries a lot easier.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyToAllUniquePairsInDomain()

void LinkedCellsContainer::applyToAllUniquePairsInDomain ( const std::function< void(Particle &, Particle &)> &  function)
overridevirtual

Iterate over all unique pairs of particles being part of the simulation domain and apply a lambda function to them.

Parameters
functionLambda function that is applied to each unique pair of particles.

The purpose of this function is provide an easy way of calculating the force between all particles by using Newton's third law of motion.

Implements ParticleContainer.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyToAllUniquePairsInDomainOptimized()

void LinkedCellsContainer::applyToAllUniquePairsInDomainOptimized ( const std::function< void(Particle &, Particle &, std::array< double, 3 >, double)> &  function)

Implements the optimization we presented as our second idea. At the moment this is dead code, because we did not have time yet to make it compatible with our current program structure and only integrated it once when doing the time measurements.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyToEachParticle()

void LinkedCellsContainer::applyToEachParticle ( const std::function< void(Particle &)> &  function)
overridevirtual

Iterate over all particles in this container and apply a lambda function to them.

Parameters
functionLambda function that is applied to each particle.

Implements ParticleContainer.

◆ applyToEachParticleInDomain()

void LinkedCellsContainer::applyToEachParticleInDomain ( const std::function< void(Particle &)> &  function)
overridevirtual

Iterate over all particles that are part of the domain and apply a lambda function to them.

Parameters
functionLambda function that is applied to each particle.

Implements ParticleContainer.

Here is the caller graph for this function:

◆ calcCellIndex()

int LinkedCellsContainer::calcCellIndex ( const std::array< double, 3 > &  position)

Calculate the index of the cell to which a particle decided by its position belongs.

Parameters
positionPosition of the particle to calculate the cell index of.
Returns
Corresponding cell index.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calcDistanceFromBoundary()

double LinkedCellsContainer::calcDistanceFromBoundary ( Particle p,
Side  side 
)
private

Calculate the distance that a particle has to a specific side of the domain. In 2D the distance to sides top and bottom is always 0.

Parameters
pParticle used for distance calculation
sideSide of the domain to which the distance is calculated
Returns
Distance of particle p to the specified side.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calcGhostParticle()

std::array< double, 3 > LinkedCellsContainer::calcGhostParticle ( Particle p,
Side  side 
)
private

Calculate the position of the ghost particle with respect to a specific side used for reflective boundaries.

Parameters
pParticle to calculate the corresponding ghost particle of.
sideSide of the domain at which the particle is mirrored.
Returns
Position of the ghost particle.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateBoundaryCellIndices()

void LinkedCellsContainer::calculateBoundaryCellIndices ( )
private

Pre-calculation of all boundary cell indices.

Here is the caller graph for this function:

◆ calculateDomainCellsIterationScheme()

void LinkedCellsContainer::calculateDomainCellsIterationScheme ( )
private

Pre-calculation of the indices defining the processing order of cells.

Here is the caller graph for this function:

◆ calculateHaloCellIndices()

void LinkedCellsContainer::calculateHaloCellIndices ( )
private

Pre-calculation of all halo cell indices.

Here is the caller graph for this function:

◆ calculateScheduleNaive()

void LinkedCellsContainer::calculateScheduleNaive ( )
private
Here is the caller graph for this function:

◆ calculateScheduleParallelSophisticated()

void LinkedCellsContainer::calculateScheduleParallelSophisticated ( )
private
Here is the caller graph for this function:

◆ calculateScheduleParallelSophisticatedHelper()

void LinkedCellsContainer::calculateScheduleParallelSophisticatedHelper ( int  xStart,
int  yStart,
int  zStart 
)
private

◆ clearHaloCells()

void LinkedCellsContainer::clearHaloCells ( Side  side)

Delete all particles in all halo cells being part of a specific size.

Parameters
sideSide at which all halo cells are cleared.
Here is the caller graph for this function:

◆ fromHighToLow()

std::array< double, 3 > LinkedCellsContainer::fromHighToLow ( const std::array< double, 3 > &  position,
int  dimension 
)

Move a particle along a certain dimension that overflows the domain int that dimension to the opposite side of the domain in that dimension.

Parameters
positionCurrent position of the particle.
dimensionDimension along the particle is moved.
Returns
New position.

◆ fromLowToHigh()

std::array< double, 3 > LinkedCellsContainer::fromLowToHigh ( const std::array< double, 3 > &  position,
int  dimension 
)

Move a particle along a certain dimension that underflows the domain int that dimension to the opposite side of the domain in that dimension.

Parameters
positionCurrent position of the particle.
dimensionDimension along the particle is moved.
Returns
New position.

◆ getBoundaries()

std::array<std::vector<int>, 6>& LinkedCellsContainer::getBoundaries ( )
inline

◆ getCells()

std::vector<std::vector<Particle> >& LinkedCellsContainer::getCells ( )
inline

◆ getCellSizeX()

double LinkedCellsContainer::getCellSizeX ( ) const
inline

◆ getCellSizeY()

double LinkedCellsContainer::getCellSizeY ( ) const
inline

◆ getCellSizeZ()

double LinkedCellsContainer::getCellSizeZ ( ) const
inline

◆ getDomainCellIterationScheme()

std::vector<std::vector<int> >& LinkedCellsContainer::getDomainCellIterationScheme ( )
inline

◆ getDomainSize()

std::array<double, 3> LinkedCellsContainer::getDomainSize ( ) const
inline

◆ getHaloCells()

std::array<std::vector<int>, 6>& LinkedCellsContainer::getHaloCells ( )
inline

◆ getNX()

int LinkedCellsContainer::getNX ( ) const
inline

◆ getNY()

int LinkedCellsContainer::getNY ( ) const
inline

◆ getNZ()

int LinkedCellsContainer::getNZ ( ) const
inline

◆ getRCutOff()

double LinkedCellsContainer::getRCutOff ( ) const
inline

◆ isCellInDomain()

bool LinkedCellsContainer::isCellInDomain ( std::array< int, 3 >  cell) const
private

Checks, if the specified cell is part of the domain.

Parameters
cellCell to check.
Returns
True if cell is part of the domain, false otherwise.

◆ isParticleInDomain()

bool LinkedCellsContainer::isParticleInDomain ( const std::array< double, 3 > &  position) const
private

Checks, if the specified particle is inside the domain.

Parameters
positionPosition of the particle.
Returns
True if the particle is inside the domain, false otherwise.

◆ isTwoD()

bool LinkedCellsContainer::isTwoD ( ) const
inline
Here is the caller graph for this function:

◆ oneDToThreeD()

std::array< int, 3 > LinkedCellsContainer::oneDToThreeD ( int  index) const

Convert a one dimensional coordinate to three dimensional coordinates.

Parameters
indexOne dimensional coordinate
Returns
Corresponding coordinates in three dimensional space.

◆ size()

size_t LinkedCellsContainer::size ( ) const
overridevirtual

Get the number of particles stored in this container.

Returns
Number of particles stored in this container.

Implements ParticleContainer.

◆ teleportParticlesToOppositeSide()

void LinkedCellsContainer::teleportParticlesToOppositeSide ( Side  sideStart)

Moves particles along a certain dimension from the halo cells back into the simulation domain.

Parameters
sideStartSide from which the particles will be teleported to the opposite side.

Only updates the cell of the particle, if the particle is back into the domain in all three dimensions.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ teleportParticlesToOppositeSideHelper()

void LinkedCellsContainer::teleportParticlesToOppositeSideHelper ( Side  sideStart,
int  dimension,
int  modus 
)
private

Moves particles along a certain dimension from the halo cells back into the simulation domain.

Parameters
sideStartSide from which the particles will be teleported to the opposite side.
dimensionDimension along which the particles are moved (x := 0, y := 1, z := 2)
modusSpecify if the particles are moved up or down along the dimension (down := 0, up := 1)

Only updates the cell of the particle, if the particle is back into the domain in all three dimensions.

Here is the caller graph for this function:

◆ threeDToOneD()

int LinkedCellsContainer::threeDToOneD ( int  x,
int  y,
int  z 
) const

Convert 3 dimensional coordinates to one dimensional coordinates.

Parameters
xx coordinate
yy coordinate
zz coordinate
Returns
Corresponding coordinate in one dimensional space.
Here is the caller graph for this function:

◆ threeDToOneDDomain()

int LinkedCellsContainer::threeDToOneDDomain ( int  x,
int  y,
int  z 
) const

◆ updateCells()

void LinkedCellsContainer::updateCells ( )

Assign each particle to its correct cell after there positions have been changed.

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ baseY

int LinkedCellsContainer::baseY
private

Number of cells in one row (nX many).

◆ baseYDomain

int LinkedCellsContainer::baseYDomain
private

Number of cells in one layer halo cells excluded (nX - 2 many).

◆ baseZ

int LinkedCellsContainer::baseZ
private

Number of cells in one layer (nX * nY many).

◆ baseZDomain

int LinkedCellsContainer::baseZDomain
private

Number of cells in one layer halo cells excluded ((nX - 2) * (nY - 2) many).

◆ boundaries

std::array<std::vector<int>, 6> LinkedCellsContainer::boundaries
private

The indices of all boundary cells belonging to one or more of the 6 sides

◆ boundariesSet

BoundarySet LinkedCellsContainer::boundariesSet
private

◆ cells

std::vector<std::vector<Particle> > LinkedCellsContainer::cells
private

We use an 1D vector to store the flattened 3D cell structure being an essential property of the linked cells algorithm. Each cell is represented itself by an 1D vector of particles.

◆ cellSizeX

double LinkedCellsContainer::cellSizeX
private

Size of each cell in dimension x.

◆ cellSizeY

double LinkedCellsContainer::cellSizeY
private

Size of each cell in dimension y.

◆ cellSizeZ

double LinkedCellsContainer::cellSizeZ
private

Size of each cell in dimension z.

◆ currentSize

size_t LinkedCellsContainer::currentSize
private

The current number of particles that is contained in this container is tracked by the attribute currentSize and kept up-to-date through every operation.

◆ domainCellIterationScheme

std::vector<std::vector<int> > LinkedCellsContainer::domainCellIterationScheme
private

The indices of the order in which all cells within the domain are processed to process each pair of particles only ones

◆ domainSize

std::array<double, 3> LinkedCellsContainer::domainSize
private

Size of the domain {x, y , z}. The front lower left corner of the domain is set to (0,0,0) by definition.

◆ haloCells

std::array<std::vector<int>, 6> LinkedCellsContainer::haloCells
private

The indices of all halo cells belonging to one or more of the 6 sides,

◆ lJF

LennardJonesForce LinkedCellsContainer::lJF
private

◆ nX

int LinkedCellsContainer::nX
private

Number of cells in dimension x (halo cells inclusive).

◆ nY

int LinkedCellsContainer::nY
private

Number of cells in dimension y (halo cells inclusive).

◆ nZ

int LinkedCellsContainer::nZ
private

Number of cells in dimension z (halo cells inclusive).

◆ rCutOff

double LinkedCellsContainer::rCutOff
private

Cut-off radius.

◆ scheduleParallelNaive

std::vector<int> LinkedCellsContainer::scheduleParallelNaive
private

◆ scheduleParallelSophisticated

std::vector<int> LinkedCellsContainer::scheduleParallelSophisticated
private

◆ twoD

bool LinkedCellsContainer::twoD
private

Specifies, if the simulation only uses 2 of 3 dimensions. If this is the case, resources can be saved.

◆ vtk_writer

outputWriter::VTKWriter LinkedCellsContainer::vtk_writer
private

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