/* This file is part of the OpenLB library
*
* Copyright (C) 2006-2018 Jonas Latt, Adrian Kummerlaender
* 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
* Dynamics for a generic 2D block structure -- header file.
*/
#ifndef BLOCK_LATTICE_STRUCTURE_2D_HH
#define BLOCK_LATTICE_STRUCTURE_2D_HH
#include "blockLatticeStructure2D.h"
#include "functors/lattice/indicator/blockIndicatorBaseF2D.hh"
#include "functors/lattice/indicator/blockIndicatorF2D.hh"
namespace olb {
template
void BlockLatticeStructure2D::defineRho(
BlockIndicatorF2D& indicator, AnalyticalF2D& rho)
{
T physR[2] = { };
T rhoTmp = T();
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
indicator.getBlockGeometryStructure().getPhysR(physR, iX, iY);
rho(&rhoTmp, physR);
get(iX, iY).defineRho(rhoTmp);
}
}
}
}
template
void BlockLatticeStructure2D::defineRho(
BlockGeometryStructure2D& blockGeometry, int material, AnalyticalF2D& rho)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
defineRho(indicator, rho);
}
template
void BlockLatticeStructure2D::defineU(
BlockIndicatorF2D& indicator, AnalyticalF2D& u)
{
T physR[2] = { };
T uTmp[2] = { };
const auto& geometry = indicator.getBlockGeometryStructure();
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
geometry.getPhysR(physR, iX, iY);
u(uTmp, physR);
get(iX, iY).defineU(uTmp);
}
}
}
}
template
void BlockLatticeStructure2D::defineU(
BlockGeometryStructure2D& blockGeometry, int material, AnalyticalF2D& u)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
defineU(indicator, u);
}
template
void BlockLatticeStructure2D::defineRhoU(
BlockIndicatorF2D& indicator,
AnalyticalF2D& rho, AnalyticalF2D& u)
{
T physR[2] = { };
T uTmp[2] = { };
T rhoTmp = T();
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
indicator.getBlockGeometryStructure().getPhysR(physR, iX, iY);
rho(&rhoTmp, physR);
u(uTmp, physR);
get(iX, iY).defineRhoU(rhoTmp, uTmp);
}
}
}
}
template
void BlockLatticeStructure2D::defineRhoU(
BlockGeometryStructure2D& blockGeometry, int material,
AnalyticalF2D& rho, AnalyticalF2D& u)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
defineRhoU(indicator, rho, u);
}
template
void BlockLatticeStructure2D::definePopulations(
BlockIndicatorF2D& indicator, AnalyticalF2D& Pop)
{
T physR[2] = { };
T PopTmp[DESCRIPTOR::q];
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
indicator.getBlockGeometryStructure().getPhysR(physR, iX, iY);
Pop(PopTmp, physR);
get(iX, iY).definePopulations(PopTmp);
}
}
}
}
template
void BlockLatticeStructure2D::definePopulations(
BlockGeometryStructure2D& blockGeometry, int material, AnalyticalF2D& Pop)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
definePopulations(indicator, Pop);
}
template
template
void BlockLatticeStructure2D::defineField(
BlockIndicatorF2D& indicator, AnalyticalF2D& field)
{
T* fieldTmp = new T[DESCRIPTOR::template size()];
T physR[2] = { };
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
indicator.getBlockGeometryStructure().getPhysR(physR, iX, iY);
field(fieldTmp, physR);
get(iX, iY).template defineField(fieldTmp);
}
}
}
delete[] fieldTmp;
}
template
template
void BlockLatticeStructure2D::defineField(
BlockGeometryStructure2D& blockGeometry, int material, AnalyticalF2D& field)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
defineField(indicator, field);
}
template
template
void BlockLatticeStructure2D::defineField(
BlockGeometryStructure2D& blockGeometry, IndicatorF2D& indicatorF,
AnalyticalF2D& field)
{
BlockIndicatorFfromIndicatorF2D indicator(indicatorF, blockGeometry);
defineField(indicator, field);
}
template
template
void BlockLatticeStructure2D::addField(
BlockGeometryStructure2D& blockGeometry, IndicatorF2D& indicator,
AnalyticalF2D& field)
{
T* fieldTmp = new T[DESCRIPTOR::template size()];
T physR[2] = { };
bool inside;
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
blockGeometry.getPhysR(physR, iX, iY);
indicator(&inside, &(physR[0]));
if (inside) {
field(fieldTmp,physR);
get(iX, iY).template addField(fieldTmp);
}
}
}
delete[] fieldTmp;
}
template
template
void BlockLatticeStructure2D::addField(
BlockGeometryStructure2D& blockGeometry, IndicatorF2D& indicator,
AnalyticalF2D& field, AnalyticalF2D& porous)
{
T* fieldTmp = new T[DESCRIPTOR::template size()];
bool inside;
T physR[2] = { };
T porousA[1] = { };
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
blockGeometry.getPhysR(physR, iX, iY);
indicator(&inside, physR);
if (inside) {
porous(porousA, physR);
field(fieldTmp,physR);
for (int i = 0; i < DESCRIPTOR::template size(); ++i) {
fieldTmp[i] *= porousA[0];
}
get(iX, iY).template addField(fieldTmp);
}
}
}
delete[] fieldTmp;
}
#ifndef OLB_PRECOMPILED
template
void BlockLatticeStructure2D::setExternalParticleField(BlockGeometryStructure2D& blockGeometry, AnalyticalF2D& velocity, SmoothIndicatorF2D& sIndicator)
{
int start[2] = {0};
int end[2] = {0};
// check for intersection of cuboid and indicator
Cuboid2D tmpCuboid(blockGeometry.getOrigin()[0], blockGeometry.getOrigin()[1], blockGeometry.getDeltaR(), blockGeometry.getNx(), blockGeometry.getNy());
T posXmin = sIndicator.getPos()[0] - sIndicator.getCircumRadius();
T posXmax = sIndicator.getPos()[0] + sIndicator.getCircumRadius();
T posYmin = sIndicator.getPos()[1] - sIndicator.getCircumRadius();
T posYmax = sIndicator.getPos()[1] + sIndicator.getCircumRadius();
if(tmpCuboid.checkInters(posXmin, posXmax, posYmin, posYmax, start[0], end[0], start[1], end[1])) {
for (int k=0; k<2; k++) {
start[k] -= 1;
if(start[k] < 0) start[k] = 0;
end[k] += 2;
if(end[k] > blockGeometry.getExtend()[k]) end[k] = blockGeometry.getExtend()[k];
}
T foo[3] = { }; /// Contains foo[0]=vel0; foo[1]=vel1; foo[2]=porosity
T physR[2]= { };
T porosity[1] = { };
for (int iX = start[0]; iX < end[0]; ++iX) {
for (int iY = start[1]; iY < end[1]; ++iY) {
blockGeometry.getPhysR(physR, iX, iY);
sIndicator(porosity, physR);
if (!util::nearZero(porosity[0])) {
// TODO: Check / adapt to use descriptor fields
velocity(foo,physR);
foo[0] *= porosity[0];
foo[1] *= porosity[0];
foo[2] = porosity[0];
get(iX, iY).template addField(foo);
get(iX, iY).template addField(&foo[2]);
porosity[0] = 1.-porosity[0];
*(get(iX, iY).template getFieldPointer()) *= porosity[0];
}
}
}
}
}
#endif
template
template
void BlockLatticeStructure2D::multiplyField(
BlockGeometryStructure2D& blockGeometry, IndicatorF2D& indicator,
AnalyticalF2D& field)
{
T* fieldTmp = new T [DESCRIPTOR::template size()];
bool inside;
T physR[3] = { };
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
blockGeometry.getPhysR(physR, iX, iY);
indicator(&inside, &(physR[0]));
if (inside) {
field(fieldTmp, physR);
get(iX, iY).template multiplyField(fieldTmp);
}
}
}
delete[] fieldTmp;
}
template
void BlockLatticeStructure2D::iniEquilibrium(
BlockIndicatorF2D& indicator,
AnalyticalF2D& rho, AnalyticalF2D& u)
{
T physR[2] = { };
T uTmp[2] = { };
T rhoTmp = T();
for (int iX = 0; iX < getNx(); ++iX) {
for (int iY = 0; iY < getNy(); ++iY) {
if (indicator(iX, iY)) {
indicator.getBlockGeometryStructure().getPhysR(physR, iX, iY);
u(uTmp, physR);
rho(&rhoTmp, physR);
get(iX, iY).iniEquilibrium(rhoTmp, uTmp);
}
}
}
}
template
void BlockLatticeStructure2D::iniEquilibrium(
BlockGeometryStructure2D& blockGeometry, int material,
AnalyticalF2D& rho, AnalyticalF2D& u)
{
BlockIndicatorMaterial2D indicator(blockGeometry, material);
iniEquilibrium(indicator, rho, u);
}
} // namespace olb
#endif