/* 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
* <http://www.openlb.net/>
*
* 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 <limits>
#include <numeric>
#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<typename T, typename DESCRIPTOR>
SuperLattice2D<T, DESCRIPTOR>::SuperLattice2D(SuperGeometry2D<T>& superGeometry,
int overlapRefinement)
: SuperStructure2D<T>(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<T, DESCRIPTOR> 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<T> ;
_statistics_on = true;
if (_commBC_on) {
_commBC.init_nh();
}
this->_communicationNeeded=true;
}
template<typename T, typename DESCRIPTOR>
SuperLattice2D<T,DESCRIPTOR>::~SuperLattice2D ()
{
delete _statistics;
}
template<typename T, typename DESCRIPTOR>
bool SuperLattice2D<T,DESCRIPTOR>::set(T iX, T iY, Cell<T,DESCRIPTOR> const& cell)
{
bool found = false;
int locX, locY;
for (int iC=0; iC<this->_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<typename T, typename DESCRIPTOR>
void SuperLattice2D<T,DESCRIPTOR>::set(Vector<int,3> pos, const Cell<T,DESCRIPTOR>& 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<typename T, typename DESCRIPTOR>
void SuperLattice2D<T,DESCRIPTOR>::get(Vector<int,3> pos, Cell<T,DESCRIPTOR>& 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