/* 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 BLOCK_INDICATOR_F_3D_HH #define BLOCK_INDICATOR_F_3D_HH #include #include "blockIndicatorF3D.h" #include "core/util.h" namespace olb { template BlockIndicatorFfromIndicatorF3D::BlockIndicatorFfromIndicatorF3D( IndicatorF3D& indicatorF, BlockGeometryStructure3D& blockGeometry) : BlockIndicatorF3D(blockGeometry), _indicatorF(indicatorF) { } template bool BlockIndicatorFfromIndicatorF3D::operator() (bool output[], const int input[]) { T physR[3]; this->_blockGeometryStructure.getPhysR(physR,input); return _indicatorF(output,physR); } template Vector BlockIndicatorFfromIndicatorF3D::getMin() { const Vector min = _indicatorF.getMin(); return Vector { static_cast(floor(min[0])), static_cast(floor(min[1])), static_cast(floor(min[2])) }; } template Vector BlockIndicatorFfromIndicatorF3D::getMax() { const Vector max = _indicatorF.getMax(); return Vector { static_cast(ceil(max[0])), static_cast(ceil(max[1])), static_cast(ceil(max[2])) }; } template BlockIndicatorFfromSmoothIndicatorF3D::BlockIndicatorFfromSmoothIndicatorF3D( SmoothIndicatorF3D& indicatorF, BlockGeometryStructure3D& blockGeometry) : BlockIndicatorF3D(blockGeometry), _indicatorF(indicatorF) { } template bool BlockIndicatorFfromSmoothIndicatorF3D::operator() (bool output[], const int input[]) { T physR[3]; T inside[1]; this->_blockGeometryStructure.getPhysR(physR,input); _indicatorF(inside, physR); return !util::nearZero(inside[0]); } template Vector BlockIndicatorFfromSmoothIndicatorF3D::getMin() { const T min = -_indicatorF.getCircumRadius(); return Vector { static_cast(floor(min)), static_cast(floor(min)), static_cast(floor(min)) }; } template Vector BlockIndicatorFfromSmoothIndicatorF3D::getMax() { const T max = _indicatorF.getCircumRadius(); return Vector { static_cast(ceil(max)), static_cast(ceil(max)), static_cast(ceil(max)) }; } template BlockIndicatorMaterial3D::BlockIndicatorMaterial3D( BlockGeometryStructure3D& blockGeometry, std::vector materials) : BlockIndicatorF3D(blockGeometry), _materials(materials) { } template BlockIndicatorMaterial3D::BlockIndicatorMaterial3D( BlockGeometryStructure3D& blockGeometry, std::list materials) : BlockIndicatorMaterial3D(blockGeometry, std::vector(materials.begin(), materials.end())) { } template BlockIndicatorMaterial3D::BlockIndicatorMaterial3D( BlockGeometryStructure3D& blockGeometry, int material) : BlockIndicatorMaterial3D(blockGeometry, std::vector(1,material)) { } template bool BlockIndicatorMaterial3D::operator() (bool output[], const int input[]) { // read material number explicitly using the const version // of BlockGeometry3D::get to avoid resetting geometry // statistics: const BlockGeometryStructure3D& blockGeometry = this->_blockGeometryStructure; const int current = blockGeometry.get(input[0], input[1], input[2]); output[0] = std::any_of(_materials.cbegin(), _materials.cend(), [current](int material) { return current == material; }); return true; } template bool BlockIndicatorMaterial3D::isEmpty() { auto& statistics = this->getBlockGeometryStructure().getStatistics(); return std::none_of(_materials.cbegin(), _materials.cend(), [&statistics](int material) -> bool { return statistics.getNvoxel(material) > 0; }); } template Vector BlockIndicatorMaterial3D::getMin() { auto& blockGeometry = this->getBlockGeometryStructure(); auto& statistics = blockGeometry.getStatistics(); Vector globalMin{ blockGeometry.getNx()-1, blockGeometry.getNy()-1, blockGeometry.getNz()-1, }; for ( int material : _materials ) { if ( statistics.getNvoxel(material) > 0 ) { const Vector localMin = statistics.getMinLatticeR(material); for ( int d = 0; d < 3; ++d ) { globalMin[d] = localMin[d] < globalMin[d] ? localMin[d] : globalMin[d]; } } } return globalMin; } template Vector BlockIndicatorMaterial3D::getMax() { auto& statistics = this->getBlockGeometryStructure().getStatistics(); Vector globalMax{ 0, 0, 0 }; for ( int material : _materials ) { if ( statistics.getNvoxel(material) > 0 ) { const Vector localMax = statistics.getMaxLatticeR(material); for ( int d = 0; d < 3; ++d ) { globalMax[d] = localMax[d] > globalMax[d] ? localMax[d] : globalMax[d]; } } } return globalMax; } template BlockIndicatorIdentity3D::BlockIndicatorIdentity3D(BlockIndicatorF3D& indicatorF) : BlockIndicatorF3D(indicatorF.getBlockGeometryStructure()), _indicatorF(indicatorF) { } template bool BlockIndicatorIdentity3D::operator() (bool output[], const int input[]) { return _indicatorF(output, input); } template Vector BlockIndicatorIdentity3D::getMin() { return _indicatorF.getMin(); } template Vector BlockIndicatorIdentity3D::getMax() { return _indicatorF.getMax(); } } // namespace olb #endif