/* This file is part of the OpenLB library
*
* Copyright (C) 2006, 2007 Jonas Latt
* 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 FD_BOUNDARIES_2D_HH
#define FD_BOUNDARIES_2D_HH
#include "boundaryPostProcessors2D.h"
#include "core/finiteDifference2D.h"
#include "core/blockLattice2D.h"
#include "core/util.h"
#include "dynamics/lbHelpers.h"
#include "dynamics/firstOrderLbHelpers.h"
namespace olb {
/////////// StraightFdBoundaryProcessor2D ///////////////////////////////////
template
StraightFdBoundaryProcessor2D::
StraightFdBoundaryProcessor2D(int x0_, int x1_, int y0_, int y1_)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_)
{
OLB_PRECONDITION(x0==x1 || y0==y1);
}
template
void StraightFdBoundaryProcessor2D::
processSubDomain(BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
using namespace olb::util::tensorIndices2D;
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
int iX;
#ifdef PARALLEL_MODE_OMP
#pragma omp parallel for
#endif
for (iX=newX0; iX<=newX1; ++iX) {
T dx_u[DESCRIPTOR::d], dy_u[DESCRIPTOR::d];
for (int iY=newY0; iY<=newY1; ++iY) {
Cell& cell = blockLattice.get(iX,iY);
Dynamics* dynamics = blockLattice.getDynamics(iX, iY);
T rho, u[DESCRIPTOR::d];
cell.computeRhoU(rho,u);
interpolateGradients<0>(blockLattice, dx_u, iX, iY);
interpolateGradients<1>(blockLattice, dy_u, iX, iY);
T dx_ux = dx_u[0];
T dy_ux = dy_u[0];
T dx_uy = dx_u[1];
T dy_uy = dy_u[1];
T omega = dynamics->getOmega();
T sToPi = - rho / descriptors::invCs2() / omega;
T pi[util::TensorVal::n];
pi[xx] = (T)2 * dx_ux * sToPi;
pi[yy] = (T)2 * dy_uy * sToPi;
pi[xy] = (dx_uy + dy_ux) * sToPi;
// Computation of the particle distribution functions
// according to the regularized formula
T uSqr = util::normSqr(u);
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = dynamics -> computeEquilibrium(iPop,rho,u,uSqr) +
firstOrderLbHelpers::fromPiToFneq(iPop, pi);
}
}
}
}
}
template
void StraightFdBoundaryProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
template
template
void StraightFdBoundaryProcessor2D::
interpolateGradients(BlockLattice2D const& blockLattice,
T velDeriv[DESCRIPTOR::d], int iX, int iY) const
{
fd::DirectedGradients2D::
interpolateVector(velDeriv, blockLattice, iX, iY);
}
//////// StraightFdBoundaryProcessorGenerator2D ////////////////////////////////
template
StraightFdBoundaryProcessorGenerator2D::
StraightFdBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_)
{ }
template
PostProcessor2D*
StraightFdBoundaryProcessorGenerator2D::generate() const
{
return new StraightFdBoundaryProcessor2D
( this->x0, this->x1, this->y0, this->y1);
}
template
PostProcessorGenerator2D*
StraightFdBoundaryProcessorGenerator2D::clone() const
{
return new StraightFdBoundaryProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1);
}
//////// StraightConvectionBoundaryProcessor2D ////////////////////////////////
template
StraightConvectionBoundaryProcessor2D::
StraightConvectionBoundaryProcessor2D(int x0_, int x1_, int y0_, int y1_, T* uAv_)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_), uAv(uAv_)
{
OLB_PRECONDITION(x0==x1 || y0==y1);
saveCell = new T** [(size_t)(x1_-x0_+1)];
for (int iX=0; iX<=x1_-x0_; ++iX) {
saveCell[iX] = new T* [(size_t)(y1_-y0_+1)];
for (int iY=0; iY<=y1_-y0_; ++iY) {
saveCell[iX][iY] = new T [(size_t)(DESCRIPTOR::q)];
for (int iPop=0; iPop
StraightConvectionBoundaryProcessor2D::
~StraightConvectionBoundaryProcessor2D()
{
for (int iX=0; iX<=x1-x0; ++iX) {
for (int iY=0; iY<=y1-y0; ++iY) {
delete [] saveCell[iX][iY];
}
delete [] saveCell[iX];
}
delete [] saveCell;
}
template
void StraightConvectionBoundaryProcessor2D::
processSubDomain(BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
using namespace olb::util::tensorIndices2D;
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
int iX;
#ifdef PARALLEL_MODE_OMP
#pragma omp parallel for
#endif
for (iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
Cell& cell = blockLattice.get(iX,iY);
for (int iPop = 0; iPop < DESCRIPTOR::q ; ++iPop) {
if (descriptors::c(iPop,direction)==-orientation) {
// using default -1 avoids wrong first call
if (!util::nearZero(1 + saveCell[iX-newX0][iY-newY0][iPop]) ){
cell[iPop] = saveCell[iX-newX0][iY-newY0][iPop];
}
}
}
T rho0, u0[2];
T rho1, u1[2];
T rho2, u2[2];
if (direction==0) {
blockLattice.get(iX,iY).computeRhoU(rho0,u0);
blockLattice.get(iX-orientation,iY).computeRhoU(rho1,u1);
blockLattice.get(iX-orientation*2,iY).computeRhoU(rho2,u2);
} else {
blockLattice.get(iX,iY).computeRhoU(rho0,u0);
blockLattice.get(iX,iY-orientation).computeRhoU(rho1,u1);
blockLattice.get(iX,iY-orientation*2).computeRhoU(rho2,u2);
}
// rho0 = T(1); rho1 = T(1); rho2 = T(1);
T uDelta[2];
T uAverage = rho0*u0[direction];
if (uAv!=nullptr) {
uAverage = *uAv;
}
uDelta[0]=-uAverage*0.5*(3*rho0*u0[0]-4*rho1*u1[0]+rho2*u2[0]);
uDelta[1]=-uAverage*0.5*(3*rho0*u0[1]-4*rho1*u1[1]+rho2*u2[1]);
for (int iPop = 0; iPop < DESCRIPTOR::q ; ++iPop) {
if (descriptors::c(iPop,direction) == -orientation) {
saveCell[iX-newX0][iY-newY0][iPop] = cell[iPop] + descriptors::invCs2()*descriptors::t(iPop)*(uDelta[0]*descriptors::c(iPop,0)+uDelta[1]*descriptors::c(iPop,1));
}
}
}
}
}
}
template
void StraightConvectionBoundaryProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
//////// StraightConvectionBoundaryProcessorGenerator2D ////////////////////////////////
template
StraightConvectionBoundaryProcessorGenerator2D::
StraightConvectionBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_, T* uAv_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_), uAv(uAv_)
{ }
template
PostProcessor2D*
StraightConvectionBoundaryProcessorGenerator2D::generate() const
{
return new StraightConvectionBoundaryProcessor2D
( this->x0, this->x1, this->y0, this->y1, uAv);
}
template
PostProcessorGenerator2D*
StraightConvectionBoundaryProcessorGenerator2D::clone() const
{
return new StraightConvectionBoundaryProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1, uAv);
}
//////// SlipBoundaryProcessor2D ////////////////////////////////
template
SlipBoundaryProcessor2D::
SlipBoundaryProcessor2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX, int discreteNormalY)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_)
{
OLB_PRECONDITION(x0==x1 || y0==y1);
reflectionPop[0] = 0;
for (int iPop = 1; iPop < DESCRIPTOR::q; iPop++) {
reflectionPop[iPop] = 0;
// iPop are the directions which ointing into the fluid, discreteNormal is pointing outwarts
if (descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY < 0) {
// std::cout << "-----" <(iPop,0) - mult*(descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY )*discreteNormalX);
mirrorDirection1 = (descriptors::c(iPop,1) - mult*(descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY )*discreteNormalY);
// computes mirror jPop
for (reflectionPop[iPop] = 1; reflectionPop[iPop] < DESCRIPTOR::q ; reflectionPop[iPop]++) {
if (descriptors::c(reflectionPop[iPop],0)==mirrorDirection0 && descriptors::c(reflectionPop[iPop],1)==mirrorDirection1 ) {
break;
}
}
//std::cout <
void SlipBoundaryProcessor2D::
processSubDomain(BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
int iX;
#ifdef PARALLEL_MODE_OMP
#pragma omp parallel for
#endif
for (iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
if (reflectionPop[iPop]!=0) {
//do reflection
blockLattice.get(iX,iY)[iPop] = blockLattice.get(iX,iY)[reflectionPop[iPop]];
}
}
}
}
}
}
template
void SlipBoundaryProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
//////// SlipBoundaryProcessorGenerator2D ////////////////////////////////
template
SlipBoundaryProcessorGenerator2D::
SlipBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_), discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_)
{ }
template
PostProcessor2D*
SlipBoundaryProcessorGenerator2D::generate() const
{
return new SlipBoundaryProcessor2D
( this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
template
PostProcessorGenerator2D*
SlipBoundaryProcessorGenerator2D::clone() const
{
return new SlipBoundaryProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
//////// PartialSlipBoundaryProcessor2D ////////////////////////////////
template
PartialSlipBoundaryProcessor2D::
PartialSlipBoundaryProcessor2D(T tuner_, int x0_, int x1_, int y0_, int y1_, int discreteNormalX, int discreteNormalY)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_), tuner(tuner_)
{
OLB_PRECONDITION(x0==x1 || y0==y1);
reflectionPop[0] = 0;
for (int iPop = 1; iPop < DESCRIPTOR::q; iPop++) {
reflectionPop[iPop] = 0;
// iPop are the directions which ointing into the fluid, discreteNormal is pointing outwarts
if (descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY < 0) {
//std::cout << "-----" <(iPop,0) - mult*(descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY )*discreteNormalX);
mirrorDirection1 = (descriptors::c(iPop,1) - mult*(descriptors::c(iPop,0)*discreteNormalX + descriptors::c(iPop,1)*discreteNormalY )*discreteNormalY);
// computes mirror jPop
for (reflectionPop[iPop] = 1; reflectionPop[iPop] < DESCRIPTOR::q ; reflectionPop[iPop]++) {
if (descriptors::c(reflectionPop[iPop],0)==mirrorDirection0 && descriptors::c(reflectionPop[iPop],1)==mirrorDirection1 ) {
break;
}
}
//std::cout <
void PartialSlipBoundaryProcessor2D::
processSubDomain(BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
int iX;
#ifdef PARALLEL_MODE_OMP
#pragma omp parallel for
#endif
for (iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
if (reflectionPop[iPop]!=0) {
//do reflection
blockLattice.get(iX,iY)[iPop] = tuner*blockLattice.get(iX,iY)[reflectionPop[iPop]];
}
}
for (int iPop = 1; iPop < DESCRIPTOR::q/2 ; ++iPop) {
T provv = blockLattice.get(iX,iY)[descriptors::opposite(iPop)];
blockLattice.get(iX,iY)[descriptors::opposite(iPop)] +=
(1.-tuner)*blockLattice.get(iX,iY)[iPop];
blockLattice.get(iX,iY)[iPop] += (1.-tuner)*provv;
}
}
}
}
}
template
void PartialSlipBoundaryProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
//////// PartialSlipBoundaryProcessorGenerator2D ////////////////////////////////
template
PartialSlipBoundaryProcessorGenerator2D::
PartialSlipBoundaryProcessorGenerator2D(T tuner_, int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_), discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_), tuner(tuner_)
{ }
template
PostProcessor2D*
PartialSlipBoundaryProcessorGenerator2D::generate() const
{
return new PartialSlipBoundaryProcessor2D
(tuner, this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
template
PostProcessorGenerator2D*
PartialSlipBoundaryProcessorGenerator2D::clone() const
{
return new PartialSlipBoundaryProcessorGenerator2D
(tuner, this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
/////////// OuterVelocityCornerProcessor2D /////////////////////////////////////
template
OuterVelocityCornerProcessor2D::
OuterVelocityCornerProcessor2D(int x_, int y_)
: x(x_), y(y_)
{ }
template
void OuterVelocityCornerProcessor2D::
process(BlockLattice2D& blockLattice)
{
using namespace olb::util::tensorIndices2D;
T rho10 = blockLattice.get(x-1*xNormal, y-0*yNormal).computeRho();
T rho01 = blockLattice.get(x-0*xNormal, y-1*yNormal).computeRho();
T rho20 = blockLattice.get(x-2*xNormal, y-0*yNormal).computeRho();
T rho02 = blockLattice.get(x-0*xNormal, y-2*yNormal).computeRho();
T rho = (T)2/(T)3*(rho01+rho10) - (T)1/(T)6*(rho02+rho20);
T dx_u[DESCRIPTOR::d], dy_u[DESCRIPTOR::d];
fd::DirectedGradients2D::interpolateVector(dx_u, blockLattice, x,y);
fd::DirectedGradients2D::interpolateVector(dy_u, blockLattice, x,y);
T dx_ux = dx_u[0];
T dy_ux = dy_u[0];
T dx_uy = dx_u[1];
T dy_uy = dy_u[1];
Cell& cell = blockLattice.get(x,y);
Dynamics* dynamics = blockLattice.getDynamics(x, y);
T omega = dynamics -> getOmega();
T sToPi = - rho / descriptors::invCs2() / omega;
T pi[util::TensorVal::n];
pi[xx] = (T)2 * dx_ux * sToPi;
pi[yy] = (T)2 * dy_uy * sToPi;
pi[xy] = (dx_uy + dy_ux) * sToPi;
// Computation of the particle distribution functions
// according to the regularized formula
T u[DESCRIPTOR::d];
blockLattice.get(x,y).computeU(u);
T uSqr = util::normSqr(u);
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] =
dynamics -> computeEquilibrium(iPop,rho,u,uSqr) +
firstOrderLbHelpers::fromPiToFneq(iPop, pi);
}
}
template
void OuterVelocityCornerProcessor2D::
processSubDomain(BlockLattice2D& blockLattice,
int x0_, int x1_, int y0_, int y1_ )
{
if (util::contained(x, y, x0_, x1_, y0_, y1_)) {
process(blockLattice);
}
}
//////// OuterVelocityCornerProcessorGenerator2D ////////////////////////////
template
OuterVelocityCornerProcessorGenerator2D::
OuterVelocityCornerProcessorGenerator2D(int x_, int y_)
: PostProcessorGenerator2D(x_, x_, y_, y_)
{ }
template
PostProcessor2D*
OuterVelocityCornerProcessorGenerator2D::generate() const
{
return new OuterVelocityCornerProcessor2D
( this->x0, this->y0);
}
template
PostProcessorGenerator2D*
OuterVelocityCornerProcessorGenerator2D::
clone() const
{
return new OuterVelocityCornerProcessorGenerator2D
( this->x0, this->y0);
}
template
FreeEnergyWallProcessor2D::
FreeEnergyWallProcessor2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_, T addend_)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_),
discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_),
addend(addend_)
{ }
template
void FreeEnergyWallProcessor2D::
processSubDomain(BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
for (int iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
T rhoAvg = blockLattice.get(iX-discreteNormalX, iY-discreteNormalY).computeRho();
T rhoTmp = 0.;
for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
rhoTmp += blockLattice.get(iX,iY)[iPop];
}
T rho = rhoAvg + addend;
rho -= rhoTmp;
blockLattice.get(iX,iY)[0] = rho-1.;
}
}
}
}
template
void FreeEnergyWallProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
template
FreeEnergyWallProcessorGenerator2D::
FreeEnergyWallProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX_,
int discreteNormalY_, T addend_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_), discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_), addend(addend_)
{ }
template
PostProcessor2D*
FreeEnergyWallProcessorGenerator2D::generate() const
{
return new FreeEnergyWallProcessor2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY, addend);
}
template
PostProcessorGenerator2D*
FreeEnergyWallProcessorGenerator2D::clone() const
{
return new FreeEnergyWallProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY, addend);
}
//////// FreeEnergyChemPotBoundaryProcessor2D ////////////////////////////
template
FreeEnergyChemPotBoundaryProcessor2D::
FreeEnergyChemPotBoundaryProcessor2D(
int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_, int latticeNumber_)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_), discreteNormalX(discreteNormalX_),
discreteNormalY(discreteNormalY_), latticeNumber(latticeNumber_)
{ }
template
void FreeEnergyChemPotBoundaryProcessor2D::
processSubDomain(
BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
for (int iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
blockLattice.get(iX,iY).template setField(
blockLattice.get(iX-discreteNormalX, iY-discreteNormalY).template getField()
);
if (latticeNumber == 1) {
T rho0 = blockLattice.get(iX, iY).computeRho();
T rho1 = blockLattice.get(iX-discreteNormalX, iY-discreteNormalY).computeRho();
*(blockLattice.get(iX,iY).template getFieldPointer()) += (rho1 / rho0 - 1) / descriptors::invCs2();
}
}
}
}
}
template
void FreeEnergyChemPotBoundaryProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
//////// FreeEnergyChemPotBoundaryProcessorGenerator2D ////////////////////////////
template
FreeEnergyChemPotBoundaryProcessorGenerator2D::
FreeEnergyChemPotBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_,
int discreteNormalX_, int discreteNormalY_, int latticeNumber_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_), discreteNormalX(discreteNormalX_),
discreteNormalY(discreteNormalY_), latticeNumber(latticeNumber_)
{ }
template
PostProcessor2D*
FreeEnergyChemPotBoundaryProcessorGenerator2D::generate() const
{
return new FreeEnergyChemPotBoundaryProcessor2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY, latticeNumber);
}
template
PostProcessorGenerator2D*
FreeEnergyChemPotBoundaryProcessorGenerator2D::clone() const
{
return new FreeEnergyChemPotBoundaryProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY, latticeNumber);
}
//////// FreeEnergyConvectiveProcessor2D ////////////////////////////
template
FreeEnergyConvectiveProcessor2D::
FreeEnergyConvectiveProcessor2D(
int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_)
: x0(x0_), x1(x1_), y0(y0_), y1(y1_),
discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_)
{ }
template
void FreeEnergyConvectiveProcessor2D::
processSubDomain(
BlockLattice2D& blockLattice, int x0_, int x1_, int y0_, int y1_)
{
int newX0, newX1, newY0, newY1;
if ( util::intersect (
x0, x1, y0, y1,
x0_, x1_, y0_, y1_,
newX0, newX1, newY0, newY1 ) ) {
for (int iX=newX0; iX<=newX1; ++iX) {
for (int iY=newY0; iY<=newY1; ++iY) {
T rho, rho0, rho1, u[2];
rho0 = blockLattice.get(iX,iY).computeRho();
blockLattice.get(iX-discreteNormalX,iY-discreteNormalY).computeRhoU(rho1, u);
T uPerp = 0;
if (discreteNormalX == 0) {
uPerp = discreteNormalY * u[1];
} else if (discreteNormalY == 0) {
uPerp = discreteNormalX * u[0];
}
rho = (rho0 + uPerp * rho1) / (1. + uPerp);
blockLattice.get(iX,iY).defineRho(rho);
}
}
}
}
template
void FreeEnergyConvectiveProcessor2D::
process(BlockLattice2D& blockLattice)
{
processSubDomain(blockLattice, x0, x1, y0, y1);
}
//////// FreeEnergyConvectiveProcessorGenerator2D ////////////////////////////
template
FreeEnergyConvectiveProcessorGenerator2D::
FreeEnergyConvectiveProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_,
int discreteNormalX_, int discreteNormalY_)
: PostProcessorGenerator2D(x0_, x1_, y0_, y1_),
discreteNormalX(discreteNormalX_), discreteNormalY(discreteNormalY_)
{ }
template
PostProcessor2D*
FreeEnergyConvectiveProcessorGenerator2D::generate() const
{
return new FreeEnergyConvectiveProcessor2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
template
PostProcessorGenerator2D*
FreeEnergyConvectiveProcessorGenerator2D::clone() const
{
return new FreeEnergyConvectiveProcessorGenerator2D
(this->x0, this->x1, this->y0, this->y1, discreteNormalX, discreteNormalY);
}
} // namespace olb
#endif