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/superGeometryStatistics2D.hh | 392 ++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 src/geometry/superGeometryStatistics2D.hh (limited to 'src/geometry/superGeometryStatistics2D.hh') diff --git a/src/geometry/superGeometryStatistics2D.hh b/src/geometry/superGeometryStatistics2D.hh new file mode 100644 index 0000000..b38c11d --- /dev/null +++ b/src/geometry/superGeometryStatistics2D.hh @@ -0,0 +1,392 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2013, 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 + * Representation of a statistic for a parallel 2D geometry -- generic implementation. + */ + +#include +#include +#include +#include + +#include "geometry/superGeometry2D.h" +#include "geometry/superGeometryStatistics2D.h" +#include "core/olbDebug.h" + +namespace olb { + +template +SuperGeometryStatistics2D::SuperGeometryStatistics2D(SuperGeometry2D* superGeometry) + : _superGeometry(superGeometry), _statisticsUpdateNeeded(true), _overlap(superGeometry->getOverlap()), clout(std::cout,"SuperGeometryStatistics2D") +{ +} + +template +SuperGeometryStatistics2D::SuperGeometryStatistics2D(SuperGeometryStatistics2D const& rhs) + : _superGeometry(rhs._superGeometry), _statisticsUpdateNeeded(true), _overlap(rhs._superGeometry->getOverlap() ), clout(std::cout,"SuperGeometryStatistics2D") +{ +} + +template +SuperGeometryStatistics2D& SuperGeometryStatistics2D::operator=(SuperGeometryStatistics2D const& rhs) +{ + _superGeometry = rhs._superGeometry; + _statisticsUpdateNeeded = true; + _overlap = rhs._overlap; + return *this; +} + + +template +bool& SuperGeometryStatistics2D::getStatisticsStatus() +{ + return _statisticsUpdateNeeded; +} + +template +bool const & SuperGeometryStatistics2D::getStatisticsStatus() const +{ + return _statisticsUpdateNeeded; +} + + +template +void SuperGeometryStatistics2D::update(bool verbose) +{ + +#ifdef PARALLEL_MODE_MPI + int updateReallyNeededGlobal = 0; + if (_statisticsUpdateNeeded ) { + updateReallyNeededGlobal = 1; + } + singleton::mpi().reduceAndBcast(updateReallyNeededGlobal, MPI_SUM); + if (updateReallyNeededGlobal>0) { + _statisticsUpdateNeeded = true; + } + //singleton::mpi().reduceAndBcast(_statisticsUpdateNeeded, MPI_LOR); +#endif + + // check if update is really needed + if (_statisticsUpdateNeeded ) { + int updateReallyNeeded = 0; + for (int iCloc=0; iCloc<_superGeometry->getLoadBalancer().size(); iCloc++) { + if (_superGeometry->getBlockGeometry(iCloc).getStatistics().getStatisticsStatus() ) { + _superGeometry->getBlockGeometry(iCloc).getStatistics().update(false); + updateReallyNeeded++; + } + } + + +#ifdef PARALLEL_MODE_MPI + singleton::mpi().reduceAndBcast(updateReallyNeeded, MPI_SUM); +#endif + + if (updateReallyNeeded==0) { + _statisticsUpdateNeeded = false; + // clout << "almost updated" << std::endl; + return; + } + + + // get total number of different materials right + _material2n = std::map(); + _nMaterials = int(); + for (int iCloc=0; iCloc<_superGeometry->getLoadBalancer().size(); iCloc++) { + if (_superGeometry->getBlockGeometry(iCloc).getStatistics(false).getNmaterials() > 0) { + _nMaterials = _superGeometry->getBlockGeometry(iCloc).getStatistics(false).getNmaterials(); + } + } + + +#ifdef PARALLEL_MODE_MPI + singleton::mpi().reduceAndBcast(_nMaterials, MPI_SUM); +#endif + + // store the number and min., max. possition for each rank + for (int iCloc=0; iCloc<_superGeometry->getLoadBalancer().size(); iCloc++) { + std::map material2n = _superGeometry->getBlockGeometry(iCloc).getStatistics(false).getMaterial2n(); + std::map::iterator iter; + + for (iter = material2n.begin(); iter != material2n.end(); iter++) { + if (iter->second!=0) { + std::vector minPhysR = _superGeometry->getBlockGeometry(iCloc).getStatistics(false).getMinPhysR(iter->first); + std::vector maxPhysR = _superGeometry->getBlockGeometry(iCloc).getStatistics(false).getMaxPhysR(iter->first); + if (_material2n.count(iter->first) == 0) { + _material2n[iter->first] = iter->second; + _material2min[iter->first] = minPhysR; + _material2max[iter->first] = maxPhysR; + //std::cout << iter->first<<":"<<_material2n[iter->first]<first] += iter->second; + for (int iDim=0; iDim<2; iDim++) { + if (_material2min[iter->first][iDim] > minPhysR[iDim]) { + _material2min[iter->first][iDim] = minPhysR[iDim]; + } + if (_material2max[iter->first][iDim] < maxPhysR[iDim]) { + _material2max[iter->first][iDim] = maxPhysR[iDim]; + } + } + //std::cout << iter->first<<":"<<_material2n[iter->first]<::iterator iMaterial; + for (iMaterial = _material2n.begin(); iMaterial != _material2n.end(); iMaterial++) { + materials[counter] = iMaterial->first; + materialCount[counter] = iMaterial->second; + for (int iDim=0; iDim<2; iDim++) { + materialMinR[2*counter + iDim] = _material2min[iMaterial->first][iDim]; + materialMaxR[2*counter + iDim] = _material2max[iMaterial->first][iDim]; + } + counter++; + } + + for (int iRank=1; iRank minPhysR(2,T()); + std::vector maxPhysR(2,T()); + for (int iDim=0; iDim<2; iDim++) { + minPhysR[iDim] = materialMinRinBuf[2*iM + iDim]; + maxPhysR[iDim] = materialMaxRinBuf[2*iM + iDim]; + } + if (_material2n.count(materialsInBuf[iM]) == 0) { + _material2n[materialsInBuf[iM]] = materialCountInBuf[iM]; + _material2min[materialsInBuf[iM]] = minPhysR; + _material2max[materialsInBuf[iM]] = maxPhysR; + } else { + _material2n[materialsInBuf[iM]] += materialCountInBuf[iM]; + for (int iDim=0; iDim<2; iDim++) { + if (_material2min[materialsInBuf[iM]][iDim] > minPhysR[iDim]) { + _material2min[materialsInBuf[iM]][iDim] = minPhysR[iDim]; + } + if (_material2max[materialsInBuf[iM]][iDim] < maxPhysR[iDim]) { + _material2max[materialsInBuf[iM]][iDim] = maxPhysR[iDim]; + } + } + } + } + } + } +#endif + + //clout.setMultiOutput(true); + //print(); + //clout.setMultiOutput(false); + + if (verbose) { + clout << "updated" << std::endl; + } + _statisticsUpdateNeeded = false; + } +} + +template +int SuperGeometryStatistics2D::getNmaterials() +{ + update(); + return _nMaterials; +} + +template +int SuperGeometryStatistics2D::getNvoxel(int material) +{ + update(true); + return _material2n[material]; +} + +template +int SuperGeometryStatistics2D::getNvoxel() +{ + update(); + int total = 0; + std::map::iterator iter; + for (iter = _material2n.begin(); iter != _material2n.end(); iter++) { + if (iter->first!=0) { + total+=iter->second; + } + } + return total; +} + +template +std::vector SuperGeometryStatistics2D::getMinPhysR(int material) +{ + update(); + return _material2min[material]; +} + +template +std::vector SuperGeometryStatistics2D::getMaxPhysR(int material) +{ + update(); + return _material2max[material]; +} + +template +std::vector SuperGeometryStatistics2D::getPhysExtend(int material) +{ + update(); + std::vector extend; + for (int iDim = 0; iDim < 2; iDim++) { + extend.push_back(_material2max[material][iDim] - _material2min[material][iDim]); + } + return extend; +} + +template +std::vector SuperGeometryStatistics2D::getPhysRadius(int material) +{ + update(); + std::vector radius; + for (int iDim=0; iDim<2; iDim++) { + radius.push_back((getMaxPhysR(material)[iDim] - getMinPhysR(material)[iDim])/2.); + } + return radius; +} + +template +std::vector SuperGeometryStatistics2D::getCenterPhysR(int material) +{ + update(); + std::vector center; + for (int iDim=0; iDim<2; iDim++) { + center.push_back(getMinPhysR(material)[iDim] + getPhysRadius(material)[iDim]); + } + return center; +} + +template +std::vector SuperGeometryStatistics2D::getType(int iC, int iX, int iY) +{ + update(); + int iCloc=_superGeometry->getLoadBalancer().loc(iC); + std::vector discreteNormal = _superGeometry->getExtendedBlockGeometry(iCloc).getStatistics(false).getType(iX+_overlap, iY+_overlap); + return discreteNormal; +} + +template +std::vector SuperGeometryStatistics2D::computeNormal(int material) +{ + update(); + + std::vector normal (2,int()); + for (int iCloc=0; iCloc<_superGeometry->getLoadBalancer().size(); iCloc++) { + for (int iDim=0; iDim<2; iDim++) { + if (_superGeometry->getBlockGeometry(iCloc).getStatistics(false).getNvoxel(material)!=0) { + normal[iDim] += _superGeometry->getBlockGeometry(iCloc).getStatistics(false).computeNormal(material)[iDim]*_superGeometry->getBlockGeometry(iCloc).getStatistics(false).getNvoxel(material); + } + } + } + +#ifdef PARALLEL_MODE_MPI + for (int iDim=0; iDim<2; iDim++) { + singleton::mpi().reduceAndBcast((normal[iDim]), MPI_SUM); + } +#endif + + int nVoxel = getNvoxel(material); + if (nVoxel != 0) { + for (int iDim=0; iDim<2; iDim++) { + normal[iDim] /= nVoxel; + } + } + OLB_ASSERT(nVoxel || (normal[0] == 0 && normal[1] == 0), "if no voxels found we expect the normal to be zero"); + + T norm = sqrt(normal[0]*normal[0]+normal[1]*normal[1]); + if (norm>0.) { + normal[0]/=norm; + normal[1]/=norm; + } + return normal; +} + +template +std::vector SuperGeometryStatistics2D::computeDiscreteNormal(int material, T maxNorm) +{ + update(); + std::vector normal = computeNormal(material); + std::vector discreteNormal(2,int(0)); + + T smallestAngle = T(0); + for (int iX = -1; iX<=1; iX++) { + for (int iY = -1; iY<=1; iY++) { + T norm = sqrt(iX*iX+iY*iY); + if (norm>0.&& norm=smallestAngle) { + smallestAngle=angle; + discreteNormal[0] = iX; + discreteNormal[1] = iY; + } + } + } + } + return discreteNormal; +} + + +template +void SuperGeometryStatistics2D::print() +{ + update(); + std::map::iterator iter; + for (iter = _material2n.begin(); iter != _material2n.end(); iter++) { + clout << "materialNumber=" << iter->first + << "; count=" << iter->second + << "; minPhysR=(" << _material2min[iter->first][0] <<","<< _material2min[iter->first][1] <<")" + << "; maxPhysR=(" << _material2max[iter->first][0] <<","<< _material2max[iter->first][1] <<")" + << std::endl; + } +} + + +} // namespace olb -- cgit v1.2.3