/* This file is part of the OpenLB library
*
* Copyright (C) 2019 Adrian Kummerländer
* 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.
*/
#ifndef REFINEMENT_GRID_2D_HH
#define REFINEMENT_GRID_2D_HH
#include "grid2D.h"
#include "coupler2D.hh"
#include "utilities/vectorHelpers.h"
#include "communication/heuristicLoadBalancer.h"
namespace olb {
template class DESCRIPTOR>
Grid2D::Grid2D(FunctorPtr>&& domainF, int resolution, T tau, int re):
_domainF(std::move(domainF)),
_converter(new UnitConverterFromResolutionAndRelaxationTime(
resolution, // resolution: number of voxels per charPhysL
tau, // latticeRelaxationTime: relaxation time, has to be greater than 0.5!
T{1}, // charPhysLength: reference length of simulation geometry
T{1}, // charPhysVelocity: maximal/highest expected velocity during simulation in __m / s__
T{1./re}, // physViscosity: physical kinematic viscosity in __m^2 / s__
T{1}, // physDensity: physical density in __kg / m^3__
T{1})),
_cuboids(new CuboidGeometry2D(
*_domainF,
_converter->getConversionFactorLength(),
#ifdef PARALLEL_MODE_MPI
singleton::mpi().getSize()
#else
1
#endif
)),
_balancer(new HeuristicLoadBalancer(
*_cuboids)),
_geometry(new SuperGeometry2D(
*_cuboids,
*_balancer,
2)),
_lattice(new SuperLattice2D(
*_geometry))
{
_converter->print();
}
template class DESCRIPTOR>
UnitConverter& Grid2D::getConverter()
{
return *_converter;
}
template class DESCRIPTOR>
CuboidGeometry2D& Grid2D::getCuboidGeometry()
{
return *_cuboids;
}
template class DESCRIPTOR>
LoadBalancer& Grid2D::getLoadBalancer()
{
return *_balancer;
}
template class DESCRIPTOR>
SuperGeometry2D& Grid2D::getSuperGeometry()
{
return *_geometry;
}
template class DESCRIPTOR>
SuperLattice2D& Grid2D::getSuperLattice()
{
return *_lattice;
}
template class DESCRIPTOR>
void Grid2D::collideAndStream()
{
for ( auto& fineCoupler : _fineCouplers ) {
fineCoupler->store();
}
this->getSuperLattice().collideAndStream();
for ( auto& fineGrid : _fineGrids ) {
fineGrid->collideAndStream();
}
for ( auto& fineCoupler : _fineCouplers ) {
fineCoupler->interpolate();
fineCoupler->couple();
}
for ( auto& fineGrid : _fineGrids ) {
fineGrid->collideAndStream();
}
for ( auto& fineCoupler : _fineCouplers ) {
fineCoupler->store();
fineCoupler->couple();
}
for ( auto& coarseCoupler : _coarseCouplers ) {
coarseCoupler->couple();
}
}
template class DESCRIPTOR>
FineCoupler2D& Grid2D::addFineCoupling(
Grid2D& fineGrid, Vector origin, Vector extend)
{
_fineCouplers.emplace_back(
new FineCoupler2D(
*this, fineGrid, origin, extend));
return *_fineCouplers.back();
}
template class DESCRIPTOR>
CoarseCoupler2D& Grid2D::addCoarseCoupling(
Grid2D& fineGrid, Vector origin, Vector extend)
{
_coarseCouplers.emplace_back(
new CoarseCoupler2D(
*this, fineGrid, origin, extend));
return *_coarseCouplers.back();
}
template class DESCRIPTOR>
Vector Grid2D::alignOriginToGrid(Vector physR) const
{
Vector latticeR{};
_cuboids->getLatticeR(physR, latticeR);
return _cuboids->getPhysR(latticeR.toStdVector());
}
template class DESCRIPTOR>
Vector Grid2D::alignExtendToGrid(Vector extend) const
{
const T deltaX = _converter->getPhysDeltaX();
return util::floor(extend / deltaX) * deltaX;
}
template class DESCRIPTOR>
RefiningGrid2D& Grid2D::refine(
Vector wantedOrigin, Vector wantedExtend, bool addCouplers)
{
if (addCouplers) {
auto& fineGrid = refine(wantedOrigin, wantedExtend, false);
const Vector origin = fineGrid.getOrigin();
const Vector extend = fineGrid.getExtend();
const Vector extendX = {extend[0],0};
const Vector extendY = {0,extend[1]};
addFineCoupling(fineGrid, origin, extendY);
addFineCoupling(fineGrid, origin + extendX, extendY);
addFineCoupling(fineGrid, origin + extendY, extendX);
addFineCoupling(fineGrid, origin, extendX);
const T coarseDeltaX = getConverter().getPhysDeltaX();
const Vector innerOrigin = origin + coarseDeltaX;
const Vector innerExtendX = extendX - Vector {2*coarseDeltaX,0};
const Vector innerExtendY = extendY - Vector {0,2*coarseDeltaX};
addCoarseCoupling(fineGrid, innerOrigin, innerExtendY);
addCoarseCoupling(fineGrid, innerOrigin + innerExtendX, innerExtendY);
addCoarseCoupling(fineGrid, innerOrigin + innerExtendY, innerExtendX);
addCoarseCoupling(fineGrid, innerOrigin, innerExtendX);
return fineGrid;
}
else {
const Vector origin = alignOriginToGrid(wantedOrigin);
const Vector extend = alignExtendToGrid(wantedExtend);
_fineGrids.emplace_back(
new RefiningGrid2D(*this, origin, extend));
return *_fineGrids.back();
}
}
template class DESCRIPTOR>
RefiningGrid2D::RefiningGrid2D(
Grid2D& parentGrid, Vector origin, Vector extend):
Grid2D(
std::unique_ptr>(new IndicatorCuboid2D(extend, origin)),
2*parentGrid.getConverter().getResolution(),
2*parentGrid.getConverter().getLatticeRelaxationTime() - 0.5,
parentGrid.getConverter().getReynoldsNumber()),
_origin(origin),
_extend(extend),
_parentGrid(parentGrid)
{ }
template class DESCRIPTOR>
Vector RefiningGrid2D::getOrigin() const
{
return _origin;
}
template class DESCRIPTOR>
Vector RefiningGrid2D::getExtend() const
{
return _extend;
}
template class DESCRIPTOR>
std::unique_ptr> RefiningGrid2D::getRefinedOverlap() const
{
const T coarseDeltaX = _parentGrid.getConverter().getPhysDeltaX();
return std::unique_ptr>(
new IndicatorCuboid2D(_extend - 4*coarseDeltaX, _origin + 2*coarseDeltaX));
}
}
#endif