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/core/superLattice3D.hh | 821 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 821 insertions(+) create mode 100644 src/core/superLattice3D.hh (limited to 'src/core/superLattice3D.hh') diff --git a/src/core/superLattice3D.hh b/src/core/superLattice3D.hh new file mode 100644 index 0000000..f040242 --- /dev/null +++ b/src/core/superLattice3D.hh @@ -0,0 +1,821 @@ +/* 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 -- cgit v1.2.3