/* This file is part of the OpenLB library * * Copyright (C) 2017 Adrian Kummerlaender * 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. */ #ifndef HYPERPLANE_LATTICE_3D_HH #define HYPERPLANE_LATTICE_3D_HH #include "hyperplaneLattice3D.h" namespace olb { template int HyperplaneLattice3D::computeMaxLatticeDistance(Cuboid3D&& cuboid) const { const Vector origin = cuboid.getOrigin(); const Vector extend = cuboid.getExtend(); const T deltaR = cuboid.getDeltaR(); T maxPhysDistance = T(); T tmp; Vector tmpO; Vector tmpE; for(int iDim=0; iDim<3; ++iDim){ tmpO[iDim] = origin[iDim] - _origin[iDim]; tmpE[iDim] = origin[iDim] + extend[iDim]*deltaR - _origin[iDim]; } tmp = sqrt(tmpO[0]*tmpO[0] + tmpO[1]*tmpO[1] + tmpO[2]*tmpO[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt((tmpE[0]*tmpE[0] + tmpO[1]*tmpO[1] + tmpO[2]*tmpO[2])); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpO[0]*tmpO[0] + tmpE[1]*tmpE[1] + tmpO[2]*tmpO[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpO[0]*tmpO[0] + tmpO[1]*tmpO[1] + tmpE[2]*tmpE[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpO[0]*tmpO[0] + tmpE[1]*tmpE[1] + tmpE[2]*tmpE[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpE[0]*tmpE[0] + tmpO[1]*tmpO[1] + tmpE[2]*tmpE[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpE[0]*tmpE[0] + tmpE[1]*tmpE[1] + tmpO[2]*tmpO[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } tmp = sqrt(tmpE[0]*tmpE[0] + tmpE[1]*tmpE[1] + tmpE[2]*tmpE[2]); if (maxPhysDistance < tmp) { maxPhysDistance = tmp; } return int(maxPhysDistance/_h) + 1; } template void HyperplaneLattice3D::constructCuboid( CuboidGeometry3D& geometry, int maxLatticeDistance) { int iC; int minX = -maxLatticeDistance; int maxX = maxLatticeDistance; int minY = -maxLatticeDistance; int maxY = maxLatticeDistance; bool found = false; for ( int iX = -maxLatticeDistance; iX < maxLatticeDistance; ++iX ) { for ( int iY = -maxLatticeDistance; iY < maxLatticeDistance; ++iY ) { if ( geometry.getC(getPhysR(iX, iY), iC) ) { minX = iX; found = true; break; } } if (found) { break; } } found = false; for ( int iX = maxLatticeDistance; iX > -maxLatticeDistance; --iX ) { for ( int iY = -maxLatticeDistance; iY < maxLatticeDistance; ++iY ) { if ( geometry.getC(getPhysR(iX, iY), iC) ) { maxX = iX; found = true; break; } } if (found) { break; } } found = false; for ( int iY = -maxLatticeDistance; iY < maxLatticeDistance; ++iY ) { for ( int iX = -maxLatticeDistance; iX < maxLatticeDistance; ++iX ) { if ( geometry.getC(getPhysR(iX, iY), iC) ) { minY = iY; found = true; break; } } if (found) { break; } } found = false; for ( int iY = maxLatticeDistance; iY > -maxLatticeDistance; --iY ) { for ( int iX = -maxLatticeDistance; iX < maxLatticeDistance; ++iX ) { if ( geometry.getC(getPhysR(iX, iY), iC) ) { maxY = iY; found = true; break; } } if (found) { break; } } _nx = maxX - minX + 1; _ny = maxY - minY + 1; _origin = _origin + double(minX)*_u + double(minY)*_v; } template void HyperplaneLattice3D::setToResolution(int resolution) { if (_nx > _ny) { T newH = _nx*_h/(T) resolution; _nx = resolution; _ny = (int) (_ny*_h/newH) + 1; _h = newH; } else { T newH = _ny*_h/(T) resolution; _ny = resolution; _nx = (int) (_nx*_h/newH) + 1; _h = newH; } _u.normalize(_h); _v.normalize(_h); } template HyperplaneLattice3D::HyperplaneLattice3D( CuboidGeometry3D& geometry, Hyperplane3D hyperplane) : _hyperplane(hyperplane), _origin(hyperplane.origin), _u(hyperplane.u), _v(hyperplane.v), _h(geometry.getMinDeltaR()) { _u.normalize(_h); _v.normalize(_h); const int maxLatticeDistance = computeMaxLatticeDistance(geometry.getMotherCuboid()); // compute _hyperplane.origin, _nx, _ny so that the cuboid is right inside the geometry constructCuboid(geometry, maxLatticeDistance); } template HyperplaneLattice3D::HyperplaneLattice3D( CuboidGeometry3D& geometry, Hyperplane3D hyperplane, int resolution) : _hyperplane(hyperplane), _origin(hyperplane.origin), _u(hyperplane.u), _v(hyperplane.v), _h(geometry.getMinDeltaR()) { _u.normalize(_h); _v.normalize(_h); const int maxLatticeDistance = computeMaxLatticeDistance(geometry.getMotherCuboid()); // compute _hyperplane.origin, _nx, _ny so that the cuboid is right inside the geometry constructCuboid(geometry, maxLatticeDistance); if ( resolution > 0 ) { setToResolution(resolution); } } template HyperplaneLattice3D::HyperplaneLattice3D( CuboidGeometry3D& geometry, Hyperplane3D hyperplane, T h) : _hyperplane(hyperplane), _origin(hyperplane.origin), _u(hyperplane.u), _v(hyperplane.v), _h(h) { if ( util::nearZero(_h) ) { _h = geometry.getMinDeltaR(); } _u.normalize(_h); _v.normalize(_h); const int maxLatticeDistance = computeMaxLatticeDistance(geometry.getMotherCuboid()); // compute _hyperplane.origin, _nx, _ny so that the cuboid is right inside the geometry constructCuboid(geometry, maxLatticeDistance); } template HyperplaneLattice3D::HyperplaneLattice3D( Hyperplane3D hyperplane, T h, int nx, int ny) : _hyperplane(hyperplane), _origin(hyperplane.origin), _u(hyperplane.u), _v(hyperplane.v), _h(h), _nx(nx), _ny(ny) { _u.normalize(_h); _v.normalize(_h); } template const Hyperplane3D& HyperplaneLattice3D::getHyperplane() const { return _hyperplane; } template Vector HyperplaneLattice3D::getPhysR(const int& planeX, const int& planeY) const { return Vector { _origin[0] + double(planeX)*_u[0] + double(planeY)*_v[0], _origin[1] + double(planeX)*_u[1] + double(planeY)*_v[1], _origin[2] + double(planeX)*_u[2] + double(planeY)*_v[2] }; } template int HyperplaneLattice3D::getNx() const { return _nx; } template int HyperplaneLattice3D::getNy() const { return _ny; } template T HyperplaneLattice3D::getPhysSpacing() const { return _h; } template Vector HyperplaneLattice3D::getPhysOrigin() const { return _origin; } template Vector HyperplaneLattice3D::getVectorU() const { return _u; } template Vector HyperplaneLattice3D::getVectorV() const { return _v; } } #endif