/* 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 3D super lattice -- generic implementation. */ #ifndef SUPER_LATTICE_3D_HH #define SUPER_LATTICE_3D_HH #include #include #include "communication/mpiManager.h" #include "cell.h" #include "superLattice3D.h" #include "io/base64.h" #include "functors/analytical/analyticalF.h" #include "functors/lattice/superBaseF3D.h" #include "functors/lattice/indicator/superIndicatorF3D.h" #include "io/serializerIO.h" #include "geometry/superGeometry3D.h" #include "communication/loadBalancer.h" #include "geometry/cuboidGeometry3D.h" namespace olb { ////////////////////// Class SuperLattice3D ///////////////////////// template SuperLattice3D::SuperLattice3D(SuperGeometry3D& superGeometry) : SuperStructure3D(superGeometry.getCuboidGeometry(), superGeometry.getLoadBalancer()), _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; int nZ = this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).getNz() + 2 * this->_overlap; _extendedBlockLattices.emplace_back(nX, nY, nZ, superGeometry.getExtendedBlockGeometry(iC)); } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _blockLattices.emplace_back( _extendedBlockLattices[iC], this->_overlap, _extendedBlockLattices[iC].getNx() - this->_overlap - 1, this->_overlap, _extendedBlockLattices[iC].getNy() - this->_overlap - 1, this->_overlap, _extendedBlockLattices[iC].getNz() - this->_overlap - 1 ); } _statistics = new LatticeStatistics ; _statistics_on = true; if (_commBC_on) { _commBC.init_nh(); } this->_communicationNeeded=true; } template SuperLattice3D::~SuperLattice3D () { delete _statistics; } template bool SuperLattice3D::set(T iX, T iY, T iZ, Cell const& cell) { bool found = false; int locX, locY, locZ; for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkPoint(iX, iY, iZ, locX, locY, locZ, this->_overlap)) { _extendedBlockLattices[iC].get(locX, locY, locZ) = cell; found = true; } } this->_communicationNeeded = true; return found; } // Note: The dynamics of the cell are not communicated here template bool SuperLattice3D::get(T iX, T iY, T iZ, Cell& cell) const { int locX = 0; int locY = 0; int locZ = 0; bool found = false; int foundIC = 0; T physR[] = {iX, iY, iZ}; int latticeR[4]; if (this->_cuboidGeometry.getLatticeR(latticeR,physR) ) { found = true; foundIC = latticeR[0]; locX = latticeR[1]; locY = latticeR[2]; locZ = latticeR[3]; } /*for (int iC = 0; iC < this->_cuboidGeometry.getNc(); ++iC) { if (this->_cuboidGeometry.get(iC).checkPoint(iX, iY, iZ, locX, locY, locZ)) { found = true; foundIC = iC; } }*/ #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,locZ).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, locZ); } #endif return found; } template Cell SuperLattice3D::get(int iC, int locX, int locY, int locZ) 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,locZ).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,locZ); #endif return cell; } template Cell SuperLattice3D::get(std::vector latticeR) const { return _blockLattices[this->_loadBalancer.loc(latticeR[0])].get(latticeR[1],latticeR[2],latticeR[3]); } template void SuperLattice3D::initialize() { if (_commBC_on) { _commBC.init(); } //reset_statistics(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { //AENDERN VON INI in BLOCKLATTICEVIEW!!!! //_blockLattices[iC].initialize(); _blockLattices[iC].postProcess(); } this->_communicationNeeded = true; } template void SuperLattice3D::defineDynamics( FunctorPtr>&& indicator, Dynamics* dynamics) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineDynamics( indicator->getExtendedBlockIndicatorF(iC), dynamics); } } template void SuperLattice3D::defineDynamics( SuperGeometry3D& sGeometry, int material, Dynamics* dynamics) { defineDynamics(sGeometry.getMaterialIndicator(material), dynamics); } template void SuperLattice3D::defineRho( FunctorPtr>&& indicator, AnalyticalF3D& rho) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineRho(indicator->getExtendedBlockIndicatorF(iC), rho); } } template void SuperLattice3D::defineRho( SuperGeometry3D& sGeometry, int material, AnalyticalF3D& rho) { defineRho(sGeometry.getMaterialIndicator(material), rho); } template void SuperLattice3D::defineU( FunctorPtr>&& indicator, AnalyticalF3D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineU(indicator->getExtendedBlockIndicatorF(iC), u); } } template void SuperLattice3D::defineU( SuperGeometry3D& sGeometry, int material, AnalyticalF3D& u) { defineU(sGeometry.getMaterialIndicator(material), u); } template void SuperLattice3D::defineRhoU(FunctorPtr>&& indicator, AnalyticalF3D& rho, AnalyticalF3D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].defineRhoU(indicator->getExtendedBlockIndicatorF(iC), rho, u); } } template void SuperLattice3D::defineRhoU(SuperGeometry3D& sGeometry, int material, AnalyticalF3D& rho, AnalyticalF3D& u) { defineRhoU(sGeometry.getMaterialIndicator(material), rho, u); } template void SuperLattice3D::definePopulations( FunctorPtr>&& indicator, AnalyticalF3D& Pop) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].definePopulations( indicator->getExtendedBlockIndicatorF(iC), Pop); } } template void SuperLattice3D::definePopulations( SuperGeometry3D& sGeometry, int material, AnalyticalF3D& Pop) { definePopulations(sGeometry.getMaterialIndicator(material), Pop); } template void SuperLattice3D::definePopulations( FunctorPtr>&& indicator, SuperF3D& Pop) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].definePopulations( indicator->getExtendedBlockIndicatorF(iC), Pop.getBlockF(iC)); } } template void SuperLattice3D::definePopulations( SuperGeometry3D& sGeometry, int material, SuperF3D& Pop) { definePopulations(sGeometry.getMaterialIndicator(material), Pop); } template template void SuperLattice3D::defineField( SuperGeometry3D& sGeometry, int material, SuperF3D& field) { if (sGeometry.getStatistics().getNvoxel(material)!=0) { int overlap = sGeometry.getOverlap(); for (int iC=0; iC < this->_loadBalancer.size(); ++iC) { if (sGeometry.getExtendedBlockGeometry(iC).getStatistics().getNvoxel(material)!=0) { const int x0 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMinLatticeR(material)[0]; const int y0 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMinLatticeR(material)[1]; const int z0 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMinLatticeR(material)[2]; const int x1 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMaxLatticeR(material)[0]; const int y1 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMaxLatticeR(material)[1]; const int z1 = sGeometry.getExtendedBlockGeometry(iC).getStatistics().getMaxLatticeR(material)[2]; for (int iX=x0; iX<=x1; ++iX) { for (int iY=y0; iY<=y1; ++iY) { for (int iZ=z0; iZ<=z1; ++iZ) { if (sGeometry.getExtendedBlockGeometry(iC).getMaterial(iX,iY,iZ) == material) { T fieldTmp[DESCRIPTOR::template size()]; int inputTmp[4]= {this->_loadBalancer.glob(iC),iX-overlap,iY-overlap,iZ-overlap}; field(fieldTmp,inputTmp); _extendedBlockLattices[iC].get(iX,iY,iZ).template defineField(fieldTmp); } } } } } } } } template template void SuperLattice3D::defineField(SuperGeometry3D& sGeometry, IndicatorF3D& indicator, AnalyticalF3D& field) { SuperIndicatorFfromIndicatorF3D indicatorF(indicator, sGeometry); defineField(indicatorF, field); } template void SuperLattice3D::iniEquilibrium( FunctorPtr>&& indicator, AnalyticalF3D& rho, AnalyticalF3D& u) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].iniEquilibrium( indicator->getExtendedBlockIndicatorF(iC), rho, u); } this->_communicationNeeded = true; } template void SuperLattice3D::iniEquilibrium( SuperGeometry3D& sGeometry, int material, AnalyticalF3D& rho, AnalyticalF3D& u) { iniEquilibrium(sGeometry.getMaterialIndicator(material), rho, u); } #ifndef OLB_PRECOMPILED template void SuperLattice3D::setExternalParticleField(SuperGeometry3D& sGeometry, AnalyticalF3D& velocity, SmoothIndicatorF3D& sIndicator) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].setExternalParticleField( sGeometry.getExtendedBlockGeometry(iC), velocity, sIndicator); } } #endif template void SuperLattice3D::collide() { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _blockLattices[iC].collide(); } this->_communicationNeeded = true; } template void SuperLattice3D::collide(T x0, T x1, T y0, T y1, T z0, T z1) { int locX0, locX1, locY0, locY1, locZ0, locZ1; for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, z0, z1, locX0, locX1, locY0, locY1, locZ0, locZ1)) { _blockLattices[iC].collide(locX0, locX1, locY0, locY1, locZ0, locZ1); } } this->_communicationNeeded = true; } template void SuperLattice3D::stream() { _commStream.send(); _commStream.receive(); _commStream.write(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].stream(this->_overlap - 1, _extendedBlockLattices[iC].getNx() - this->_overlap, this->_overlap - 1, _extendedBlockLattices[iC].getNy() - this->_overlap, this->_overlap - 1, _extendedBlockLattices[iC].getNz() - this->_overlap); } if (_commBC_on) { _commBC.send(); _commBC.receive(); _commBC.write(); } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded = true; } template void SuperLattice3D::stream(T x0, T x1, T y0, T y1, T z0, T z1) { _commStream.send(); _commStream.receive(); _commStream.write(); int locX0, locX1, locY0, locY1, locZ0, locZ1; for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, z0, z1, locX0, locX1, locY0, locY1, locZ0, locZ1, this->_overlap)) { _extendedBlockLattices[iC].stream(locX0, locX1, locY0, locY1, locZ0, locZ1); } } if (_commBC_on) { _commBC.send(); _commBC.receive(); _commBC.write(); } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded = true; } template void SuperLattice3D::collideAndStream() { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { int x1 = _blockLattices[iC].getNx() - 1; int y1 = _blockLattices[iC].getNy() - 1; int z1 = _blockLattices[iC].getNz() - 1; _blockLattices[iC].collide(0, x1, 0, 0, 0, z1); _blockLattices[iC].collide(0, x1, y1, y1, 0, z1); if (y1>1) { _blockLattices[iC].collide(0, 0, 1, y1 - 1, 0, z1); _blockLattices[iC].collide(x1, x1, 1, y1 - 1, 0, z1); if (x1>1) { _blockLattices[iC].collide(1, x1 - 1, 1, y1 - 1, 0, 0); _blockLattices[iC].collide(1, x1 - 1, 1, y1 - 1, z1, z1); } } } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (2*this->_overlap + 2 < _extendedBlockLattices[iC].getNx() && 2*this->_overlap + 2 < _extendedBlockLattices[iC].getNy() && 2*this->_overlap + 2 < _extendedBlockLattices[iC].getNz() ) _extendedBlockLattices[iC].bulkCollideAndStream(this->_overlap + 1, _extendedBlockLattices[iC].getNx() - this->_overlap - 2, this->_overlap + 1, _extendedBlockLattices[iC].getNy() - this->_overlap - 2, this->_overlap + 1, _extendedBlockLattices[iC].getNz() - this->_overlap - 2); } _commStream.send(); _commStream.receive(); _commStream.write(); for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { int x1 = _extendedBlockLattices[iC].getNx() - 1; int y1 = _extendedBlockLattices[iC].getNy() - 1; int z1 = _extendedBlockLattices[iC].getNz() - 1; if (2*this->_overlap-3 < x1 && 2*this->_overlap-3 < z1) { _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, this->_overlap - 1, x1 - this->_overlap + 1, this->_overlap - 1, this->_overlap, this->_overlap - 1, z1 - this->_overlap + 1); _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, this->_overlap - 1, x1 - this->_overlap + 1, y1 - this->_overlap, y1 - this->_overlap + 1, this->_overlap - 1, z1 - this->_overlap + 1); } if (2*this->_overlap+1 < y1 && 2*this->_overlap-3 < z1) { _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, this->_overlap - 1, this->_overlap, this->_overlap + 1, y1 - this->_overlap - 1, this->_overlap - 1, z1 - this->_overlap + 1); _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, x1 - this->_overlap, x1 - this->_overlap + 1, this->_overlap + 1, y1 - this->_overlap - 1, this->_overlap - 1, z1 - this->_overlap + 1); } if (2*this->_overlap+1 < x1 && 2*this->_overlap+1 < y1) { _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, this->_overlap + 1, x1 - this->_overlap - 1, this->_overlap + 1, y1 - this->_overlap - 1, this->_overlap - 1, this->_overlap); _extendedBlockLattices[iC].boundaryStream(0, x1, 0, y1, 0, z1, this->_overlap + 1, x1 - this->_overlap - 1, this->_overlap + 1, y1 - this->_overlap - 1, z1 - this->_overlap, z1 - this->_overlap + 1); } } this->_communicationNeeded = true; if (_commBC_on) { _commBC.send(); _commBC.receive(); _commBC.write(); //SuperLattice3D::communicate(); } for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _blockLattices[iC].postProcess(); } if (_statistics_on) { reset_statistics(); } this->_communicationNeeded = true; } template void SuperLattice3D::stripeOffDensityOffset ( int x0, int x1, int y0, int y1, int z0, int z1, T offset ) { int locX0, locX1, locY0, locY1, locZ0, locZ1; for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { if (this->_cuboidGeometry.get(this->_loadBalancer.glob(iC)).checkInters(x0, x1, y0, y1, z0, z1, locX0, locX1, locY0, locY1, locZ0, locZ1, this->_overlap)) { _extendedBlockLattices[iC].stripeOffDensityOffset(locX0, locX1, locY0, locY1, locZ0, locZ1, offset); } } this->_communicationNeeded = true; } template void SuperLattice3D::stripeOffDensityOffset(T offset) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].stripeOffDensityOffset(offset); } this->_communicationNeeded = true; } template LatticeStatistics& SuperLattice3D::getStatistics() { return *_statistics; } template LatticeStatistics const& SuperLattice3D::getStatistics() const { return *_statistics; } template void SuperLattice3D::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 template void SuperLattice3D::addLatticeCoupling( LatticeCouplingGenerator3D const& lcGen, SuperLattice3D& partnerLattice) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector< SpatiallyExtendedObject3D* > partnerOne; partnerOne.push_back(&partnerLattice.getExtendedBlockLattice(iC)); int nx = getExtendedBlockLattice(iC).getNx(); int ny = getExtendedBlockLattice(iC).getNy(); int nz = getExtendedBlockLattice(iC).getNz(); LatticeCouplingGenerator3D *extractedLcGen = lcGen.clone(); extractedLcGen->reset(1, nx-2, 1, ny-2, 1, nz-2); getExtendedBlockLattice(iC).addLatticeCoupling(*extractedLcGen, partnerOne); delete extractedLcGen; } return; } template template void SuperLattice3D::addLatticeCoupling( FunctorPtr>&& indicator, LatticeCouplingGenerator3D const& lcGen, SuperLattice3D& 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) { for (int iZ = 1; iZ < _extendedBlockLattices[iC].getNz()-1; ++iZ) { std::unique_ptr> extractedLcGen{ lcGen.clone() }; //TODO done quick and dirty if (extractedLcGen->extract(0, 0, 0, 0, 0, 0) ) { if (indicator->getExtendedBlockIndicatorF(iC)(iX, iY, iZ)) { extractedLcGen->shift(iX, iY, iZ, this->_loadBalancer.glob(iC)); _extendedBlockLattices[iC].addLatticeCoupling(*extractedLcGen, partnerOne); } } } } } } } template template void SuperLattice3D::addLatticeCoupling( SuperGeometry3D& sGeometry, int material, LatticeCouplingGenerator3D const& lcGen, SuperLattice3D& partnerLattice) { addLatticeCoupling(sGeometry.getMaterialIndicator(material), lcGen, partnerLattice); } template template void SuperLattice3D::addLatticeCoupling( LatticeCouplingGenerator3D const& lcGen, std::vector*> partnerLattices) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector< SpatiallyExtendedObject3D* > partners; for (auto partnerLattice: partnerLattices) { partners.push_back(&partnerLattice->getExtendedBlockLattice(iC)); } int nx = getExtendedBlockLattice(iC).getNx(); int ny = getExtendedBlockLattice(iC).getNy(); int nz = getExtendedBlockLattice(iC).getNz(); LatticeCouplingGenerator3D *extractedLcGen = lcGen.clone(); extractedLcGen->reset(1, nx-2, 1, ny-2, 1, nz-2); getExtendedBlockLattice(iC).addLatticeCoupling(*extractedLcGen, partners); delete extractedLcGen; } return; } template template void SuperLattice3D::addLatticeCoupling( FunctorPtr>&& indicator, LatticeCouplingGenerator3D const& lcGen, std::vector*> partnerLattices) { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { std::vector< SpatiallyExtendedObject3D* > 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) { for (int iZ = 1; iZ < _extendedBlockLattices[iC].getNz()-1; ++iZ) { std::unique_ptr> extractedLcGen{ lcGen.clone() }; //TODO done quick and dirty if (extractedLcGen->extract(0, 0, 0, 0, 0, 0) ) { if (indicator->getExtendedBlockIndicatorF(iC)(iX, iY, iZ)) { extractedLcGen->shift(iX, iY, iZ, this->_loadBalancer.glob(iC)); _extendedBlockLattices[iC].addLatticeCoupling(*extractedLcGen, partners); } } } } } } } template template void SuperLattice3D::addLatticeCoupling( SuperGeometry3D& sGeometry, int material, LatticeCouplingGenerator3D const& lcGen, std::vector*> partnerLattices) { addLatticeCoupling(sGeometry.getMaterialIndicator(material), lcGen, partnerLattices); } template void SuperLattice3D::executeCoupling() { for (int iC = 0; iC < this->_loadBalancer.size(); ++iC) { _extendedBlockLattices[iC].executeCoupling(); } this->_communicationNeeded = true; return; } template std::size_t SuperLattice3D::getNblock() const { return std::accumulate(_extendedBlockLattices.begin(), _extendedBlockLattices.end(), size_t(0), Serializable::sumNblock()); } template std::size_t SuperLattice3D::getSerializableSize() const { return std::accumulate(_extendedBlockLattices.begin(), _extendedBlockLattices.end(), size_t(0), Serializable::sumSerializableSize()); } template bool* SuperLattice3D::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; } } // namespace olb #endif