/* 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 "communication/heuristicLoadBalancer.h"
namespace olb {
template class DESCRIPTOR>
std::unique_ptr> Grid2D::make(
IndicatorF2D& domainF,
int resolution, T tau, int re)
{
return std::unique_ptr>(
new Grid2D(domainF, resolution, tau, re)
);
}
template class DESCRIPTOR>
Grid2D::Grid2D(IndicatorF2D& domainF, int resolution, T tau, int re):
_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>
T Grid2D::getScalingFactor()
{
return 4. - _converter->getLatticeRelaxationFrequency();
}
template class DESCRIPTOR>
T Grid2D::getInvScalingFactor()
{
return 1./getScalingFactor();
}
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>
Grid2D& Grid2D::refine(IndicatorF2D& domainF)
{
_fineGrids.emplace_back(
new Grid2D(
domainF,
2*getConverter().getResolution(),
2*getConverter().getLatticeRelaxationTime() - 0.5,
getConverter().getReynoldsNumber()
));
return *_fineGrids.back();
}
template class DESCRIPTOR>
Vector Grid2D::alignToGrid(Vector physR) const
{
Vector latticeR{};
_cuboids->getLatticeR(physR, latticeR);
return _cuboids->getPhysR(latticeR.toStdVector());
}
template class DESCRIPTOR>
Grid2D& Grid2D::refine(Vector origin, Vector extend)
{
IndicatorCuboid2D fineCuboid(extend, origin);
auto& fineGrid = refine(fineCuboid);
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;
}
}
#endif