From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/core/MakeHeader | 49 ++ src/core/blockData2D.cpp | 38 ++ src/core/blockData2D.h | 128 +++++ src/core/blockData2D.hh | 300 ++++++++++++ src/core/blockData3D.cpp | 37 ++ src/core/blockData3D.h | 123 +++++ src/core/blockData3D.hh | 329 +++++++++++++ src/core/blockLattice2D.cpp | 36 ++ src/core/blockLattice2D.h | 193 ++++++++ src/core/blockLattice2D.hh | 684 ++++++++++++++++++++++++++ src/core/blockLattice3D.cpp | 36 ++ src/core/blockLattice3D.h | 214 +++++++++ src/core/blockLattice3D.hh | 781 ++++++++++++++++++++++++++++++ src/core/blockLatticeStructure2D.cpp | 36 ++ src/core/blockLatticeStructure2D.h | 143 ++++++ src/core/blockLatticeStructure2D.hh | 330 +++++++++++++ src/core/blockLatticeStructure3D.cpp | 36 ++ src/core/blockLatticeStructure3D.h | 214 +++++++++ src/core/blockLatticeStructure3D.hh | 305 ++++++++++++ src/core/blockLatticeView2D.cpp | 36 ++ src/core/blockLatticeView2D.h | 98 ++++ src/core/blockLatticeView2D.hh | 295 ++++++++++++ src/core/blockLatticeView3D.cpp | 36 ++ src/core/blockLatticeView3D.h | 97 ++++ src/core/blockLatticeView3D.hh | 346 ++++++++++++++ src/core/blockStructure2D.cpp | 35 ++ src/core/blockStructure2D.h | 61 +++ src/core/blockStructure3D.cpp | 35 ++ src/core/blockStructure3D.h | 72 +++ src/core/cell.cpp | 35 ++ src/core/cell.h | 365 ++++++++++++++ src/core/cell.hh | 159 ++++++ src/core/core2D.h | 45 ++ src/core/core2D.hh | 42 ++ src/core/core3D.h | 45 ++ src/core/core3D.hh | 42 ++ src/core/finiteDifference.h | 80 ++++ src/core/finiteDifference2D.h | 141 ++++++ src/core/finiteDifference3D.h | 148 ++++++ src/core/latticeStatistics.cpp | 31 ++ src/core/latticeStatistics.h | 93 ++++ src/core/latticeStatistics.hh | 344 +++++++++++++ src/core/module.mk | 27 ++ src/core/olbDebug.h | 52 ++ src/core/olbInit.h | 64 +++ src/core/postProcessing.h | 224 +++++++++ src/core/postProcessing.hh | 379 +++++++++++++++ src/core/postProcessing2D.cpp | 38 ++ src/core/postProcessing3D.cpp | 39 ++ src/core/powerLawUnitConverter.h | 173 +++++++ src/core/powerLawUnitConverter.hh | 218 +++++++++ src/core/radiativeUnitConverter.cpp | 92 ++++ src/core/radiativeUnitConverter.h | 209 ++++++++ src/core/serializer.cpp | 36 ++ src/core/serializer.h | 607 +++++++++++++++++++++++ src/core/serializer.hh | 139 ++++++ src/core/singleton.h | 174 +++++++ src/core/spatiallyExtendedObject2D.h | 37 ++ src/core/spatiallyExtendedObject3D.h | 37 ++ src/core/superData2D.cpp | 37 ++ src/core/superData2D.h | 106 ++++ src/core/superData2D.hh | 215 +++++++++ src/core/superData3D.cpp | 37 ++ src/core/superData3D.h | 117 +++++ src/core/superData3D.hh | 244 ++++++++++ src/core/superExternal2D.h | 67 +++ src/core/superExternal2D.hh | 82 ++++ src/core/superExternal3D.h | 81 ++++ src/core/superExternal3D.hh | 62 +++ src/core/superLattice2D.cpp | 40 ++ src/core/superLattice2D.h | 357 ++++++++++++++ src/core/superLattice2D.hh | 904 +++++++++++++++++++++++++++++++++++ src/core/superLattice3D.cpp | 38 ++ src/core/superLattice3D.h | 357 ++++++++++++++ src/core/superLattice3D.hh | 821 +++++++++++++++++++++++++++++++ src/core/thermalUnitConverter.h | 258 ++++++++++ src/core/thermalUnitConverter.hh | 206 ++++++++ src/core/unitConverter.cpp | 41 ++ src/core/unitConverter.h | 428 +++++++++++++++++ src/core/unitConverter.hh | 198 ++++++++ src/core/util.h | 471 ++++++++++++++++++ src/core/vector.h | 482 +++++++++++++++++++ 82 files changed, 14887 insertions(+) create mode 100644 src/core/MakeHeader create mode 100644 src/core/blockData2D.cpp create mode 100644 src/core/blockData2D.h create mode 100644 src/core/blockData2D.hh create mode 100644 src/core/blockData3D.cpp create mode 100644 src/core/blockData3D.h create mode 100644 src/core/blockData3D.hh create mode 100644 src/core/blockLattice2D.cpp create mode 100644 src/core/blockLattice2D.h create mode 100644 src/core/blockLattice2D.hh create mode 100644 src/core/blockLattice3D.cpp create mode 100644 src/core/blockLattice3D.h create mode 100644 src/core/blockLattice3D.hh create mode 100644 src/core/blockLatticeStructure2D.cpp create mode 100644 src/core/blockLatticeStructure2D.h create mode 100644 src/core/blockLatticeStructure2D.hh create mode 100644 src/core/blockLatticeStructure3D.cpp create mode 100644 src/core/blockLatticeStructure3D.h create mode 100644 src/core/blockLatticeStructure3D.hh create mode 100644 src/core/blockLatticeView2D.cpp create mode 100644 src/core/blockLatticeView2D.h create mode 100644 src/core/blockLatticeView2D.hh create mode 100644 src/core/blockLatticeView3D.cpp create mode 100644 src/core/blockLatticeView3D.h create mode 100644 src/core/blockLatticeView3D.hh create mode 100644 src/core/blockStructure2D.cpp create mode 100644 src/core/blockStructure2D.h create mode 100644 src/core/blockStructure3D.cpp create mode 100644 src/core/blockStructure3D.h create mode 100644 src/core/cell.cpp create mode 100644 src/core/cell.h create mode 100644 src/core/cell.hh create mode 100644 src/core/core2D.h create mode 100644 src/core/core2D.hh create mode 100644 src/core/core3D.h create mode 100644 src/core/core3D.hh create mode 100644 src/core/finiteDifference.h create mode 100644 src/core/finiteDifference2D.h create mode 100644 src/core/finiteDifference3D.h create mode 100644 src/core/latticeStatistics.cpp create mode 100644 src/core/latticeStatistics.h create mode 100644 src/core/latticeStatistics.hh create mode 100644 src/core/module.mk create mode 100644 src/core/olbDebug.h create mode 100644 src/core/olbInit.h create mode 100644 src/core/postProcessing.h create mode 100644 src/core/postProcessing.hh create mode 100644 src/core/postProcessing2D.cpp create mode 100644 src/core/postProcessing3D.cpp create mode 100644 src/core/powerLawUnitConverter.h create mode 100644 src/core/powerLawUnitConverter.hh create mode 100644 src/core/radiativeUnitConverter.cpp create mode 100644 src/core/radiativeUnitConverter.h create mode 100644 src/core/serializer.cpp create mode 100644 src/core/serializer.h create mode 100644 src/core/serializer.hh create mode 100644 src/core/singleton.h create mode 100644 src/core/spatiallyExtendedObject2D.h create mode 100644 src/core/spatiallyExtendedObject3D.h create mode 100644 src/core/superData2D.cpp create mode 100644 src/core/superData2D.h create mode 100644 src/core/superData2D.hh create mode 100644 src/core/superData3D.cpp create mode 100644 src/core/superData3D.h create mode 100644 src/core/superData3D.hh create mode 100644 src/core/superExternal2D.h create mode 100644 src/core/superExternal2D.hh create mode 100644 src/core/superExternal3D.h create mode 100644 src/core/superExternal3D.hh create mode 100644 src/core/superLattice2D.cpp create mode 100644 src/core/superLattice2D.h create mode 100644 src/core/superLattice2D.hh create mode 100644 src/core/superLattice3D.cpp create mode 100644 src/core/superLattice3D.h create mode 100644 src/core/superLattice3D.hh create mode 100644 src/core/thermalUnitConverter.h create mode 100644 src/core/thermalUnitConverter.hh create mode 100644 src/core/unitConverter.cpp create mode 100644 src/core/unitConverter.h create mode 100644 src/core/unitConverter.hh create mode 100644 src/core/util.h create mode 100644 src/core/vector.h (limited to 'src/core') diff --git a/src/core/MakeHeader b/src/core/MakeHeader new file mode 100644 index 0000000..622c77f --- /dev/null +++ b/src/core/MakeHeader @@ -0,0 +1,49 @@ +# This file is part of the OpenLB library +# +# Copyright (C) 2007 Mathias Krause +# 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. + + +generic := blockStructure2D \ + blockStructure3D \ + radiativeUnitConverter + + +precompiled := blockStructure2D \ + blockStructure3D \ + blockData2D \ + blockData3D \ + blockLattice2D \ + blockLattice3D \ + blockLatticeStructure2D \ + blockLatticeStructure3D \ + blockLatticeView2D \ + blockLatticeView3D \ + cell \ + latticeStatistics \ + postProcessing2D \ + postProcessing3D \ + radiativeUnitConverter \ + serializer \ + superData2D \ + superData3D \ + superLattice2D \ + superLattice3D \ + unitConverter diff --git a/src/core/blockData2D.cpp b/src/core/blockData2D.cpp new file mode 100644 index 0000000..7d9845b --- /dev/null +++ b/src/core/blockData2D.cpp @@ -0,0 +1,38 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 2D block data -- template instantiation. + */ + +#include "blockData2D.h" +#include "blockData2D.hh" + + +namespace olb { + +template class BlockData2D; +template class BlockData2D; +template class BlockData2D; + +} // namespace olb diff --git a/src/core/blockData2D.h b/src/core/blockData2D.h new file mode 100644 index 0000000..1f43b95 --- /dev/null +++ b/src/core/blockData2D.h @@ -0,0 +1,128 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 2D block data -- header file. + */ +#ifndef BLOCK_DATA_2D_H +#define BLOCK_DATA_2D_H + + +#include +#include "blockStructure2D.h" +#include "serializer.h" + + +namespace olb { + +// forward declaration is sufficient at this state, include is moved to .hh +template class BlockF2D; +template class Cuboid2D; + + +/** A highly generic data structure class. + * + * Stored data is of type BaseType + * + * \param _size data element size + * \param _rawData classic array representation of all elements + * \param _filed a matrix like representation of _rawData + */ +template +class BlockData2D : public BlockStructure2D, public Serializable { +protected: + /// dimension of data element, vector, scalar, ... + int _size; + /// holds data as a 1D vector + BaseType *_rawData; + /** Pointer structure to a 3D data field. + * It can be interpreted as a 2D matrix[iX,iY] with elements of dimension _size. + * Those elements may be + * 1. vector valued like velocity, (f0,f1,...,f8) + * 2. scalar valued like density, pressure, ... + * + */ + BaseType ***_field; +public: + virtual ~BlockData2D(); + /// Construct empty cuboid + BlockData2D(); + /// Construct from cuboid + BlockData2D(Cuboid2D& cuboid, int size=1); + /// Construct from X-Y node count + BlockData2D(int nx, int ny, int size=1); + /// Construct from Block Functor, attention!! operator() accesses functor data + BlockData2D(BlockF2D& rhs); + /// Copy Constructor + BlockData2D(BlockData2D const& rhs); + /// Assignment Operator + BlockData2D& operator=(BlockData2D const& rhs); + /// Move Operator + BlockData2D& operator=(BlockData2D&& rhs); + /// Move Constructor + BlockData2D(BlockData2D&& rhs); + /// Swap rhs Data into local fields + void swap(BlockData2D& rhs); + /// Memory Management + bool isConstructed() const; + void construct(); + void deConstruct(); + void reset(); + /// read and write access to data element [iX][iY][iSize] + BaseType& get(int iX, int iY, int iSize=0); + /// read only access to data element [iX][iY][iSize] + BaseType const& get(int iX, int iY, int iSize=0) const; + /// \return dataElement _rawData[ind], read and write + BaseType& operator[] (int ind); + /// \return dataElement _rawData[ind], read only + BaseType const& operator[] (int ind) const; + /// Write access to the memory of the data of the block data where (iX, iY) is the point providing the data iData + bool* operator() (int iX, int iY, int iData); + /// \return max of data, for vector valued data it determines the max component + BaseType getMax(); + /// \return min of data, for vector valued data it determines the max component + BaseType getMin(); + /// \return _rawData array + BaseType* getRawData() const; + /// \return length of array _rawData or equivalent nX*nY*size + virtual size_t getDataSize() const; + /// Read only access to the dim of the data of the super structure + int getSize() const; + /// Number of data blocks for the serializable interface + std::size_t getNblock() const override + { + return 4; + }; + /// Binary size for the serializer + std::size_t getSerializableSize() const override; + /// Returns 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; +private: + void allocateMemory(); // TODO + void releaseMemory(); +}; + + +} // namespace olb + +#endif diff --git a/src/core/blockData2D.hh b/src/core/blockData2D.hh new file mode 100644 index 0000000..2646e6b --- /dev/null +++ b/src/core/blockData2D.hh @@ -0,0 +1,300 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 2D block data -- header file. + */ +#ifndef BLOCK_DATA_2D_HH +#define BLOCK_DATA_2D_HH + +#include +#include "olbDebug.h" +#include "blockData2D.h" +#include "geometry/cuboid2D.h" +#include "functors/lattice/blockBaseF2D.h" + + +namespace olb { + + +template +BlockData2D::BlockData2D() : BlockStructure2D(0,0), _size(0), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData2D::BlockData2D(Cuboid2D& cuboid, int size) + : BlockStructure2D(cuboid.getNx(), cuboid.getNy()), _size(size), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData2D::BlockData2D(int nx, int ny, int size) + : BlockStructure2D(nx, ny), _size(size), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData2D::~BlockData2D() +{ + deConstruct(); +} + +template +BlockData2D::BlockData2D(BlockF2D& rhs) + : BlockStructure2D(rhs.getBlockStructure().getNx(), rhs.getBlockStructure().getNy()), + _size(rhs.getTargetDim()) +{ + construct(); + int i[2]; + for (i[0] = 0; i[0] < this->_nx; ++i[0]) { + for (i[1] = 0; i[1] < this->_ny; ++i[1]) { + rhs(_field[i[0]][i[1]], i); + } + } +} + +template +BlockData2D::BlockData2D(BlockData2D const& rhs) + : BlockStructure2D(rhs._nx, rhs._ny), _size(rhs._size), _rawData(nullptr), _field(nullptr) +{ + if (rhs.isConstructed()) { + construct(); + std::copy( rhs._rawData, rhs._rawData + getDataSize(), _rawData ); + } +} + +template +BlockData2D& BlockData2D::operator=(BlockData2D const& rhs) +{ + BlockData2D tmp(rhs); + swap(tmp); + return *this; +} + +// benefits of move operator: does not allocate memory or copys objects +template +BlockData2D& BlockData2D::operator=(BlockData2D&& rhs) +{ + if (this == &rhs) { + return *this; + } +// this->releaseMemory(); // free data of object this + + _size = rhs._size; // swap object data + _rawData = rhs._rawData; + _field = rhs._field; + this->_nx = rhs._nx; + this->_ny = rhs._ny; + + rhs._rawData = nullptr; // free data of object rhs + rhs._field = nullptr; + rhs._nx = 0; + rhs._ny = 0; + + return *this; +} + +// benefits of move operator: does not allocate memory +template +BlockData2D::BlockData2D(BlockData2D&& rhs) + : BlockStructure2D(rhs._nx, rhs._ny), _size(0), _rawData(nullptr), _field(nullptr) +{ + *this = std::move(rhs); // https://msdn.microsoft.com/de-de/library/dd293665.aspx +} + + +template +bool BlockData2D::isConstructed() const +{ + return _rawData; +} + +template +void BlockData2D::construct() +{ + if (!isConstructed()) { + allocateMemory(); + } +} + +template +void BlockData2D::deConstruct() +{ + if (isConstructed()) { + releaseMemory(); + } +} + +template +void BlockData2D::reset() +{ + OLB_PRECONDITION(isConstructed()); + for (size_t index = 0; index < getDataSize(); ++index) { + (*this)[index] = BaseType(); + } +} + +template +void BlockData2D::swap(BlockData2D& rhs) +{ + // Block2D + std::swap(this->_nx, rhs._nx); + std::swap(this->_ny, rhs._ny); + // BlockData2D + std::swap(_size, rhs._size); + std::swap(_rawData, rhs._rawData); + std::swap(_field, rhs._field); +} + +template +void BlockData2D::allocateMemory() +{ + // The conversions to size_t ensure 64-bit compatibility. Note that + // nx and ny are of type int, which might by 32-bit types, even on + // 64-bit platforms. Therefore, nx*ny may lead to a type overflow. + _rawData = new BaseType[ getDataSize() ]; + _field = new BaseType** [(size_t)(this->_nx)]; + for (int iX = 0; iX < this->_nx; ++iX) { + _field[iX] = new BaseType* [(size_t)this->_ny]; + for (int iY = 0; iY < this->_ny; ++iY) { + // connect matrix element to the corresponding array entry of _rawData + _field[iX][iY] = _rawData + _size*( (size_t)iY + (size_t)(this->_ny)*(size_t)iX ); + for (int iDim = 0; iDim < _size; ++iDim) { + // initialize data with zero + _field[iX][iY][iDim] = BaseType(); + } + } + } +} + +template +void BlockData2D::releaseMemory() +{ + delete [] _rawData; + _rawData = nullptr; + for (unsigned int iX = 0; iX < (size_t)(this->_nx); ++iX) { + delete [] _field[iX]; + } + delete [] _field; +} + +template +BaseType& BlockData2D::get(int iX, int iY, int iSize) +{ + OLB_PRECONDITION(iX >= 0 && iX < this->_nx); + OLB_PRECONDITION(iY >= 0 && iY < this->_ny); + OLB_PRECONDITION(iSize >= 0 && iSize < _size); + OLB_PRECONDITION(isConstructed()); + return _field[iX][iY][iSize]; +} + +template +BaseType const& BlockData2D::get(int iX, int iY, int iSize) const +{ + OLB_PRECONDITION(iX >= 0 && iX < this->_nx); + OLB_PRECONDITION(iY >= 0 && iY < this->_ny); + OLB_PRECONDITION(iSize >= 0 && iSize < _size); + OLB_PRECONDITION(isConstructed()); + return _field[iX][iY][iSize]; +} + +template +BaseType& BlockData2D::operator[] (int ind) +{ + OLB_PRECONDITION(ind >= 0 && ind < this->_nx * this->_ny * this->_size); + OLB_PRECONDITION(isConstructed()); + return _rawData[ind]; +} + +template +BaseType const& BlockData2D::operator[] (int ind) const +{ + OLB_PRECONDITION(ind >= 0 && ind < this->_nx * this->_ny * this->_size); + OLB_PRECONDITION(isConstructed()); + return _rawData[ind]; +} + +template +bool* BlockData2D::operator() (int iX, int iY, int iData) +{ + return (bool*)&_field[iX][iY][iData]; +} + +template +BaseType BlockData2D::getMax() +{ + return ***std::max_element( _field, _field + getDataSize() ) ; +} + +template +BaseType BlockData2D::getMin() +{ + return ***std::min_element( _field, _field + getDataSize() ) ; +} + +template +BaseType* BlockData2D::getRawData() const +{ + return _rawData; +} + +template +size_t BlockData2D::getDataSize() const +{ + return (size_t)(this->_nx) * (size_t)(this->_ny) * (size_t)(_size); +} + +template +int BlockData2D::getSize() const +{ + return _size; +} + +template +size_t BlockData2D::getSerializableSize() const +{ + return 3 * sizeof(int) // _size, _nX/Y + + getDataSize() * sizeof(BaseType); // _rawData +}; + +template +bool* BlockData2D::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) +{ + std::size_t currentBlock = 0; + bool* dataPtr = nullptr; + + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, _size); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, this->_nx); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, this->_ny); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, *_rawData, getDataSize()); + + return dataPtr; +} + +} // namespace olb + +#endif diff --git a/src/core/blockData3D.cpp b/src/core/blockData3D.cpp new file mode 100644 index 0000000..0faf071 --- /dev/null +++ b/src/core/blockData3D.cpp @@ -0,0 +1,37 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 3D block data -- template instantiation. + */ + +#include "blockData3D.h" +#include "blockData3D.hh" + +namespace olb { + +template class BlockData3D; +template class BlockData3D; +template class BlockData3D; + +} // namespace olb diff --git a/src/core/blockData3D.h b/src/core/blockData3D.h new file mode 100644 index 0000000..d1c7c9b --- /dev/null +++ b/src/core/blockData3D.h @@ -0,0 +1,123 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 3D block data -- header file. + */ +#ifndef BLOCK_DATA_3D_H +#define BLOCK_DATA_3D_H + + +#include +#include "blockStructure3D.h" +#include "serializer.h" + + +namespace olb { + +// forward declaration is sufficient at this state, include is moved to .hh +template class BlockF3D; +template class Cuboid3D; + + +/** A highly generic data structure class. + * + * Stored data is of type BaseType + * + * \param _size data element size + * \param _rawData classic array representation of all elements + * \param _filed a matrix like representation of _rawData + */ +template +class BlockData3D : public BlockStructure3D, public Serializable { +protected: + /// dimension of data element, vector, scalar, ... + int _size; + /// holds data as a 1D vector + BaseType *_rawData; + /// Pointer structure to [3D data]x[1D element] + BaseType ****_field; +public: + virtual ~BlockData3D(); + /// Construct empty cuboid + BlockData3D(); + /// Construct from cuboid + BlockData3D(Cuboid3D& cuboid, int size=1); + /// Construct from X-Y-Z node count + BlockData3D(int nx, int ny, int nz, int size=1); + /// Construct from Block Functor + BlockData3D(BlockF3D& rhs); + /// Copy Constructor + BlockData3D(BlockData3D const& rhs); + /// Assignment Operator + BlockData3D& operator=(BlockData3D const& rhs); + /// Move Operator + BlockData3D& operator=(BlockData3D&& rhs); + /// Move Constructor + BlockData3D(BlockData3D&& rhs); + /// Swap rhs Data into local fields + void swap(BlockData3D& rhs); + /// Memory Management + bool isConstructed() const; + void construct(); + void deConstruct(); + void reset(); + /// \return dataElement _rawData[ind], read and write + BaseType& operator[] (int ind); + /// \return dataElement _rawData[ind], read only + BaseType const& operator[] (int ind) const; + /// Write access to the memory of the data of the block data where (iX, iY, iZ) is the point providing the data iData + bool* operator() (int iX, int iY, int iZ, int iData); + bool operator() (T output[], const int input[]); + /// read and write access to data element [iX][iY][iZ][iSize] + BaseType& get(int iX, int iY, int iZ, int iSize=0); + /// read only access to data element [iX][iY][iZ][iSize] + BaseType const& get(int iX, int iY, int iZ, int iSize=0) const; + /// \return max of data, for vector valued data it determines the max component + BaseType getMax(); + /// \return min of data, for vector valued data it determines the max component + BaseType getMin(); + /// \return _rawData array + BaseType* getRawData() const; + /// Number of all variables in the data field + virtual size_t getDataSize() const; + /// \return _size, the dimension of an data element + int getSize() const; + /// Number of data blocks for the serializable interface + std::size_t getNblock() const override + { + return 5; + }; + /// Binary size for the serializer + std::size_t getSerializableSize() const override; + /// Returns 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; +private: + /// Memory Management + void allocateMemory(); + void releaseMemory(); +}; + +} // namespace olb + +#endif diff --git a/src/core/blockData3D.hh b/src/core/blockData3D.hh new file mode 100644 index 0000000..d982eb7 --- /dev/null +++ b/src/core/blockData3D.hh @@ -0,0 +1,329 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2015 Mathias J. Krause + * 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 + * Dynamics for a generic 3D block data -- header file. + */ +#ifndef BLOCK_DATA_3D_HH +#define BLOCK_DATA_3D_HH + +#include +#include "olbDebug.h" +#include "blockData3D.h" +#include "geometry/cuboid3D.h" +#include "functors/lattice/blockBaseF3D.h" + +namespace olb { + + +template +BlockData3D::BlockData3D() + : BlockStructure3D(0,0,0), _size(0), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData3D::BlockData3D(Cuboid3D& cuboid, int size) + : BlockStructure3D(cuboid.getNx(), cuboid.getNy(), cuboid.getNz()), + _size(size), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData3D::BlockData3D(int nx, int ny, int nz, int size) + : BlockStructure3D(nx, ny, nz), _size(size), _rawData(nullptr), _field(nullptr) +{ + construct(); +} + +template +BlockData3D::~BlockData3D() +{ + deConstruct(); +} + +template +BlockData3D::BlockData3D(BlockF3D& rhs) + : BlockStructure3D(rhs.getBlockStructure().getNx(), + rhs.getBlockStructure().getNy(), + rhs.getBlockStructure().getNz()), + _size(rhs.getTargetDim()), _rawData(nullptr), _field(nullptr) +{ + construct(); + int i[3]; + for (i[0] = 0; i[0] < this->_nx; ++i[0]) { + for (i[1] = 0; i[1] < this->_ny; ++i[1]) { + for (i[2] = 0; i[2] < this->_nz; ++i[2]) { + rhs(_field[i[0]][i[1]][i[2]], i); + } + } + } +} + +template +BlockData3D::BlockData3D(BlockData3D const& rhs) + : BlockStructure3D(rhs._nx, rhs._ny, rhs._nz), _size(rhs._size), _rawData(nullptr), _field(nullptr) +{ + if (rhs.isConstructed()) { + construct(); +// for (size_t iData = 0; iData < getDataSize(); ++iData) { +// (*this)[iData] = rhs[iData]; +// } + std::copy( rhs._rawData, rhs._rawData + getDataSize(), _rawData ); + } +} + +template +BlockData3D& BlockData3D::operator=(BlockData3D const& rhs) +{ + BlockData3D tmp(rhs); + swap(tmp); + return *this; +} + +template +BlockData3D& BlockData3D::operator=(BlockData3D&& rhs) +{ + std::cout << "/// Move Operator BlockData3D" << std::endl; + if (this != &rhs) { + } +// this->releaseMemory(); // free data of object this + + _size = rhs._size; // swap object data + _rawData = rhs._rawData; + _field = rhs._field; + this->_nx = rhs._nx; + this->_ny = rhs._ny; + this->_nz = rhs._nz; + + rhs._rawData = nullptr; // free data of object rhs + rhs._field = nullptr; + rhs._nx = 0; + rhs._ny = 0; + rhs._nz = 0; + return *this; +} + +template +BlockData3D::BlockData3D(BlockData3D&& rhs) + : BlockStructure3D(rhs._nx, rhs._ny, rhs._nz), _size(rhs._size), _rawData(nullptr), _field(nullptr) +{ + std::cout << "/// Move Ctor BlockData3D" << std::endl; + *this = std::move(rhs); // https://msdn.microsoft.com/de-de/library/dd293665.aspx +} + + +template +bool BlockData3D::isConstructed() const +{ + return _rawData; +} + +template +void BlockData3D::construct() +{ + if (!isConstructed()) { + allocateMemory(); + } +} + +template +void BlockData3D::deConstruct() +{ + if (isConstructed()) { + releaseMemory(); + } +} + +template +void BlockData3D::reset() +{ + OLB_PRECONDITION(isConstructed()); + for (size_t index = 0; index < getDataSize(); ++index) { + (*this)[index] = BaseType(); + } +} + +template +void BlockData3D::swap(BlockData3D& rhs) +{ + // Block3D + std::swap(this->_nx, rhs._nx); + std::swap(this->_ny, rhs._ny); + std::swap(this->_nz, rhs._nz); + // BlockData3D + std::swap(_size, rhs._size); + std::swap(_rawData, rhs._rawData); + std::swap(_field, rhs._field); +} + +template +void BlockData3D::allocateMemory() +{ + // The conversions to size_t ensure 64-bit compatibility. Note that + // nx and ny are of type int, which might be 32-bit types, even on + // 64-bit platforms. Therefore, nx*ny may lead to a type overflow. + _rawData = new BaseType[ getDataSize() ]; + _field = new BaseType*** [(size_t)(this->_nx)]; + for (int iX = 0; iX < this->_nx; ++iX) { + _field[iX] = new BaseType** [(size_t)this->_ny]; + for (int iY = 0; iY < this->_ny; ++iY) { + _field[iX][iY] = new BaseType* [(size_t)this->_nz]; + for (int iZ = 0; iZ < this->_nz; ++iZ) { + _field[iX][iY][iZ] = _rawData + _size*( (size_t)iZ + (size_t)(this->_nz)*((size_t)iY + (size_t)(this->_ny)*(size_t)iX) ); + for (int iDim = 0; iDim < _size; ++iDim) { + _field[iX][iY][iZ][iDim] = BaseType(); + } + } + } + } +} + +template +void BlockData3D::releaseMemory() +{ + delete [] _rawData; + _rawData = nullptr; + for (int iX = 0; iX < this->_nx; ++iX) { + for (int iY = 0; iY < this->_ny; ++iY) { + delete [] _field[iX][iY]; + } + delete [] _field[iX]; + } + delete [] _field; +} + +template +BaseType& BlockData3D::operator[] (int ind) +{ + OLB_PRECONDITION(ind >= 0 && ind < this->_nx * this->_ny * this->_nz * this->_size); + OLB_PRECONDITION(isConstructed()); + return _rawData[ind]; +} + +template +BaseType const& BlockData3D::operator[] (int ind) const +{ + OLB_PRECONDITION(ind >= 0 && ind < this->_nx * this->_ny * this->_nz * this->_size); + OLB_PRECONDITION(isConstructed()); + return _rawData[ind]; +} + +template +bool* BlockData3D::operator() (int iX, int iY, int iZ, int iData) +{ + return (bool*)&_field[iX][iY][iZ][iData]; +} + +template +bool BlockData3D::operator() (T output[], const int input[]) +{ + if ( input[0] >= 0 && input[1] >= 0 && input[2] >= 0 && input[0] < this->_nx && input[1] < this->_ny && input[2] < this->_nz ) { + for (int i=0; i < _size; i++) + output[i] = _field[input[0]][input[1]][input[2]][i]; + return true; + } else { + return false; + } +} + +template +BaseType& BlockData3D::get(int iX, int iY, int iZ, int iSize) +{ + OLB_PRECONDITION(iX >= 0 && iX < this->_nx); + OLB_PRECONDITION(iY >= 0 && iY < this->_ny); + OLB_PRECONDITION(iZ >= 0 && iZ < this->_nz); + OLB_PRECONDITION(iSize >= 0 && iSize < _size); + OLB_PRECONDITION(isConstructed()); + return _field[iX][iY][iZ][iSize]; +} + +template +BaseType const& BlockData3D::get(int iX, int iY, int iZ, int iSize) const +{ + OLB_PRECONDITION(iX >= 0 && iX < this->_nx); + OLB_PRECONDITION(iY >= 0 && iY < this->_ny); + OLB_PRECONDITION(iZ >= 0 && iZ < this->_nz); + OLB_PRECONDITION(iSize >= 0 && iSize < _size); + OLB_PRECONDITION(isConstructed()); + return _field[iX][iY][iZ][iSize]; +} + +template +BaseType BlockData3D::getMax() +{ + return ****std::max_element( _field, _field + getDataSize() ) ; +} + +template +BaseType BlockData3D::getMin() +{ + return ****std::min_element( _field, _field + getDataSize() ) ; +} + +template +BaseType* BlockData3D::getRawData() const +{ + return _rawData; +} + +template +size_t BlockData3D::getDataSize() const +{ + return (size_t)(this->_nx) * (size_t)(this->_ny) * (size_t)(this->_nz) * (size_t)(_size); +} + +template +int BlockData3D::getSize() const +{ + return _size; +} + + +template +size_t BlockData3D::getSerializableSize() const +{ + return 4 * sizeof(int) // _size, _nX/Y/Z + + getDataSize() * sizeof(BaseType); // _rawData +}; + +template +bool* BlockData3D::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) +{ + std::size_t currentBlock = 0; + bool* dataPtr = nullptr; + + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, _size); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, this->_nx); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, this->_ny); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, this->_nz); + registerVar(iBlock, sizeBlock, currentBlock, dataPtr, *_rawData, getDataSize()); + + return dataPtr; +} + +} // namespace olb + +#endif diff --git a/src/core/blockLattice2D.cpp b/src/core/blockLattice2D.cpp new file mode 100644 index 0000000..c09d65f --- /dev/null +++ b/src/core/blockLattice2D.cpp @@ -0,0 +1,36 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2006, 2007 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 2D block lattice -- template instantiation. + */ +#include "blockLattice2D.h" +#include "blockLattice2D.hh" +#include "dynamics/latticeDescriptors.h" + + +namespace olb { + +template class BlockLattice2D>; + +} // namespace olb diff --git a/src/core/blockLattice2D.h b/src/core/blockLattice2D.h new file mode 100644 index 0000000..5aa6e07 --- /dev/null +++ b/src/core/blockLattice2D.h @@ -0,0 +1,193 @@ +/* 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 2D block lattice -- header file. + */ +#ifndef BLOCK_LATTICE_2D_H +#define BLOCK_LATTICE_2D_H + +#include +#include "olbDebug.h" +#include "postProcessing.h" +#include "blockLatticeStructure2D.h" +#include "core/cell.h" +#include "latticeStatistics.h" +#include "serializer.h" + +/// All OpenLB code is contained in this namespace. +namespace olb { + +template class BlockGeometryStructure2D; +template struct Dynamics; +template class BlockIndicatorF2D; + +/** A regular lattice for highly efficient 2D LB dynamics. + * A block lattice contains a regular 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 BlockLattice2D final : public BlockLatticeStructure2D, public Serializable { +public: + typedef std::vector*> PostProcVector; +private: + /// Actual data array + Cell *rawData; + /// 3D-Array pointing to rawData; grid[iX] points to beginning of y-array in rawData + Cell **grid; + PostProcVector postProcessors, latticeCouplings; +#ifdef PARALLEL_MODE_OMP + LatticeStatistics **statistics; +#else + LatticeStatistics *statistics; +#endif + +public: + /// Construction of an nx_ by ny_ lattice + BlockLattice2D(int nx, int ny); + /// Destruction of the lattice + ~BlockLattice2D() override; + /// Copy construction + BlockLattice2D(BlockLattice2D const& rhs) = delete; + // Move constructor + BlockLattice2D(BlockLattice2D&&) = default; + /// Copy assignment + BlockLattice2D& operator=(BlockLattice2D const& rhs) = delete; +public: + /// Read/write access to lattice cells + Cell& get(int iX, int iY) override + { + OLB_PRECONDITION(iX_nx); + OLB_PRECONDITION(iY_ny); + return grid[iX][iY]; + } + /// Read/write access to lattice cells + Cell& get(int latticeR[]) override + { + return get(latticeR[0], latticeR[1]); + } + /// Read only access to lattice cells + Cell const& get(int iX, int iY) const override + { + OLB_PRECONDITION(iX_nx); + OLB_PRECONDITION(iY_ny); + return grid[iX][iY]; + } + /// Initialize the lattice cells to become ready for simulation + void initialize() override; + /// Get the dynamics for the specific point + Dynamics* getDynamics(int iX, int iY) override; + /// Define the dynamics on a rectangular domain + void defineDynamics (int x0, int x1, int y0, int y1, + Dynamics* dynamics ) override; + /// Define the dynamics on a lattice site + void defineDynamics(int iX, int iY, Dynamics* dynamics) override; + /// Define the dynamics on a domain described by an indicator + void defineDynamics(BlockIndicatorF2D& indicator, + Dynamics* dynamics); + /// Define the dynamics on a domain described by a material number + void defineDynamics(BlockGeometryStructure2D& blockGeometry, int material, + Dynamics* dynamics); + + /// Apply collision step to a rectangular domain + void collide(int x0, int x1, int y0, int y1) override; + /// Apply collision step to the whole domain + void collide() override; + /// Apply streaming step to a rectangular domain + void stream(int x0, int x1, int y0, int y1) override; + /// Apply streaming step to the whole domain + void stream(bool periodic=false) override; + /// Apply first collision, then streaming step to a rectangular domain + void collideAndStream(int x0, int x1, int y0, int y1) 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) 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, 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, 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_, + 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 ( PostProcessorGenerator2D 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_) override; + /// Execute post-processing steps + void postProcess() override; + /// Add a non-local post-processing step which couples together lattices + void addLatticeCoupling( LatticeCouplingGenerator2D const& lcGen, + std::vector partners ) override; + /// Execute couplings on a sub-lattice + void executeCoupling(int x0_, int x1_, int y0_, int y1_) override; + /// Execute couplings + 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; +public: + /// Apply streaming step to bulk (non-boundary) cells + void bulkStream(int x0, int x1, int y0, int y1); + /// Apply streaming step to boundary cells + void boundaryStream ( int lim_x0, int lim_x1, int lim_y0, int lim_y1, int x0, + int x1, int y0, int y1 ); + /// Apply collision and streaming step to bulk (non-boundary) cells + void bulkCollideAndStream(int x0, int x1, int y0, int y1); + + + /// 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; + +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 lattice couplings + void clearLatticeCouplings(); + void periodicEdge(int x0, int x1, int y0, int y1); + void makePeriodic(); +}; + +} // namespace olb + +#endif diff --git a/src/core/blockLattice2D.hh b/src/core/blockLattice2D.hh new file mode 100644 index 0000000..84661fa --- /dev/null +++ b/src/core/blockLattice2D.hh @@ -0,0 +1,684 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2006-2008 Jonas Latt + * OMP parallel code by Mathias Krause, Copyright (C) 2007 + * 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 2D block lattice -- generic implementation. + */ +#ifndef BLOCK_LATTICE_2D_HH +#define BLOCK_LATTICE_2D_HH + +#include +#include "blockLattice2D.h" +#include "dynamics/dynamics.h" +#include "dynamics/lbHelpers.h" +#include "util.h" +#include "communication/loadBalancer.h" +#include "communication/blockLoadBalancer.h" +#include "functors/lattice/indicator/blockIndicatorF2D.h" +#include "communication/ompManager.h" + +namespace olb { + +////////////////////// Class BlockLattice2D ///////////////////////// + +/** \param nx lattice width (first index) + * \param ny lattice height (second index) + */ +template +BlockLattice2D::BlockLattice2D(int nx, int ny) + : BlockLatticeStructure2D(nx,ny) +{ + allocateMemory(); + resetPostProcessors(); +#ifdef PARALLEL_MODE_OMP + statistics = new LatticeStatistics* [3*omp.get_size()]; + #pragma omp parallel + { + statistics[omp.get_rank() + omp.get_size()] + = new LatticeStatistics; + statistics[omp.get_rank()] = new LatticeStatistics; + statistics[omp.get_rank() + 2*omp.get_size()] + = new LatticeStatistics; + } +#else + statistics = new LatticeStatistics; +#endif +} + +/** During destruction, the memory for the lattice and the contained + * cells is released. However, the dynamics objects pointed to by + * the cells must be deleted manually by the user. + */ +template +BlockLattice2D::~BlockLattice2D() +{ + releaseMemory(); + clearPostProcessors(); + clearLatticeCouplings(); +#ifdef PARALLEL_MODE_OMP + #pragma omp parallel + { + delete statistics[omp.get_rank()]; + } + delete statistics; +#else + delete statistics; +#endif +} + +template +void BlockLattice2D::initialize() +{ + postProcess(); +} + +template +Dynamics* BlockLattice2D::getDynamics (int iX, int iY) +{ + return grid[iX][iY].getDynamics(); +} + +/** The dynamics object is not duplicated: all cells of the rectangular + * domain point to the same dynamics. + * + * The dynamics object is not owned by the BlockLattice2D object, its + * memory management is in charge of the user. + */ +template +void BlockLattice2D::defineDynamics ( + int x0, int x1, int y0, int y1, Dynamics* dynamics ) +{ + OLB_PRECONDITION(x0>=0 && x1_nx); + OLB_PRECONDITION(x1>=x0); + OLB_PRECONDITION(y0>=0 && y1_ny); + OLB_PRECONDITION(y1>=y0); + + for (int iX=x0; iX<=x1; ++iX) { + for (int iY=y0; iY<=y1; ++iY) { + grid[iX][iY].defineDynamics(dynamics); + } + } +} + +template +void BlockLattice2D::defineDynamics ( + int iX, int iY, Dynamics* dynamics ) +{ + OLB_PRECONDITION(iX>=0 && iX_nx); + OLB_PRECONDITION(iY>=0 && iY_ny); + + grid[iX][iY].defineDynamics(dynamics); +} + +template +void BlockLattice2D::defineDynamics ( + BlockIndicatorF2D& indicator, Dynamics* dynamics) +{ + int latticeR[2]; + for (latticeR[0] = 0; latticeR[0] < this->_nx; ++latticeR[0]) { + for (latticeR[1] = 0; latticeR[1] < this->_ny; ++latticeR[1]) { + if (indicator(latticeR)) { + get(latticeR).defineDynamics(dynamics); + } + } + } +} + +template +void BlockLattice2D::defineDynamics( + BlockGeometryStructure2D& blockGeometry, int material, Dynamics* dynamics) +{ + BlockIndicatorMaterial2D indicator(blockGeometry, std::vector(1, material)); + defineDynamics(indicator, dynamics); +} + +template +void BlockLattice2D::collide(int x0, int x1, int y0, int y1) +{ + OLB_PRECONDITION(x0>=0 && x1_nx); + OLB_PRECONDITION(x1>=x0); + OLB_PRECONDITION(y0>=0 && y1_ny); + OLB_PRECONDITION(y1>=y0); + + int iX; +#ifdef PARALLEL_MODE_OMP + #pragma omp parallel for schedule(dynamic,1) +#endif + for (iX=x0; iX<=x1; ++iX) { + for (int iY=y0; iY<=y1; ++iY) { + grid[iX][iY].collide(getStatistics()); + grid[iX][iY].revert(); + } + } +} + +/** \sa collide(int,int,int,int) */ +template +void BlockLattice2D::collide() +{ + collide(0, this->_nx-1, 0, this->_ny-1); +} + +/** The distribution functions never leave the rectangular domain. On the + * domain boundaries, the (outgoing) distribution functions that should + * be streamed outside are simply left untouched. + * The post-processing steps are not automatically invoked by this method, + * as they are in the method stream(). If you want them to be executed, you + * must explicitly call the method postProcess(). + * \sa stream() + */ +template +void BlockLattice2D::stream(int x0, int x1, int y0, int y1) +{ + OLB_PRECONDITION(x0>=0 && x1_nx); + OLB_PRECONDITION(x1>=x0); + OLB_PRECONDITION(y0>=0 && y1_ny); + OLB_PRECONDITION(y1>=y0); + + static const int vicinity = descriptors::vicinity(); + + bulkStream(x0+vicinity,x1-vicinity,y0+vicinity,y1-vicinity); + + boundaryStream(x0,x1,y0,y1, x0,x0+vicinity-1, y0,y1); + boundaryStream(x0,x1,y0,y1, x1-vicinity+1,x1, y0,y1); + boundaryStream(x0,x1,y0,y1, x0+vicinity,x1-vicinity, y0,y0+vicinity-1); + boundaryStream(x0,x1,y0,y1, x0+vicinity,x1-vicinity, y1-vicinity+1,y1); +} + +/** At the end of this method, the post-processing steps are automatically + * invoked. + * \sa stream(int,int,int,int) + */ +template +void BlockLattice2D::stream(bool periodic) +{ + stream(0, this->_nx-1, 0, this->_ny-1); + + if (periodic) { + makePeriodic(); + } + + postProcess(); + getStatistics().incrementTime(); +} + +/** This operation is more efficient than a successive application of + * collide(int,int,int,int) and stream(int,int,int,int), because memory + * is traversed only once instead of twice. + * The post-processing steps are not automatically invoked by this method, + * as they are in the method stream(). If you want them to be executed, you + * must explicitly call the method postProcess(). + * \sa collideAndStream() + */ +template +void BlockLattice2D::collideAndStream(int x0, int x1, int y0, int y1) +{ + OLB_PRECONDITION(x0>=0 && x1_nx); + OLB_PRECONDITION(x1>=x0); + OLB_PRECONDITION(y0>=0 && y1_ny); + OLB_PRECONDITION(y1>=y0); + + static const int vicinity = descriptors::vicinity(); + + // First, do the collision on cells within a boundary envelope of width + // equal to the range of the lattice vectors (e.g. 1 for D2Q9) + collide(x0,x0+vicinity-1, y0,y1); + collide(x1-vicinity+1,x1, y0,y1); + collide(x0+vicinity,x1-vicinity, y0,y0+vicinity-1); + collide(x0+vicinity,x1-vicinity, y1-vicinity+1,y1); + + // Then, do the efficient collideAndStream algorithm in the bulk, + // excluding the envelope (this is efficient because there is no + // if-then-else statement within the loop, given that the boundary + // region is excluded) + bulkCollideAndStream(x0+vicinity,x1-vicinity,y0+vicinity,y1-vicinity); + + // Finally, do streaming in the boundary envelope to conclude the + // collision-stream cycle + boundaryStream(x0,x1,y0,y1, x0,x0+vicinity-1,y0,y1); + boundaryStream(x0,x1,y0,y1, x1-vicinity+1,x1,y0,y1); + boundaryStream(x0,x1,y0,y1, x0+vicinity,x1-vicinity, y0,y0+vicinity-1); + boundaryStream(x0,x1,y0,y1, x0+vicinity,x1-vicinity, y1-vicinity+1,y1); +} + +/** At the end of this method, the post-processing steps are automatically + * invoked. + * \sa collideAndStream(int,int,int,int) */ +template +void BlockLattice2D::collideAndStream(bool periodic) +{ + collideAndStream(0, this->_nx-1, 0, this->_ny-1); + + if (periodic) { + makePeriodic(); + } + + postProcess(); + getStatistics().incrementTime(); +} + +template +T BlockLattice2D::computeAverageDensity ( int x0, int x1, int y0, int y1) const +{ + T sumRho = T(); + for (int iX=x0; iX<=x1; ++iX) { + for (int iY=y0; iY<=y1; ++iY) { + T rho, u[DESCRIPTOR::d]; + get(iX,iY).computeRhoU(rho, u); + sumRho += rho; + } + } + return sumRho / (T)(x1-x0+1) / (T)(y1-y0+1); +} + +template +T BlockLattice2D::computeAverageDensity() const +{ + return computeAverageDensity(0, this->_nx-1, 0, this->_ny-1); +} + +template +void BlockLattice2D::computeStress(int iX, int iY, T pi[util::TensorVal::n]) +{ + grid[iX][iY].computeStress(pi); +} + +template +void BlockLattice2D::stripeOffDensityOffset ( int x0, int x1, int y0, int y1, T offset ) +{ + for (int iX=x0; iX<=x1; ++iX) { + for (int iY=y0; iY<=y1; ++iY) { + for (int iPop=0; iPop(iPop) * offset; + } + } + } +} + +template +void BlockLattice2D::stripeOffDensityOffset(T offset) +{ + stripeOffDensityOffset(0, this->_nx-1, 0, this->_ny-1, offset); +} + +template +void BlockLattice2D::forAll ( + int x0, int x1, int y0, int y1, WriteCellFunctional const& application ) +{ + for (int iX=x0; iX<=x1; ++iX) { + for (int iY=y0; iY<=y1; ++iY) { + int pos[] = {iX, iY}; + application.apply( get(iX,iY), pos ); + } + } +} + +template +void BlockLattice2D::forAll(WriteCellFunctional const& application) +{ + forAll(0, this->_nx-1, 0, this->_ny-1, application); +} + +template +void BlockLattice2D::addPostProcessor ( + PostProcessorGenerator2D const& ppGen ) +{ + postProcessors.push_back(ppGen.generate()); +} + +template +void BlockLattice2D::resetPostProcessors() +{ + clearPostProcessors(); + StatPPGenerator2D statPPGenerator; + addPostProcessor(statPPGenerator); +} + +template +void BlockLattice2D::clearPostProcessors() +{ + typename PostProcVector::iterator ppIt = postProcessors.begin(); + for (; ppIt != postProcessors.end(); ++ppIt) { + delete *ppIt; + } + postProcessors.clear(); +} + +template +void BlockLattice2D::postProcess() +{ + for (unsigned iPr=0; iPr process(*this); + } +} + +template +void BlockLattice2D::postProcess(int x0_, int x1_, int y0_, int y1_) +{ + for (unsigned iPr=0; iPr processSubDomain(*this, x0_, x1_, y0_, y1_); + } +} + +template +void BlockLattice2D::addLatticeCoupling ( + LatticeCouplingGenerator2D const& lcGen, + std::vector partners ) +{ + latticeCouplings.push_back(lcGen.generate(partners)); +} + +template +void BlockLattice2D::executeCoupling() +{ + for (unsigned iPr=0; iPr process(*this); + } +} + +template +void BlockLattice2D::executeCoupling(int x0_, int x1_, int y0_, int y1_) +{ + for (unsigned iPr=0; iPr processSubDomain(*this, x0_, x1_, y0_, y1_); + } +} + +template +void BlockLattice2D::clearLatticeCouplings() +{ + typename PostProcVector::iterator ppIt = latticeCouplings.begin(); + for (; ppIt != latticeC