/* This file is part of the OpenLB library * * Copyright (C) 2007, 2014 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 * The description of a vector of 3D cuboid -- header file. */ #ifndef CUBOID_GEOMETRY_3D_H #define CUBOID_GEOMETRY_3D_H #include #include #include "core/singleton.h" #include "core/serializer.h" #include "io/ostreamManager.h" #include "io/xmlReader.h" #include "core/vector.h" #include "geometry/cuboid3D.h" /// All OpenLB code is contained in this namespace. namespace olb { template< typename T> class Cuboid3D; template class IndicatorF3D; template class LoadBalancer; /// A cuboid geometry represents a voxel mesh /** A cuboid geometry is given by a number of cuboids. To represent * a connected domain it is required that the distance between two * neighbouring cuboids is less than the smallest delta of them. * * By the class, access is provided to the cuboids. Core methods of * the class are transforming lattice to physical positions in the * corresponding unit systems. * * WARNING: * At the moment there are only cuboids with a constant delta possible * and the distance between two neighbouring cuboids must be delta * since an interpolation operator in time and space is missing in * cuboidNeighbourhood and superLattice. * * This class is not intended to be derived from. */ template class CuboidGeometry3D : public BufferSerializable { private: /// Vector of the cuboids std::vector > _cuboids; /// Cuboid which contains all other cuboids Cuboid3D _motherCuboid; /// Periodicity flag Vector _periodicityOn; /// class specific ostream mutable OstreamManager clout; public: /// Constructs empty Geometry CuboidGeometry3D(); /// Constructs a cuboid geometry with a cubic shape of size nX times nY times nZ with origin originR=(originX, originY, originZ) that consists of nC cuboids CuboidGeometry3D(T originX, T originY, T originZ, T deltaR, int nX, int nY, int nZ, int nC=1); /// Constructor with vectors CuboidGeometry3D(std::vector origin, T deltaR, std::vector extent, int nC=1); /// Constructs a cuboid structure with a uniform spacing of voxelSize which consists of nC cuboids, the cuboids not needed are removed and too big ones are shrinked CuboidGeometry3D(IndicatorF3D& indicatorF, T voxelSize, int nC=1); CuboidGeometry3D(std::shared_ptr> indicator_sharedPtrF, T voxelSize, int nC=1); /// Constructs a cuboid structure with a uniform spacing of voxelSize which consists of nC cuboids, the cuboids not needed are removed and too big ones are shrinked. Uses an iterative method: Halves the largest child cuboid until the set number of cuboids is reached. Largest cuboid is determined by either volume or weight as choosen in minimizeBy. CuboidGeometry3D(IndicatorF3D& indicatorF, T voxelSize, int nC, std::string minimizeBy); CuboidGeometry3D(std::shared_ptr> indicator_sharedPtrF, T voxelSize, int nC, std::string minimizeBy); /// Destructs CuboidGeometry virtual ~CuboidGeometry3D(); /// Read and write access to a single cuboid Cuboid3D& get(int iC); /// Read access to a single cuboid Cuboid3D const& get(int iC) const; /// Returns the smallest cuboid that includes all cuboids of the structure Cuboid3D getMotherCuboid(); Cuboid3D const& getMotherCuboid() const; /// Set flag to enable/disable periodicity depending of direction. Be aware that not all directions are true to ensure boundary conditions like for velocity are not disturbed. void setPeriodicity(bool periodicityX, bool periodicityY, bool periodicityZ); /// Gives for a given point (globX/globY/globZ) the related cuboidID /// and _p if the point is not in any of the cuboid _childrenQ int get_iC(T globX, T globY, T globZ, int offset = 0) const; //TODO old ones int get_iC(Vector, int offset = 0) const; /// This function checks if the points (globX/globY/globZ) and /// (globX + orientationX/delta/globY + orientationY/delta/ /// globZ + orientationZ/delta) is in a cuboid. /// It gives the related cuboidID and _p if the points are /// not in any of the cuboids. /// abs(orientationX) = abs(orientationY) = abs(orientationY) = 1 /// must be satisfied int get_iC(T globX, T globY, T globZ, int orientationX, int orientationY, int orientationZ) const; //TODO old ones /// Returns true and the cuboid number of the nearest lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getC(T physR[3], int& iC) const; /// Returns true and the cuboid number of the nearest lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getC(std::vector physR, int& iC) const; //TODO new one /// Returns true and the cuboid number of the nearest lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getC(const Vector& physR, int& iC) const; /// Returns true and the nearest lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getLatticeR(int latticeR[4], const T physR[3]) const; /// Returns true and the floor lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getFloorLatticeR(const std::vector& physR, std::vector& latticeR) const; /// Returns true and the floor lattice position to the given physical position if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry bool getFloorLatticeR(const Vector& physR, Vector& latticeR) const; /// Returns the physical position to the given lattice position respecting periodicity for the overlap nodes which are not in the mother cuboid for the case the flag periodicityOn[iDim]=true if the physical position is within any of the cuboids with an overlap of 1/2*delta belonging to the cuboid geometry void getPhysR(T physR[3], const int& iCglob, const int& iX, const int& iY, const int& iZ) const; /// Returns the physical position to the given lattice position respecting periodicity for the overlap nodes which are not in the mother cuboid for the case the flag periodicityOn[iDim]=true void getPhysR(T physR[3], const int latticeR[4]) const; /// Stores the iC of the neighbouring cuboids in a vector; void getNeighbourhood(int cuboid, std::vector& neighbours, int offset = 0); /// Returns the number of cuboids in the structure int getNc() const; /// Returns the minimum of the ratio nX/NY in the structure T getMinRatio() const; /// Returns the maximum of the ratio nX/NY in the structure T getMaxRatio() const; /// Returns the minimum coordinate in the structure Vector getMinPhysR() const; /// Returns the maximum coordinate in the structure Vector getMaxPhysR() const; /// Returns the minimum volume in the structure T getMinPhysVolume() const; /// Returns the maximum volume in the structure T getMaxPhysVolume() const; /// Returns the minimum number of nodes in the structure size_t getMinLatticeVolume() const; /// Returns the maximum number of nodes in the structure size_t getMaxLatticeVolume() const; /// Returns the minimum number of nodes in the structure inside the indicator size_t getMinLatticeWeight() const; /// Returns the maximum number of nodes in the structure inside the indicator size_t getMaxLatticeWeight() const; /// Returns the minimum delta in the structure T getMinDeltaR() const; /// Returns the maximum delta in the structure T getMaxDeltaR() const; /// Compares two CuboidGeometries bool operator==(CuboidGeometry3D& rhs); /// Swaps data from input into object void swap(CuboidGeometry3D& rhs); /// Swaps the vector of cuboids void swapCuboids(std::vector< Cuboid3D >& cuboids); /// Replace the vector of cuboids void replaceCuboids(std::vector< Cuboid3D >& cuboids); /// Sets the number of full cells of each cuboid void setWeights(IndicatorF3D& indicatorF); /// Resets the cuboid array void clearCuboids() { _cuboids.clear(); } /// Adds a cuboid void add(Cuboid3D cuboid); /// Splits cuboid iC, removes it and adds p cuboids of same volume void split(int iC, int p); /// Splits cuboid iC, removes it and adds p cuboids of same weight void splitByWeight(int iC, int p, IndicatorF3D& indicatorF); /// Removes the cuboid iC void remove(int iC); /// Removes all cuboids where indicatorF = 0 void remove(IndicatorF3D& indicatorF); /// Shrink cuboid iC so that no empty planes are left void shrink(int iC, IndicatorF3D& indicatorF); /// Shrink all cuboids so that no empty planes are left void shrink(IndicatorF3D& indicatorF); /// Number of data blocks for the serializer interface size_t getNblock() const override; /// Binary size for the serializer interface 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; /// Prints cuboid geometry details void print() const; /// Prints cuboid geometry details plus details of all cuboids void printExtended(); /// Save CuboidGeometry into an existing XML File void writeToExistingFile(std::string completeFileName, LoadBalancer& loadBalancer); /// Save CuboidGeometry into XML File void writeToFile(std::string fileName, LoadBalancer& loadBalancer); private: /// Helper Function to create cuboid parameters for XML tag std::string _cuboidParameters(Cuboid3D const& cub); }; /// Helper Function to retrieve nData-dimensional std::vector of type S from space separated tag template std::vector getDataFromTag(XMLreader const& reader, std::string attrName, int nData) { std::vector values(nData, S()); std::stringstream extstr(reader.getAttribute(attrName)); for (auto& valueI: values) { extstr >> valueI; } return values; } /// Load CuboidGeometry from XML File template CuboidGeometry3D* createCuboidGeometry(std::string fileName) { OstreamManager clout("saveCuboidGeometry3D"); std::string fname = singleton::directories().getLogOutDir() + fileName + ".xml"; XMLreader reader(fname); std::vector origin = getDataFromTag(reader["CuboidGeometry"], "origin", 3); std::vector extent = getDataFromTag(reader["CuboidGeometry"], "extent", 3); T deltaR = getDataFromTag(reader["CuboidGeometry"], "deltaR", 1)[0]; size_t weight = getDataFromTag(reader["CuboidGeometry"], "weight", 1)[0]; int refinementLevel = getDataFromTag(reader["CuboidGeometry"], "refinementLevel", 1)[0]; CuboidGeometry3D* cGeo = new CuboidGeometry3D (origin, deltaR, extent); cGeo->getMotherCuboid().setRefinementLevel(refinementLevel); cGeo->getMotherCuboid().setWeight(weight); cGeo->clearCuboids(); for ( XMLreader* cub: reader["CuboidGeometry"] ) { origin = getDataFromTag(*cub, "origin", 3); extent = getDataFromTag(*cub, "extent", 3); deltaR = getDataFromTag(*cub, "deltaR", 1)[0]; weight = getDataFromTag(*cub, "weight", 1)[0]; refinementLevel = getDataFromTag(*cub, "refinementLevel", 1)[0]; cGeo->add( Cuboid3D(origin, deltaR, extent, refinementLevel) ); cGeo->get(cGeo->getNc() - 1).setWeight(weight); } return cGeo; } } // namespace olb #endif