/* This file is part of the OpenLB library
*
* Copyright (C) 2006-2008 Jonas Latt
* E-mail contact: info@openlb.net
* The most recent release of OpenLB can be downloaded at
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/** \file
* The dynamics of a 3D block lattice -- header file.
*/
#ifndef BLOCK_LATTICE_3D_H
#define BLOCK_LATTICE_3D_H
#include
#include "olbDebug.h"
#include "core/cell.h"
#include "postProcessing.h"
#include "blockLatticeStructure3D.h"
#include "geometry/blockGeometry3D.h"
#include "latticeStatistics.h"
#include "serializer.h"
/// All OpenLB code is contained in this namespace.
namespace olb {
template class BlockGeometryStructure3D;
template class BlockIndicatorF3D;
template struct Dynamics;
/** BlockLattice3D is a regular lattice for highly efficient 3D LB dynamics.
* A block lattice contains an array of Cell objects and
* some useful methods to execute the LB dynamics on the lattice.
*
* This class is not intended to be derived from.
*/
template
class BlockLattice3D final : public BlockLatticeStructure3D, public Serializable {
public:
typedef std::vector*> PostProcVector;
private:
/// Actual data array
Cell *rawData;
/// 3D-Array pointing to rawData; grid[iX][iY] points to beginning of z-array in rawData
Cell ***grid;
PostProcVector postProcessors, latticeCouplings;
#ifdef PARALLEL_MODE_OMP
LatticeStatistics **statistics;
#else
LatticeStatistics *statistics;
#endif
BlockGeometry3D& geometry_;
public:
/// Construction of an nx_ by ny_ by nz_ lattice
BlockLattice3D(int nx_, int ny_, int nz_, BlockGeometry3D& geometry);
/// Destruction of the lattice
~BlockLattice3D() override;
/// Copy construction
BlockLattice3D(BlockLattice3D const& rhs) = delete;
/// Move constructor
BlockLattice3D(BlockLattice3D&&) = default;
/// Copy assignment
BlockLattice3D& operator=(BlockLattice3D const& rhs) = delete;
/// Read/write access to lattice cells
Cell& get(int iX, int iY, int iZ) override
{
OLB_PRECONDITION(iX_nx);
OLB_PRECONDITION(iY_ny);
OLB_PRECONDITION(iZ_nz);
return grid[iX][iY][iZ];
}
/// Read/write access to lattice cells
Cell& get(const int latticeR[]) override
{
return get(latticeR[0], latticeR[1], latticeR[2]);
}
/// Read only access to lattice cells
Cell const& get(int iX, int iY, int iZ) const override
{
OLB_PRECONDITION(iX_nx);
OLB_PRECONDITION(iY_ny);
OLB_PRECONDITION(iZ_nz);
return grid[iX][iY][iZ];
}
/// Initialize the lattice cells to become ready for simulation
void initialize() override;
/// Get the dynamics on a lattice site
Dynamics* getDynamics(int iX, int iY, int iZ) override;
/// Define the dynamics on a lattice site
void defineDynamics(int iX, int iY, int iZ, Dynamics* dynamics) override;
/// Define the dynamics on a 3D sub-box
void defineDynamics(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_,
Dynamics* dynamics ) override;
/// Define the dynamics on a domain described by an indicator
void defineDynamics(BlockIndicatorF3D& indicator,
Dynamics* dynamics) override;
/// Define the dynamics on a domain with a particular material number
void defineDynamics(BlockGeometryStructure3D& blockGeometry, int material,
Dynamics* dynamics) override;
/// Apply collision step to a 3D sub-box
void collide(int x0_, int x1_, int y0_, int y1_,
int z0_, int z1_) override;
/// Apply collision step to the whole domain
void collide() override;
/// Apply streaming step to a 3D sub-box
void stream(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_) override;
/// Apply streaming step to the whole domain
void stream(bool periodic=false) override;
/// Apply first collision, then streaming step to a 3D sub-box
void collideAndStream(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_) override;
/// Apply first collision, then streaming step to the whole domain
void collideAndStream(bool periodic=false) override;
/// Compute the average density within a rectangular domain
T computeAverageDensity(int x0_, int x1_, int y0_, int y1_,
int z0_, int z1_ ) const override;
/// Compute the average density within the whole domain
T computeAverageDensity() const override;
/// Compute components of the stress tensor on the cell.
void computeStress(int iX, int iY, int iZ, T pi[util::TensorVal::n]) override;
/// Subtract a constant offset from the density within the whole domain
void stripeOffDensityOffset (
int x0_, int x1_, int y0_, int y1_, int z0_, int z1_, T offset ) override;
/// Subtract a constant offset from the density within a rect. domain
void stripeOffDensityOffset(T offset) override;
/// Apply an operation to all cells of a sub-domain
void forAll(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_,
WriteCellFunctional const& application) override;
/// Apply an operation to all cells
void forAll(WriteCellFunctional const& application) override;
/// Add a non-local post-processing step
void addPostProcessor (
PostProcessorGenerator3D const& ppGen ) override;
/// Clean up all non-local post-processing steps
void resetPostProcessors() override;
/// Execute post-processing on a sub-lattice
void postProcess(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_) override;
/// Execute post-processing steps
void postProcess() override;
/// Add a non-local post-processing step
void addLatticeCoupling (
LatticeCouplingGenerator3D const& lcGen,
std::vector partners ) override;
/// Execute couplings on a sub-lattice
void executeCoupling(int x0_, int x1_, int y0_, int y1_, int z0_, int z1_) override;
/// Execute couplings steps
void executeCoupling() override;
/// Return a handle to the LatticeStatistics object
LatticeStatistics& getStatistics() override;
/// Return a constant handle to the LatticeStatistics object
LatticeStatistics const& getStatistics() const override;
/// Apply streaming step to bulk (non-boundary) cells
void bulkStream(int x0, int x1, int y0, int y1, int z0, int z1);
/// Apply streaming step to boundary cells
void boundaryStream (
int lim_x0, int lim_x1, int lim_y0, int lim_y1,
int lim_z0, int lim_z1,
int x0, int x1, int y0, int y1, int z0, int z1 );
/// Apply collision and streaming step to bulk (non-boundary) cells
void bulkCollideAndStream(int x0, int x1, int y0, int y1, int z0, int z1);
/// Number of data blocks for the serializable interface
std::size_t getNblock() const override;
/// Binary size for the serializer
std::size_t getSerializableSize() const override;
/// Return a pointer to the memory of the current block and its size for the serializable interface
bool* getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) override;
/// Get material number of cell
int getMaterial(int iX, int iY, int iZ);
private:
/// Helper method for memory allocation
void allocateMemory();
/// Helper method for memory de-allocation
void releaseMemory();
/// Release memory for post processors
void clearPostProcessors();
/// Release memory for post processors
void clearLatticeCouplings();
/// Make the lattice periodic in all directions
void makePeriodic();
void periodicSurface(int x0, int x1, int y0, int y1, int z0, int z1);
};
} // namespace olb
#endif