/* This file is part of the OpenLB library * * Copyright (C) 2007 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 * A helper for initialising 3D boundaries -- generic implementation. */ #ifndef SUPER_BOUNDARY_CONDITION_3D_HH #define SUPER_BOUNDARY_CONDITION_3D_HH #include #include "boundaryCondition3D.h" #include "geometry/superGeometry3D.h" #include "extendedFiniteDifferenceBoundary3D.h" #include "superBoundaryCondition3D.h" #include "core/superLattice3D.h" #include "functors/lattice/indicator/superIndicatorBaseF3D.h" #include "advectionDiffusionBoundaryCondition3D.h" namespace olb { ///////// class superBoundaryCondition3D /////////////////////////////// template sOnLatticeBoundaryCondition3D::sOnLatticeBoundaryCondition3D( SuperLattice3D& sLattice) : clout(std::cout,"sOnLatticeBoundaryCondition3D"), _sLattice(sLattice), _output(false) { } template sOnLatticeBoundaryCondition3D::sOnLatticeBoundaryCondition3D( sOnLatticeBoundaryCondition3D const& rhs) : clout(std::cout,"sOnLatticeBoundaryCondition3D"), _sLattice(rhs._sLattice), _output(false) { _blockBCs = rhs._blockBCs; _ADblockBCs = rhs._ADblockBCs; _overlap = rhs._overlap; } template sOnLatticeBoundaryCondition3D sOnLatticeBoundaryCondition3D::operator=(sOnLatticeBoundaryCondition3D rhs) { sOnLatticeBoundaryCondition3D tmp(rhs); return tmp; } template sOnLatticeBoundaryCondition3D::~sOnLatticeBoundaryCondition3D() { for (auto &iC : _blockBCs) { delete iC; } for (auto &iC : _ADblockBCs) { delete iC; } } template void sOnLatticeBoundaryCondition3D::addVelocityBoundary( FunctorPtr>&& indicator, T omega) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iC = 0; iC < _sLattice.getLoadBalancer().size(); ++iC) { _blockBCs[iC]->addVelocityBoundary(indicator->getExtendedBlockIndicatorF(iC), omega, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addVelocityBoundary( SuperGeometry3D& superGeometry, int material, T omega) { addVelocityBoundary(superGeometry.getMaterialIndicator(material), omega); } template void sOnLatticeBoundaryCondition3D::addSlipBoundary( FunctorPtr>&& indicator) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addSlipBoundary( indicator->getExtendedBlockIndicatorF(iCloc), includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addSlipBoundary( SuperGeometry3D& superGeometry, int material) { addSlipBoundary(superGeometry.getMaterialIndicator(material)); } template void sOnLatticeBoundaryCondition3D::addPartialSlipBoundary( T tuner, FunctorPtr>&& indicator) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addPartialSlipBoundary( tuner, indicator->getExtendedBlockIndicatorF(iCloc), includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addPartialSlipBoundary( T tuner, SuperGeometry3D& superGeometry, int material) { addPartialSlipBoundary(tuner, superGeometry.getMaterialIndicator(material)); } template void sOnLatticeBoundaryCondition3D::addWallFunctionBoundary( FunctorPtr>&& indicator, UnitConverter const& converter, wallFunctionParam const& wallFunctionParam, IndicatorF3D* geoIndicator) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addWallFunctionBoundary( indicator->getExtendedBlockIndicatorF(iCloc), converter, wallFunctionParam, geoIndicator, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addWallFunctionBoundary( SuperGeometry3D& superGeometry, int material, UnitConverter const& converter, wallFunctionParam const& wallFunctionParam, IndicatorF3D* geoIndicator) { addWallFunctionBoundary(superGeometry.getMaterialIndicator(material), converter, wallFunctionParam, geoIndicator); } template void sOnLatticeBoundaryCondition3D::addPressureBoundary( FunctorPtr>&& indicator, T omega) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addPressureBoundary(indicator->getExtendedBlockIndicatorF(iCloc), omega, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addPressureBoundary( SuperGeometry3D& superGeometry, int material, T omega) { addPressureBoundary(superGeometry.getMaterialIndicator(material), omega); } template void sOnLatticeBoundaryCondition3D::addConvectionBoundary( FunctorPtr>&& indicator, T omega, T* uAv) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addConvectionBoundary(indicator->getExtendedBlockIndicatorF(iCloc), omega, uAv, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addConvectionBoundary( SuperGeometry3D& superGeometry, int material, T omega, T* uAv) { addConvectionBoundary(superGeometry.getMaterialIndicator(material), omega, uAv); } template void sOnLatticeBoundaryCondition3D::addConvectionBoundary( FunctorPtr>&& indicator) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _ADblockBCs[iCloc]->addConvectionBoundary(indicator->getExtendedBlockIndicatorF(iCloc), includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addConvectionBoundary( SuperGeometry3D& superGeometry, int material) { addConvectionBoundary(superGeometry.getMaterialIndicator(material)); } template void sOnLatticeBoundaryCondition3D::addTemperatureBoundary( FunctorPtr>&& indicator, T omega) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); iCloc++) { _ADblockBCs[iCloc]->addTemperatureBoundary( indicator->getExtendedBlockIndicatorF(iCloc), omega, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addTemperatureBoundary( SuperGeometry3D& superGeometry, int material, T omega) { addTemperatureBoundary(superGeometry.getMaterialIndicator(material), omega); } template void sOnLatticeBoundaryCondition3D::addExtFieldBoundary( FunctorPtr>&& indicator, int offset) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _ADblockBCs[iCloc]->addExtFieldBoundary(indicator->getExtendedBlockIndicatorF(iCloc), offset, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addExtFieldBoundary( SuperGeometry3D& superGeometry, int material, int offset) { addExtFieldBoundary(superGeometry.getMaterialIndicator(material), offset); } template void sOnLatticeBoundaryCondition3D::addZeroDistributionBoundary( FunctorPtr>&& indicator) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _ADblockBCs[iCloc]->addZeroDistributionBoundary( indicator->getExtendedBlockIndicatorF(iCloc), includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addZeroDistributionBoundary( SuperGeometry3D& superGeometry, int material) { addZeroDistributionBoundary(superGeometry.getMaterialIndicator(material)); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyWallBoundary( FunctorPtr>&& indicator, T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } T addend = 0; if(latticeNumber==1) addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) ); else if(latticeNumber==2) addend = 1./(alpha*alpha) * ( (h1/kappa1) + (-h2/kappa2) ); else if(latticeNumber==3) addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) ); for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addFreeEnergyWallBoundary( indicator->getExtendedBlockIndicatorF(iCloc), addend, latticeNumber, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyWallBoundary( SuperGeometry3D& superGeometry, int material, T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber) { addFreeEnergyWallBoundary(superGeometry.getMaterialIndicator(material), alpha, kappa1, kappa2, h1, h2, latticeNumber); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyWallBoundary( FunctorPtr>&& indicator, T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2, T h3, int latticeNumber) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } T addend = 0; if(latticeNumber==1) addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) + (h3/kappa3) ); else if(latticeNumber==2) addend = 1./(alpha*alpha) * ( (h1/kappa1) + (-h2/kappa2) ); else if(latticeNumber==3) addend = 1./(alpha*alpha) * ( (h3/kappa3) ); for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addFreeEnergyWallBoundary( indicator->getExtendedBlockIndicatorF(iCloc), addend, latticeNumber, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyWallBoundary( SuperGeometry3D& superGeometry, int material, T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2, T h3, int latticeNumber) { addFreeEnergyWallBoundary(superGeometry.getMaterialIndicator(material), alpha, kappa1, kappa2, kappa3, h1, h2, h3, latticeNumber); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyInletBoundary( FunctorPtr>&& indicator, T omega, std::string type, int latticeNumber) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addFreeEnergyInletBoundary( indicator->getExtendedBlockIndicatorF(iCloc), omega, type, latticeNumber, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyInletBoundary( SuperGeometry3D& superGeometry, int material, T omega, std::string type, int latticeNumber) { addFreeEnergyInletBoundary(superGeometry.getMaterialIndicator(material), omega, type, latticeNumber); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyOutletBoundary( FunctorPtr>&& indicator, T omega, std::string type, int latticeNumber) { bool includeOuterCells = false; if (indicator->getSuperGeometry().getOverlap() == 1) { includeOuterCells = true; clout << "WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials" << std::endl; } for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { _blockBCs[iCloc]->addFreeEnergyOutletBoundary( indicator->getExtendedBlockIndicatorF(iCloc), omega, type, latticeNumber, includeOuterCells); } addPoints2CommBC(std::forward(indicator)); } template void sOnLatticeBoundaryCondition3D::addFreeEnergyOutletBoundary( SuperGeometry3D& superGeometry, int material, T omega, std::string type, int latticeNumber) { addFreeEnergyOutletBoundary(superGeometry.getMaterialIndicator(material), omega, type, latticeNumber); } template void sOnLatticeBoundaryCondition3D::addPoints2CommBC( FunctorPtr>&& indicator) { if (_overlap == 0) { return; } SuperGeometry3D& superGeometry = indicator->getSuperGeometry(); for (int iCloc = 0; iCloc < _sLattice.getLoadBalancer().size(); ++iCloc) { const int nX = superGeometry.getBlockGeometry(iCloc).getNx(); const int nY = superGeometry.getBlockGeometry(iCloc).getNy(); const int nZ = superGeometry.getBlockGeometry(iCloc).getNz(); for (int iX = -_overlap; iX < nX+_overlap; ++iX) { for (int iY = -_overlap; iY < nY+_overlap; ++iY) { for (int iZ = -_overlap; iZ < nZ+_overlap; ++iZ) { if (iX < 0 || iX > nX - 1 || iY < 0 || iY > nY - 1 || iZ < 0 || iZ > nZ - 1 ) { // if within overlap if (superGeometry.getBlockGeometry(iCloc).getMaterial(iX,iY,iZ) != 0) { bool found = false; for (int iXo = -_overlap; iXo <= _overlap && !found; ++iXo) { for (int iYo = -_overlap; iYo <= _overlap && !found; ++iYo) { for (int iZo = -_overlap; iZo <= _overlap && !found; ++iZo) { const int nextX = iXo + iX; const int nextY = iYo + iY; const int nextZ = iZo + iZ; if (indicator->getBlockIndicatorF(iCloc)(nextX, nextY, nextZ) && nextX >= -_overlap && nextX < nX+_overlap && nextY >= -_overlap && nextY < nY+_overlap && nextZ >= -_overlap && nextZ < nZ+_overlap) { _sLattice.get_commBC().add_cell(iCloc, iX, iY, iZ); found = true; } } } } } } } } } } } template void sOnLatticeBoundaryCondition3D::addPoints2CommBC(SuperGeometry3D& superGeometry, int material) { addPoints2CommBC(superGeometry.getMaterialIndicator(material)); } template SuperLattice3D& sOnLatticeBoundaryCondition3D::getSuperLattice() { return _sLattice; } template std::vector*>& sOnLatticeBoundaryCondition3D::getBlockBCs() { return _blockBCs; } template std::vector*>& sOnLatticeBoundaryCondition3D::getADblockBCs() { return _ADblockBCs; } template int sOnLatticeBoundaryCondition3D::getOverlap() { return _overlap; } template void sOnLatticeBoundaryCondition3D::setOverlap(int overlap) { _overlap = overlap; } //////////////// Output functions ////////////////////////////////// template void sOnLatticeBoundaryCondition3D::outputOn() { _output = true; int nC = _sLattice.getLoadBalancer().size(); for (int iCloc = 0; iCloc < nC; iCloc++) { _blockBCs[iCloc]->outputOn(); } } template void sOnLatticeBoundaryCondition3D::outputOff() { _output = false; int nC = _sLattice.getLoadBalancer().size(); for (int iCloc = 0; iCloc < nC; iCloc++) { _blockBCs[iCloc]->outputOff(); } } ////////////////// Factory functions ////////////////////////////////// template void createLocalBoundaryCondition3D(sOnLatticeBoundaryCondition3D& sBC) { int nC = sBC.getSuperLattice().getLoadBalancer().size(); sBC.setOverlap(0); for (int iC = 0; iC < nC; iC++) { OnLatticeBoundaryCondition3D* blockBC = createLocalBoundaryCondition3D( sBC.getSuperLattice().getExtendedBlockLattice(iC)); sBC.getBlockBCs().push_back(blockBC); } } template void createInterpBoundaryCondition3D(sOnLatticeBoundaryCondition3D& sBC) { int nC = sBC.getSuperLattice().getLoadBalancer().size(); sBC.setOverlap(1); for (int iC = 0; iC < nC; iC++) { OnLatticeBoundaryCondition3D* blockBC = createInterpBoundaryCondition3D( sBC.getSuperLattice().getExtendedBlockLattice(iC)); sBC.getBlockBCs().push_back(blockBC); } } template void createExtFdBoundaryCondition3D(sOnLatticeBoundaryCondition3D& sBC) { int nC = sBC.getSuperLattice().getLoadBalancer().size(); sBC.setOverlap(1); for (int iC = 0; iC < nC; iC++) { OnLatticeBoundaryCondition3D* blockBC = createExtendedFdBoundaryCondition3D( sBC.getSuperLattice().getExtendedBlockLattice(iC)); sBC.getBlockBCs().push_back(blockBC); } } } // namespace olb #endif