/* 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 * The description of a 2D super lattice -- generic implementation. */ #ifndef SUPER_LATTICE_2D_HH #define SUPER_LATTICE_2D_HH #include #include #include "communication/mpiManager.h" #include "blockLattice2D.h" #include "cell.h" #include "geometry/cuboidGeometry2D.h" #include "geometry/superGeometry2D.h" #include "communication/loadBalancer.h" #include "superLattice2D.h" #include "io/base64.h" #include "functors/lattice/superBaseF2D.h" #include "functors/lattice/indicator/superIndicatorF2D.h" #include "io/serializerIO.h" namespace olb { template SuperLattice2D::SuperLattice2D(SuperGeometry2D& superGeometry, int overlapRefinement) : SuperStructure2D(superGeometry.getCuboidGeometry(), superGeometry.getLoadBalancer()), _overlapRefinement(overlapRefinement), _commStream(*this), _commBC(*this) { int overlapBC = superGeometry.getOverlap(); if (overlapBC >= 1) { _commBC_on = true; this->_overlap = overlapBC; } else { _commBC_on = false; this->_overlap = 1; } _commStream.init_nh(); _commStream.add_cells(1); _commStream.init(); this->_communicator.init_nh(); this->_communicator.add_cells(this->_overlap); this->_communicator.init(); _extendedBlockLattices.reserve(this->_loadBalancer.size()); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { int nX = this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).getNx() + 2 * this->_overlap; int nY = this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).getNy() + 2 * this->_overlap; _extendedBlockLattices.emplace_back(nX, nY); } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { BlockLatticeView2D lattice(_extendedBlockLattices[iC], this->_overlap, _extendedBlockLattices[iC].getNx() - this->_overlap - 1, this->_overlap, _extendedBlockLattices[iC].getNy() - this->_overlap - 1); _blockLattices.push_back(lattice); } _statistics = new LatticeStatistics ; _statistics_on = true; if (_commBC_on) { _commBC.init_nh(); } this->_communicationNeeded=true; } template SuperLattice2D::~SuperLattice2D () { delete _statistics; } template bool SuperLattice2D::set(T iX, T iY, Cell const& cell) { bool found = false; int locX, locY; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkPoint(iX, iY, locX, locY, this->_overlap)) { _extendedBlockLattices[iC].get(locX,locY) = cell; found = true; } } return found; } template void SuperLattice2D::set(Vector pos, const Cell& cell) { #ifdef PARALLEL_MODE_MPI if (this->_loadBalancer.isLocal(pos[0])) { _blockLattices[this->_loadBalancer.loc(pos[0])].get(pos[1],pos[2]) = cell; } #else _blockLattices[this->_loadBalancer.loc(pos[0])].get(pos[1],pos[2]) = cell; #endif } template void SuperLattice2D::get(Vector pos, Cell& cell) const { #ifdef PARALLEL_MODE_MPI const int sizeOfCell = DESCRIPTOR::size(); T* cellData = new T[sizeOfCell]; if (this->_loadBalancer.isLocal(pos[0])) { _blockLattices[this->_loadBalancer.loc(pos[0])].get(pos[1],pos[2]).serialize(cellData); } singleton::mpi().bCast(cellData, sizeOfCell, this->_loadBalancer.rank(pos[0])); if (!this->_loadBalancer.isLocal(pos[0])) { cell.unSerialize(cellData); } else { cell = _blockLattices[this->_loadBalancer.loc(pos[0])].get(pos[1],pos[2]); } delete [] cellData; #else cell = _blockLattices[this->_loadBalancer.loc(pos[0])].get(pos[1],pos[2]); #endif } template bool SuperLattice2D::get(T iX, T iY, Cell& cell) const { int locX, locY; bool found = false; int foundIC = 0; for (int iC=0; iC_cuboidGeometry.getNc(); ++iC) { if (this->_cuboidGeometry.get(iC).checkPoint(iX, iY, locX, locY)) { found = true; foundIC = iC; break; } } #ifdef PARALLEL_MODE_MPI const int sizeOfCell = DESCRIPTOR::size(); T* cellData = new T[sizeOfCell]; if (found) { if (this->_loadBalancer.rank(foundIC)==singleton::mpi().getRank()) { _blockLattices[this->_loadBalancer.loc(foundIC)].get(locX,locY).serialize(cellData); } singleton::mpi().bCast(cellData, sizeOfCell, this->_loadBalancer.rank(foundIC)); cell.unSerialize(cellData); delete [] cellData; } #else if (found) { cell = _blockLattices[this->_loadBalancer.loc(foundIC)].get(locX,locY); } #endif return found; } template Cell SuperLattice2D::get(int iC, int locX, int locY) const { Cell cell; #ifdef PARALLEL_MODE_MPI const int sizeOfCell = DESCRIPTOR::size(); T* cellData = new T[sizeOfCell]; if (this->_loadBalancer.rank(iC)==singleton::mpi().getRank()) { _blockLattices[this->_loadBalancer.loc(iC)].get(locX,locY).serialize(cellData); } singleton::mpi().bCast(cellData, sizeOfCell, this->_loadBalancer.rank(iC)); cell.unSerialize(cellData); delete [] cellData; #else cell = _blockLattices[this->_loadBalancer.loc(iC)].get(locX,locY); #endif return cell; } template void SuperLattice2D::initialize() { if (_commBC_on) { _commBC.init(); } for (int iC=0; iC_loadBalancer.size(); ++iC) { //AENDERN VON INI in BLOCKLATTICEVIEW!!!! //_blockLattices[iC].initialize(); _blockLattices[iC].postProcess(); } } template void SuperLattice2D::defineDynamics( FunctorPtr>&& indicator, Dynamics* dynamics) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineDynamics( indicator->getExtendedBlockIndicatorF(iC), dynamics); } } template void SuperLattice2D::defineDynamics( SuperGeometry2D& superGeometry, int material, Dynamics* dynamics) { defineDynamics(superGeometry.getMaterialIndicator(material), dynamics); } template void SuperLattice2D::defineRhoU(T x0, T x1, T y0, T y1, T rho, const T u[DESCRIPTOR::d] ) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { for (int iX=locX0; iX<=locX1; ++iX) { for (int iY=locY0; iY<=locY1; ++iY) { _extendedBlockLattices[iC].get(iX,iY).defineRhoU(rho, u); } } } } } template void SuperLattice2D::defineRhoU(FunctorPtr>&& indicator, AnalyticalF2D& rho, AnalyticalF2D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineRhoU(indicator->getExtendedBlockIndicatorF(iC), rho, u); } } template void SuperLattice2D::defineRhoU(SuperGeometry2D& sGeometry, int material, AnalyticalF2D& rho, AnalyticalF2D& u) { defineRhoU(sGeometry.getMaterialIndicator(material), rho, u); } template void SuperLattice2D::defineRho ( T x0, T x1, T y0, T y1, T rho ) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters( x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { for (int iX=locX0; iX<=locX1; ++iX) { for (int iY=locY0; iY<=locY1; ++iY) { _extendedBlockLattices[iC].get(iX,iY).defineRho(rho); } } } } } template void SuperLattice2D::defineRho( FunctorPtr>&& indicator, AnalyticalF2D& rho) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineRho(indicator->getExtendedBlockIndicatorF(iC), rho); } } template void SuperLattice2D::defineRho( SuperGeometry2D& sGeometry, int material, AnalyticalF2D& rho) { defineRho(sGeometry.getMaterialIndicator(material), rho); } template void SuperLattice2D::defineU( T x0, T x1, T y0, T y1, const T u[DESCRIPTOR::d] ) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters( x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { for (int iX=locX0; iX<=locX1; ++iX) { for (int iY=locY0; iY<=locY1; ++iY) { _extendedBlockLattices[iC].get(iX,iY).defineU(u); } } } } } template void SuperLattice2D::defineU( FunctorPtr>&& indicator, AnalyticalF2D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineU(indicator->getExtendedBlockIndicatorF(iC), u); } } template void SuperLattice2D::defineU(SuperGeometry2D& sGeometry, int material, AnalyticalF2D& u) { defineU(sGeometry.getMaterialIndicator(material), u); } template void SuperLattice2D::definePopulations( FunctorPtr>&& indicator, AnalyticalF2D& Pop) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].definePopulations( indicator->getExtendedBlockIndicatorF(iC), Pop); } } template void SuperLattice2D::definePopulations(SuperGeometry2D& sGeometry, int material, AnalyticalF2D& Pop) { definePopulations(sGeometry.getMaterialIndicator(material), Pop); } template template void SuperLattice2D::defineField( T x0, T x1, T y0, T y1, T* field ) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { for (int iX=locX0; iX<=locX1; ++iX) { for (int iY=locY0; iY<=locY1; ++iY) { _extendedBlockLattices[iC].get(iX,iY).template defineField(field); } } } } } template template void SuperLattice2D::defineField( FunctorPtr>&& indicator, SuperLatticeF2D& field) { const int overlap = indicator->getSuperGeometry().getOverlap(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { BlockIndicatorF2D& blockIndicator = indicator->getExtendedBlockIndicatorF(iC); if ( !blockIndicator.isEmpty() ) { const Vector min = blockIndicator.getMin(); const Vector max = blockIndicator.getMax(); for (int iX = min[0]; iX <= max[0]; ++iX) { for (int iY = min[1]; iY <= max[1]; ++iY) { if (blockIndicator(iX,iY)) { T fieldTmp[DESCRIPTOR::template size()]; int inputTmp[3]= { this->_loadBalancer.glob(iC), iX-overlap, iY-overlap }; field(fieldTmp,inputTmp); _extendedBlockLattices[iC].get(iX,iY).template defineField(fieldTmp); } } } } } } template template void SuperLattice2D::defineField( SuperGeometry2D& sGeometry, int material, SuperLatticeF2D& field) { defineField(sGeometry.getMaterialIndicator(material), field); } template template void SuperLattice2D::defineField(SuperGeometry2D& sGeometry, IndicatorF2D& indicator, AnalyticalF2D& field) { SuperIndicatorFfromIndicatorF2D indicatorF(indicator, sGeometry); defineField(indicatorF, field); } #ifndef OLB_PRECOMPILED template void SuperLattice2D::setExternalParticleField(SuperGeometry2D& sGeometry, AnalyticalF2D& velocity, SmoothIndicatorF2D& sIndicator) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].setExternalParticleField(sGeometry.getExtendedBlockGeometry(iC), velocity, sIndicator); } } #endif template template void SuperLattice2D::addField(SuperGeometry2D& sGeometry, IndicatorF2D& indicator, AnalyticalF2D& field) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].template addField(sGeometry.getExtendedBlockGeometry(iC), indicator, field); } } template template void SuperLattice2D::addField( SuperGeometry2D& sGeometry, IndicatorF2D& indicator, AnalyticalF2D& field, AnalyticalF2D& porous) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].template addField(sGeometry.getExtendedBlockGeometry(iC), indicator, field, porous); } } template template void SuperLattice2D::multiplyField(SuperGeometry2D& sGeometry, IndicatorF2D& indicator, AnalyticalF2D& field) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].template multiplyField(sGeometry.getExtendedBlockGeometry(iC), indicator, field); } } template void SuperLattice2D::iniEquilibrium ( T x0, T x1, T y0, T y1, T rho, const T u[DESCRIPTOR::d] ) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { for (int iX=locX0; iX<=locX1; ++iX) { for (int iY=locY0; iY<=locY1; ++iY) { _extendedBlockLattices[iC].get(iX,iY).iniEquilibrium(rho, u); } } } } } template void SuperLattice2D::iniEquilibrium( FunctorPtr>&& indicator, AnalyticalF2D& rho, AnalyticalF2D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].iniEquilibrium( indicator->getExtendedBlockIndicatorF(iC), rho, u); } } template void SuperLattice2D::iniEquilibrium( SuperGeometry2D& sGeometry, int material, AnalyticalF2D& rho, AnalyticalF2D& u) { iniEquilibrium(sGeometry.getMaterialIndicator(material), rho, u); } template void SuperLattice2D::collide () { for (int iC=0; iC_loadBalancer.size(); ++iC) { _blockLattices[iC].collide(); } this->_communicationNeeded=true; } template void SuperLattice2D::collide (T x0, T x1, T y0, T y1) { int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { _blockLattices[iC].collide(locX0, locX1, locY0, locY1); } } this->_communicationNeeded=true; } template void SuperLattice2D::stream () { _commStream.send(); _commStream.receive(); _commStream.write(); for (int iC=0; iC_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].stream(this->_overlap-1, _extendedBlockLattices[iC].getNx() - this->_overlap, this->_overlap-1, _extendedBlockLattices[iC].getNy() - this->_overlap); } if (_commBC_on) { //_commBC.send(); //_commBC.receive(); //_commBC.write(); _commStream.send(); _commStream.receive(); _commStream.write(); } for (int iC=0; iC_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded=true; } template void SuperLattice2D::stream (T x0, T x1, T y0, T y1) { _commStream.send(); _commStream.receive(); _commStream.write(); int locX0, locX1, locY0, locY1; for (int iC=0; iC_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { _extendedBlockLattices[iC].stream(locX0, locX1, locY0, locY1); } } if (_commBC_on) { //_commBC.send(); //_commBC.receive(); //_commBC.write(); _commStream.send(); _commStream.receive(); _commStream.write(); } for (int iC=0; iC_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded=true; } template void SuperLattice2D::collideAndStream () { for (int iC=0; iC_loadBalancer.size(); ++iC) { int x1 = _blockLattices[iC].getNx() - 1; int y1 = _blockLattices[iC].getNy() - 1; _blockLattices[iC].collide(0,x1,0,0); _blockLattices[iC].collide(0,x1,y1,y1); if (y1>1) { _blockLattices[iC].collide(0,0,1,y1-1); _blockLattices[iC].collide(x1,x1,1,y1-1); } } for (int iC=0; iC_loadBalancer.size(); ++iC) { if (2*this->_overlap + 2 < _extendedBlockLattices[iC].getNx() && 2*this->_overlap + 2 < _extendedBlockLattices[iC].getNy() ) _extendedBlockLattices[iC].bulkCollideAndStream(this->_overlap+1, _extendedBlockLattices[iC].getNx() - this->_overlap-2, this->_overlap+1, _extendedBlockLattices[iC].getNy() - this->_overlap-2); } _commStream.send(); _commStream.receive(); _commStream.write(); for (int iC=0; iC_loadBalancer.size(); ++iC) { int x1 = _extendedBlockLattices[iC].getNx() - 1; int y1 = _extendedBlockLattices[iC].getNy() - 1; if (2*this->_overlap-3_overlap-1,x1-this->_overlap+1, this->_overlap-1,this->_overlap); _extendedBlockLattices[iC].boundaryStream(0,x1,0,y1, this->_overlap-1,x1-this->_overlap+1, y1-this->_overlap,y1-this->_overlap+1); } if (2*this->_overlap+1_overlap-1, this->_overlap, this->_overlap+1, y1-this->_overlap-1); _extendedBlockLattices[iC].boundaryStream(0,x1,0,y1, x1-this->_overlap,x1-this->_overlap+1, this->_overlap+1, y1-this->_overlap-1); } } if (_commBC_on) { _commStream.send(); _commStream.receive(); _commStream.write(); //_commBC.send(); //_commBC.receive(); //_commBC.write(); } for (int iC=0; iC_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded=true; } template void SuperLattice2D::stripeOffDensityOffset ( int x0, int x1, int y0, int y1, T offset ) { int locX0, locX1, locY0, locY1; for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, locX0, locX1, locY0, locY1, this->_overlap)) { _extendedBlockLattices[iC].stripeOffDensityOffset(locX0, locX1, locY0, locY1, offset); } } this->_communicationNeeded=true; } template void SuperLattice2D::stripeOffDensityOffset(T offset) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].stripeOffDensityOffset(offset); } } template template void SuperLattice2D::addLatticeCoupling( LatticeCouplingGenerator2D const& lcGen, SuperLattice2D& partnerLattice) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector< SpatiallyExtendedObject2D* > partnerOne; partnerOne.push_back(&partnerLattice.getExtendedBlockLattice(iC)); int nx = getExtendedBlockLattice(iC).getNx(); int ny = getExtendedBlockLattice(iC).getNy(); LatticeCouplingGenerator2D *extractedLcGen = lcGen.clone(); extractedLcGen->reset(1, nx-2, 1, ny-2); getExtendedBlockLattice(iC).addLatticeCoupling(*extractedLcGen, partnerOne); delete extractedLcGen; } return; } template template void SuperLattice2D::addLatticeCoupling( FunctorPtr>&& indicator, LatticeCouplingGenerator2D const& lcGen, SuperLattice2D& partnerLattice) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector partnerOne; partnerOne.push_back(&partnerLattice.getExtendedBlockLattice(iC)); for (int iX = 1; iX < _extendedBlockLattices[iC].getNx()-1; ++iX) { for (int iY = 1; iY < _extendedBlockLattices[iC].getNy()-1; ++iY) { std::unique_ptr> extractedLcGen{ lcGen.clone() }; //TODO done quick and dirty if (extractedLcGen->extract(0, 0, 0, 0) ) { if (indicator->getExtendedBlockIndicatorF(iC)(iX, iY)) { extractedLcGen->shift(iX, iY); _extendedBlockLattices[iC].addLatticeCoupling(*extractedLcGen, partnerOne); } } } } } this->_communicationNeeded = true; } template template void SuperLattice2D::addLatticeCoupling( SuperGeometry2D& sGeometry, int material, LatticeCouplingGenerator2D const& lcGen, SuperLattice2D& partnerLattice) { addLatticeCoupling(sGeometry.getMaterialIndicator(material), lcGen, partnerLattice); } template template void SuperLattice2D::addLatticeCoupling( LatticeCouplingGenerator2D const& lcGen, std::vector*> partnerLattices) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector< SpatiallyExtendedObject2D* > partners; for (auto partnerLattice: partnerLattices) { partners.push_back(&partnerLattice->getExtendedBlockLattice(iC)); } int nx = getExtendedBlockLattice(iC).getNx(); int ny = getExtendedBlockLattice(iC).getNy(); LatticeCouplingGenerator2D *extractedLcGen = lcGen.clone(); extractedLcGen->reset(1, nx-2, 1, ny-2); getExtendedBlockLattice(iC).addLatticeCoupling(*extractedLcGen, partners); delete extractedLcGen; } return; } template template void SuperLattice2D::addLatticeCoupling( FunctorPtr>&& indicator, LatticeCouplingGenerator2D const& lcGen, std::vector*> partnerLattices) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector partners; for (auto partnerLattice: partnerLattices) { partners.push_back(&partnerLattice->getExtendedBlockLattice(iC)); } for (int iX = 1; iX < _extendedBlockLattices[iC].getNx()-1; ++iX) { for (int iY = 1; iY < _extendedBlockLattices[iC].getNy()-1; ++iY) { std::unique_ptr> extractedLcGen{ lcGen.clone() }; //TODO done quick and dirty if (extractedLcGen->extract(0, 0, 0, 0) ) { if (indicator->getExtendedBlockIndicatorF(iC)(iX, iY)) { extractedLcGen->shift(iX, iY); _extendedBlockLattices[iC].addLatticeCoupling(*extractedLcGen, partners); } } } } } this->_communicationNeeded = true; } template template void SuperLattice2D::addLatticeCoupling( SuperGeometry2D& sGeometry, int material, LatticeCouplingGenerator2D const& lcGen, std::vector*> partnerLattices) { addLatticeCoupling(sGeometry.getMaterialIndicator(material), lcGen, partnerLattices); } template void SuperLattice2D::executeCoupling() { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].executeCoupling(); } this->_communicationNeeded = true; return; } template std::size_t SuperLattice2D::getNblock() const { return std::accumulate(_extendedBlockLattices.begin(), _extendedBlockLattices.end(), size_t(0), Serializable::sumNblock()); } template std::size_t SuperLattice2D::getSerializableSize() const { return std::accumulate(_extendedBlockLattices.begin(), _extendedBlockLattices.end(), size_t(0), Serializable::sumSerializableSize()); } template bool* SuperLattice2D::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) { std::size_t currentBlock = 0; bool* dataPtr = nullptr; // NOTE: _extendedBlockLattices is correctly sized after constructing SuperLattice, so no resize should be done! for ( auto& bLattice : _extendedBlockLattices ) { registerSerializableOfConstSize(iBlock, sizeBlock, currentBlock, dataPtr, bLattice, loadingMode); } return dataPtr; } template void SuperLattice2D::reset_statistics () { T weight; T sum_weight = 0; T average_rho = 0; T average_energy = 0; T maxU = 0; T delta = 0; getStatistics().reset(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { delta = this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).getDeltaR(); weight = _extendedBlockLattices[iC].getStatistics().getNumCells() * delta * delta * delta; sum_weight += weight; average_rho += _extendedBlockLattices[iC].getStatistics().getAverageRho() * weight; average_energy += _extendedBlockLattices[iC].getStatistics().getAverageEnergy() * weight; if (maxU < _extendedBlockLattices[iC].getStatistics().getMaxU()) { maxU = _extendedBlockLattices[iC].getStatistics().getMaxU(); } } #ifdef PARALLEL_MODE_MPI singleton::mpi().reduceAndBcast(sum_weight, MPI_SUM); singleton::mpi().reduceAndBcast(average_rho, MPI_SUM); singleton::mpi().reduceAndBcast(average_energy, MPI_SUM); singleton::mpi().reduceAndBcast(maxU, MPI_MAX); #endif average_rho = average_rho / sum_weight; average_energy = average_energy / sum_weight; getStatistics().reset(average_rho, average_energy, maxU, (int) sum_weight); getStatistics().incrementTime(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { delta = this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).getDeltaR(); _extendedBlockLattices[iC].getStatistics().reset(average_rho, average_energy, maxU, (int) sum_weight); _extendedBlockLattices[iC].getStatistics().incrementTime(); } } template LatticeStatistics& SuperLattice2D::getStatistics() { return *_statistics; } template LatticeStatistics const& SuperLattice2D::getStatistics() const { return *_statistics; } /* template void SuperLattice2D::communicate(bool verbose) { _commStream.send(); _commStream.receive(); _commStream.write(); }*/ } // namespace olb #endif