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/geometry/cuboidGeometry2D.hh | 677 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 src/geometry/cuboidGeometry2D.hh (limited to 'src/geometry/cuboidGeometry2D.hh') diff --git a/src/geometry/cuboidGeometry2D.hh b/src/geometry/cuboidGeometry2D.hh new file mode 100644 index 0000000..f7a68e9 --- /dev/null +++ b/src/geometry/cuboidGeometry2D.hh @@ -0,0 +1,677 @@ +/* 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 2D cuboid -- generic implementation. + */ + + +#ifndef CUBOID_GEOMETRY_2D_HH +#define CUBOID_GEOMETRY_2D_HH + + +#include +#include +#include "geometry/cuboidGeometry2D.h" +#include "functors/analytical/indicator/indicatorF2D.h" + +namespace olb { + + +////////////////////// Class CuboidGeometry2D ///////////////////////// + +template +CuboidGeometry2D::CuboidGeometry2D() + : _motherCuboid(0,0,0,0,0), _periodicityOn(3, bool(false)), clout(std::cout, "CuboidGeometry3D") +{ + add(_motherCuboid); + split(0, 1); +} + +template +CuboidGeometry2D::CuboidGeometry2D(T originX, T originY, T deltaR, int nX, int nY, int nC) + : _motherCuboid(originX, originY, deltaR, nX, nY), _periodicityOn(2, bool(false)), + clout(std::cout, "CuboidGeometry2D") +{ + add(_motherCuboid); + split(0, nC); +} + +template +CuboidGeometry2D::CuboidGeometry2D(IndicatorF2D& indicatorF, T voxelSize, int nC) + : _motherCuboid(indicatorF.getMin()[0], indicatorF.getMin()[1], voxelSize, + (int)((indicatorF.getMax()[0] - indicatorF.getMin()[0]) / voxelSize + 1.5), + (int)((indicatorF.getMax()[1] - indicatorF.getMin()[1]) / voxelSize + 1.5)), + _periodicityOn(2, bool(false)), clout(std::cout, "CuboidGeometry2D") +{ + + add(_motherCuboid); + split(0, nC); + shrink(indicatorF); +} + + +template +void CuboidGeometry2D::reInit(T globPosX, T globPosY, T delta, int nX, int nY, int nC) +{ + _cuboids.clear(); + _motherCuboid = Cuboid2D(globPosX, globPosY, delta, nX, nY); + Cuboid2D cuboid(globPosX, globPosY, delta, nX, nY); + if (_oldApproach) { + cuboid.init(0, 0, 1, nX, nY); + } + + add(cuboid); + split(0, nC); +} + +template +Cuboid2D& CuboidGeometry2D::get(int i) +{ + return _cuboids[i]; +} + +template +Cuboid2D const& CuboidGeometry2D::get(int i) const +{ + return _cuboids[i]; +} + +template +void CuboidGeometry2D::setPeriodicity(bool periodicityX, bool periodicityY) +{ + _periodicityOn.resize(2); + _periodicityOn[0] = periodicityX; + _periodicityOn[1] = periodicityY; +} + + +template +bool CuboidGeometry2D::getC(std::vector physR, int& iC) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + iC = iCtmp; + return true; + } + else { + return false; + } +} + +template +bool CuboidGeometry2D::getC(const Vector& physR, int& iC) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + iC = iCtmp; + return true; + } + else { + return false; + } +} + +template +bool CuboidGeometry2D::getLatticeR(std::vector physR, std::vector& latticeR) const +{ + return getLatticeR(&latticeR[0], &physR[0]); + /* int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + latticeR[0] = iCtmp; + latticeR[1] = (int)floor( (physR[0] - _cuboids[latticeR[0]].getOrigin()[0] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + latticeR[2] = (int)floor( (physR[1] - _cuboids[latticeR[0]].getOrigin()[1] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + return true; + } else { + return false; + }*/ +} + +template +bool CuboidGeometry2D::getLatticeR(int latticeR[], const T physR[]) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + latticeR[0] = iCtmp; + latticeR[1] = (int)floor( (physR[0] - _cuboids[latticeR[0]].getOrigin()[0] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + latticeR[2] = (int)floor( (physR[1] - _cuboids[latticeR[0]].getOrigin()[1] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + return true; + } + else { + return false; + } +} + +template +bool CuboidGeometry2D::getLatticeR( + const Vector& physR, Vector& latticeR) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + latticeR[0] = iCtmp; + latticeR[1] = (int)floor( (physR[0] - _cuboids[latticeR[0]].getOrigin()[0] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + latticeR[2] = (int)floor( (physR[1] - _cuboids[latticeR[0]].getOrigin()[1] ) / _cuboids[latticeR[0]].getDeltaR() + .5); + return true; + } + else { + return false; + } +} + +template +bool CuboidGeometry2D::getFloorLatticeR(std::vector physR, std::vector& latticeR) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + latticeR[0] = iCtmp; + latticeR[1] = (int)floor( (physR[0] - _cuboids[latticeR[0]].getOrigin()[0] ) / _cuboids[latticeR[0]].getDeltaR() ); + latticeR[2] = (int)floor( (physR[1] - _cuboids[latticeR[0]].getOrigin()[1] ) / _cuboids[latticeR[0]].getDeltaR() ); + return true; + } + else { + return false; + } +} + +template +bool CuboidGeometry2D::getFloorLatticeR( + const Vector& physR, Vector& latticeR) const +{ + int iCtmp = get_iC(physR[0], physR[1]); + if (iCtmp < getNc()) { + latticeR[0] = iCtmp; + latticeR[1] = (int)floor( (physR[0] - _cuboids[latticeR[0]].getOrigin()[0] ) / _cuboids[latticeR[0]].getDeltaR() ); + latticeR[2] = (int)floor( (physR[1] - _cuboids[latticeR[0]].getOrigin()[1] ) / _cuboids[latticeR[0]].getDeltaR() ); + return true; + } + else { + return false; + } +} + +template +std::vector CuboidGeometry2D::getPhysR(int iCglob, int iX, int iY) const +{ + std::vector physR(2,T()); + _cuboids[iCglob].getPhysR(&(physR[0]), iX, iY); + for (int iDim = 0; iDim < 2; iDim++) { + if (_periodicityOn[iDim]) { + //std::cout << iDim << _periodicityOn[iDim] <<":"<< _motherCuboid.getDeltaR()*(_motherCuboid.getExtend()[iDim]) << std::endl; + physR[iDim] = remainder( physR[iDim] - _motherCuboid.getOrigin()[iDim] + + _motherCuboid.getDeltaR() * (_motherCuboid.getExtend()[iDim]), + _motherCuboid.getDeltaR() * (_motherCuboid.getExtend()[iDim])); + // solving the rounding error problem for double + if ( physR[iDim]*physR[iDim] < 0.001 * _motherCuboid.getDeltaR()*_motherCuboid.getDeltaR() ) { + physR[iDim] = T(); + } + // make it to mod instead remainer + if ( physR[iDim] < 0 ) { + physR[iDim] += _motherCuboid.getDeltaR() * _motherCuboid.getExtend()[iDim]; + } + // add origin + physR[iDim] += _motherCuboid.getOrigin()[iDim]; + } + } + return physR; +} + +template +std::vector CuboidGeometry2D::getPhysR(std::vector latticeR) const +{ + return getPhysR(latticeR[0], latticeR[1], latticeR[2]); +} + +template +void CuboidGeometry2D::getPhysR(T output[2], const int latticeR[3]) const +{ + getPhysR(output, latticeR[0], latticeR[1], latticeR[2]); +} + +template +void CuboidGeometry2D::getPhysR(T output[2], const int iCglob, const int iX, const int iY) const +{ + _cuboids[iCglob].getPhysR(output, iX, iY); + for (int iDim = 0; iDim < 2; iDim++) { + if (_periodicityOn[iDim]) { + //std::cout << iDim << _periodicityOn[iDim] <<":"<< _motherCuboid.getDeltaR()*(_motherCuboid.getExtend()[iDim]) << std::endl; + output[iDim] = remainder( output[iDim] - _motherCuboid.getOrigin()[iDim] + + _motherCuboid.getDeltaR() * (_motherCuboid.getExtend()[iDim]), + _motherCuboid.getDeltaR() * (_motherCuboid.getExtend()[iDim])); + // solving the rounding error problem for double + if ( output[iDim]*output[iDim] < 0.001 * _motherCuboid.getDeltaR()*_motherCuboid.getDeltaR() ) { + if ( output[iDim] > 0 ) { + output[iDim] = _motherCuboid.getDeltaR() * _motherCuboid.getExtend()[iDim]; + } + else { + output[iDim] = T(); + } + } + // make it to mod instead remainer + if ( output[iDim] < 0 ) { + output[iDim] += _motherCuboid.getDeltaR() * _motherCuboid.getExtend()[iDim]; + } + // add origin + output[iDim] += _motherCuboid.getOrigin()[iDim]; + } + } +} + +template +int CuboidGeometry2D::getNc() const +{ + return _cuboids.size(); +} + +template +T CuboidGeometry2D::getMinRatio() const +{ + T minRatio = 1.; + for ( auto& cuboid : _cuboids ) { + if ((T)cuboid.getNx() / (T)cuboid.getNy() < minRatio) { + minRatio = (T)cuboid.getNx() / (T)cuboid.getNy(); + } + } + return minRatio; +} + +template +T CuboidGeometry2D::getMaxRatio() const +{ + T maxRatio = 1.; + for (unsigned i = 0; i < _cuboids.size(); i++) { + if ((T)_cuboids[i].getNx() / (T)_cuboids[i].getNy() > maxRatio) { + maxRatio = (T)_cuboids[i].getNx() / (T)_cuboids[i].getNy(); + } + } + return maxRatio; +} + +template +std::vector CuboidGeometry2D::getMinPhysR() const +{ + Vector output(_cuboids[0].getOrigin()); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getOrigin()[0] < output[0]) { + output[0] = _cuboids[i].getOrigin()[0]; + } + if (_cuboids[i].getOrigin()[1] < output[1]) { + output[1] = _cuboids[i].getOrigin()[1]; + } + } + return std::vector {output[0],output[1]}; +} + +template +std::vector CuboidGeometry2D::getMaxPhysR() const +{ + Vector output(_cuboids[0].getOrigin()); + output[0] += _cuboids[0].getNx()*_cuboids[0].getDeltaR(); + output[1] += _cuboids[0].getNy()*_cuboids[0].getDeltaR(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getOrigin()[0] + _cuboids[i].getNx()*_cuboids[i].getDeltaR() > output[0]) { + output[0] = _cuboids[i].getOrigin()[0] + _cuboids[i].getNx()*_cuboids[i].getDeltaR(); + } + if (_cuboids[i].getOrigin()[1] + _cuboids[i].getNy()*_cuboids[i].getDeltaR() > output[1]) { + output[1] = _cuboids[i].getOrigin()[1] + _cuboids[i].getNy()*_cuboids[i].getDeltaR(); + } + } + return std::vector {output[0],output[1]}; +} + +template +T CuboidGeometry2D::getMinPhysVolume() const +{ + T minVolume = _cuboids[0].getPhysVolume(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getPhysVolume() < minVolume) { + minVolume = _cuboids[i].getPhysVolume(); + } + } + return minVolume; +} + +template +T CuboidGeometry2D::getMaxPhysVolume() const +{ + T maxVolume = _cuboids[0].getPhysVolume(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getPhysVolume() > maxVolume) { + maxVolume = _cuboids[i].getPhysVolume(); + } + } + return maxVolume; +} + +template +size_t CuboidGeometry2D::getMinLatticeVolume() const +{ + size_t minNodes = _cuboids[0].getLatticeVolume(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getLatticeVolume() < minNodes) { + minNodes = _cuboids[i].getLatticeVolume(); + } + } + return minNodes; +} + +template +size_t CuboidGeometry2D::getMaxLatticeVolume() const +{ + size_t maxNodes = _cuboids[0].getLatticeVolume(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getLatticeVolume() > maxNodes) { + maxNodes = _cuboids[i].getLatticeVolume(); + } + } + return maxNodes; +} + +template +T CuboidGeometry2D::getMinDeltaR() const +{ + T minDelta = _cuboids[0].getDeltaR(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getDeltaR() < minDelta) { + minDelta = _cuboids[i].getDeltaR(); + } + } + return minDelta; +} + +template +T CuboidGeometry2D::getMaxDeltaR() const +{ + T maxDelta = _cuboids[0].getDeltaR(); + for (unsigned i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].getDeltaR() > maxDelta) { + maxDelta = _cuboids[i].getDeltaR(); + } + } + return maxDelta; +} + +template +Cuboid2D CuboidGeometry2D::getMotherCuboid() const +{ + + /*Cuboid2D found; + if(_cuboids.size()==0) { + found.init(0, 0, 0, 0, 0); + return found; + } + + T delta = _cuboids[0].getDeltaR(); + T globPosXmin = _cuboids[0].get_globPosX(); + T globPosYmin = _cuboids[0].get_globPosY(); + T globPosXmax = _cuboids[0].get_globPosX() + delta*(_cuboids[0].getNx()-1); + T globPosYmax = _cuboids[0].get_globPosY() + delta*(_cuboids[0].getNy()-1); + + for (unsigned i=1; i<_cuboids.size(); i++) { + if(delta > _cuboids[i].getDeltaR() ) { + delta = _cuboids[i].getDeltaR(); + } + if(globPosXmin > _cuboids[i].get_globPosX() ) { + globPosXmin = _cuboids[i].get_globPosX(); + } + if(globPosYmin > _cuboids[i].get_globPosY() ) { + globPosYmin = _cuboids[i].get_globPosY(); + } + if(globPosXmax < _cuboids[i].get_globPosX() + + delta*(_cuboids[i].getNx()-1)) { + globPosXmax = _cuboids[i].get_globPosX() + + delta*(_cuboids[i].getNx()-1); + } + if(globPosYmax < _cuboids[i].get_globPosY() + + delta*(_cuboids[i].getNy()-1)) { + globPosYmax = _cuboids[i].get_globPosY() + + delta*(_cuboids[i].getNy()-1); + } + } + int nX = int(ceil((globPosXmax - globPosXmin)/delta))+1; + int nY = int(ceil((globPosYmax - globPosYmin)/delta))+1; + + found.init(globPosXmin, globPosYmin, delta, nX, nY); + + return found;*/ + return _motherCuboid; +} + +template +int CuboidGeometry2D::get_iC(T globX, T globY, int offset) const +{ + unsigned i; + for (i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].checkPoint(globX, globY, offset)) { + return (int)i; + } + } + return (int)i; +} + +template +int CuboidGeometry2D::get_iC(T globX, T globY, int orientationX, int orientationY) const +{ + unsigned i; + for (i = 0; i < _cuboids.size(); i++) { + if (_cuboids[i].checkPoint(globX, globY) && + _cuboids[i].checkPoint(globX + orientationX / _cuboids[i].getDeltaR(), + globY + orientationY / _cuboids[i].getDeltaR())) { + return (int)i; + } + } + return (int)i; +} + + +template +void CuboidGeometry2D::add(Cuboid2D cuboid) +{ + + _cuboids.push_back(cuboid); +} + +template +void CuboidGeometry2D::remove(int iC) +{ + + _cuboids.erase(_cuboids.begin() + iC); +} +/* +template +void CuboidGeometry2D::remove(olb::ScalarField2D* geometryData) +{ + + std::vector > cuboids; + unsigned size = _cuboids.size(); + + std::vector allZero; + for (unsigned i = 0; i < size; i++) { + allZero.push_back(1); + for (int iX = 0; iX < _cuboids[i].getNx(); iX++) { + for (int iY = 0; iY < _cuboids[i].getNy(); iY++) { + if (geometryData->get(_cuboids[i].get_globPosX() + iX, + _cuboids[i].get_globPosY() + iY) != 0 ) { + allZero[i] = 0; + } + } + } + } + for (unsigned i = 0; i < size; i++) { + if (!allZero[i] ) { + cuboids.push_back(_cuboids[i]); + } + } + _cuboids.clear(); + for (unsigned i = 0; i < cuboids.size(); i++) { + _cuboids.push_back(cuboids[i]); + } +}*/ + +template +void CuboidGeometry2D::shrink(IndicatorF2D& indicatorF) +{ + //IndicatorIdentity3D tmpIndicatorF(indicatorF); + int newX, newY, maxX, maxY; + int nC = getNc(); + std::vector latticeR(3, 0); + std::vector physR(2, T()); + bool inside[1]; + for (int iC = nC - 1; iC >= 0; iC--) { + latticeR[0] = iC; + int fullCells = 0; + int xN = get(iC).getNx(); + int yN = get(iC).getNy(); + maxX = 0; + maxY = 0; + newX = xN - 1; + newY = yN - 1; + for (int iX = 0; iX < xN; iX++) { + for (int iY = 0; iY < yN; iY++) { + latticeR[1] = iX; + latticeR[2] = iY; + physR = getPhysR(latticeR); + indicatorF(inside,&physR[0]); + if (inside[0]) { + fullCells++; + maxX = std::max(maxX, iX); + maxY = std::max(maxY, iY); + newX = std::min(newX, iX); + newY = std::min(newY, iY); + } + } + } + if (fullCells > 0) { + get(iC).setWeight(fullCells); + _cuboids[iC].resize(newX, newY, maxX - newX + 1, maxY - newY + 1); + } + else { + remove(iC); + } + } + // shrink mother cuboid + std::vector minPhysR = getMinPhysR(); + std::vector maxPhysR = getMaxPhysR(); + T minDelataR = getMinDeltaR(); + _motherCuboid = Cuboid2D(minPhysR[0], minPhysR[1], minDelataR, (int)((maxPhysR[0]-minPhysR[0])/minDelataR + 0.5), (int)((maxPhysR[1]-minPhysR[1])/minDelataR + 0.5)); +} + +template +void CuboidGeometry2D::split(int iC, int p) +{ + + Cuboid2D temp(_cuboids[iC].get_globPosX(), _cuboids[iC].get_globPosY(), + _cuboids[iC].getDeltaR(), _cuboids[iC].getNx(), _cuboids[iC].getNy()); + temp.divide(p, _cuboids); + remove(iC); +} + +template +void CuboidGeometry2D::getNeighbourhood(int cuboid, std::vector neighbours, int offset) +{ + for (int iC = 0; iC < getNc(); iC++) { + if (cuboid == iC) { + continue; + } + T globX = get(iC).get_globPosX(); + T globY = get(iC).get_globPosY(); + T nX = get(iC).getNx(); + T nY = get(iC).getNy(); + if (get(cuboid).checkInters(globX, globX + nX, globY, globY + nY, offset)) { + neighbours.push_back(iC); + } + } +} + +template +void CuboidGeometry2D::refineArea(T x0, T x1, T y0, T y1, int coarse_level) +{ + + for (int iC = 0; iC < getNc(); iC++) { + if (get(iC).get_refinementLevel() != coarse_level) { + continue; + } + int locX0, locX1, locY0, locY1; + bool inter = get(iC).checkInters(x0, y1, y0, y1, locX0, locX1, locY0, locY1, 0); + if (!inter) { + continue; + } + + T globX = get(iC).get_globPosX(); + T globY = get(iC).get_globPosY(); + T delta = get(iC).getDeltaR(); + int nx = get(iC).getNx(); + int ny = get(iC).getNy(); + + if (locX0 != 0) { + Cuboid2D right_side(globX, globY, delta, locX0, ny, coarse_level); + add(right_side); + } + + if (locY0 != 0) { + Cuboid2D down_side(globX + locX0 * delta, globY, delta, nx - locX0, locY0, coarse_level); + add(down_side); + } + + if (locX1 != get(iC).getNx() - 1) { + Cuboid2D left_side(globX + (locX1 + 1)*delta, globY + locY0 * delta, delta, nx - locX1 - 1, ny - locY0, coarse_level); + add(left_side); + } + + if (locY1 != get(iC).getNy() - 1) { + Cuboid2D top_side(globX + locX0 * delta, globY + (locY1 + 1)*delta, delta, locX1 - locX0 + 1, ny - locY1 - 1, coarse_level); + add(top_side); + } + get(iC).init(globX + locX0 * delta, globY + locY0 * delta, delta, locX1 - locX0 + 1, locY1 - locY0 + 1, coarse_level); + get(iC).refineIncrease(); + } +} + +template +void CuboidGeometry2D::print() const +{ + clout << "---Cuboid Stucture Statistics---" << std::endl; + clout << " Number of Cuboids: " << "\t" << getNc() << std::endl; + clout << " Delta (min): " << "\t" << "\t" << getMinDeltaR() << std::endl; + clout << " (max): " << "\t" << "\t" << getMaxDeltaR() << std::endl; + clout << " Ratio (min): " << "\t" << "\t" << getMinRatio() << std::endl; + clout << " (max): " << "\t" << "\t" << getMaxRatio() << std::endl; + clout << " Nodes (min): " << "\t" << "\t" << getMinLatticeVolume() << std::endl; + clout << " (max): " << "\t" << "\t" << getMaxLatticeVolume() << std::endl; + clout << "--------------------------------" << std::endl; +} + +template +void CuboidGeometry2D::printExtended() +{ + clout << "Mothercuboid :" << std::endl; + getMotherCuboid().print(); + + for (int iC = 0; iC < getNc(); iC++) { + clout << "Cuboid #" << iC << ": " << std::endl; + get(iC).print(); + } +} + +} // namespace olb + +#endif -- cgit v1.2.3