BoundaryConditions.h 14.87 KiB
//=======================================================================================
// ____ ____ __ ______ __________ __ __ __ __
// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
// \ \ | | | | | |_) | | | | | | | / \ | |
// \ \ | | | | | _ / | | | | | | / /\ \ | |
// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
// \ \ | | ________________________________________________________________
// \ \ | | | ______________________________________________________________|
// \ \| | | | __ __ __ __ ______ _______
// \ | | |_____ | | | | | | | | | _ \ / _____)
// \ | | _____| | | | | | | | | | | \ \ \_______
// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
// \ _____| |__| |________| \_______/ |__| |______/ (_______/
//
// This file is part of VirtualFluids. VirtualFluids 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 3 of
// the License, or (at your option) any later version.
//
// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file BoundaryConditions.h
//! \ingroup BoundarConditions
//! \author Sören Freudiger
//=======================================================================================
#ifndef BoundaryConditions_H
#define BoundaryConditions_H
#include <string>
#include <vector>
#include "D3Q27System.h"
#include "UbException.h"
#include "UbSystem.h"
#include "UbTuple.h"
#include "Vector3D.h"
#include <PointerDefinitions.h>
//! Difenition of baundary conditions in grid generation
class BoundaryConditions
{
public:
BoundaryConditions()
{
UB_STATIC_ASSERT(sizeof(long long) >= 8);
UB_STATIC_ASSERT((sizeof(long long) * 8) >= (D3Q27System::FENDDIR + 1) * BoundaryConditions::optionDigits);
for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++)
q[fdir] = -999.;
}
virtual ~BoundaryConditions() = default;
virtual bool isEmpty()
{
return (noslipBoundaryFlags & slipBoundaryFlags & velocityBoundaryFlags & densityBoundaryFlags) == 0;
}
virtual bool hasBoundaryCondition()
{
return (hasNoSlipBoundary() || hasSlipBoundary() || hasDensityBoundary() || hasVelocityBoundary() ||
hasWallModelBoundary());
}
virtual bool hasBoundaryConditionFlag(const int &direction)
{
assert(direction >= D3Q27System::FSTARTDIR && direction <= D3Q27System::FENDDIR);
return (hasNoSlipBoundaryFlag(direction) || hasSlipBoundaryFlag(direction) ||
hasDensityBoundaryFlag(direction) || hasVelocityBoundaryFlag(direction) ||
hasWallModelBoundaryFlag(direction));
}
protected:
void setFlagBits(long long &flag, const int &direction, const short &secOpt)
{
if ((secOpt + 1) > maxOptionVal)
throw UbException(UB_EXARGS, "error: option > " + UbSystem::toString(maxOptionVal - 1));
// all digits at the respective positions to "0"
flag &= ~(maxOptionVal << (direction * optionDigits));
// set all digits according to the flag at the respective positions
flag |= ((long long)(secOpt + 1) << (direction * optionDigits));
}
public:
/*===================== NoSlip Boundary ==================================================*/
void setNoSlipBoundaryFlag(const int &direction, const short &secOpt = 0)
{
this->setFlagBits(noslipBoundaryFlags, direction, secOpt);
}
void unsetNoSlipBoundaryFlag(const int &direction)
{
this->noslipBoundaryFlags &= ~(maxOptionVal << (direction * optionDigits));
}
void unsetNoSlipBoundary() { this->noslipBoundaryFlags = 0; }
long long getNoSlipBoundary() { return this->noslipBoundaryFlags; }
bool hasNoSlipBoundary() { return (noslipBoundaryFlags != 0); }
bool hasNoSlipBoundaryFlag(const int &direction)
{
return (((noslipBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) != 0);
}
short getNoSlipSecondaryOption(const int &direction)
{
return (short)(((noslipBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) - 1);
}
/*===================== WallModel Boundary ==================================================*/
void setWallModelBoundaryFlag(const int &direction, const short &secOpt = 0)
{
this->setFlagBits(wallModelBoundaryFlags, direction, secOpt);
}
void unsetWallModelBoundaryFlag(const int &direction)
{
this->wallModelBoundaryFlags &= ~(maxOptionVal << (direction * optionDigits));
}
void unsetWallModelBoundary() { this->wallModelBoundaryFlags = 0; }
long long getWallModelBoundary() { return this->wallModelBoundaryFlags; }
bool hasWallModelBoundary() { return (wallModelBoundaryFlags != 0); }
bool hasWallModelBoundaryFlag(const int &direction)
{
return (((wallModelBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) != 0);
}
short getWallModelSecondaryOption(const int &direction)
{
return (short)(((wallModelBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) - 1);
}
/*===================== Slip-Solid Boundary ==================================================*/
void setSlipBoundaryFlag(const int &direction, const short &secOpt = 0)
{
this->setFlagBits(slipBoundaryFlags, direction, secOpt);
}
void unsetSlipBoundaryFlag(const int &direction)
{
this->slipBoundaryFlags &= ~(maxOptionVal << (direction * optionDigits));
}
void unsetSlipBoundary() { this->slipBoundaryFlags = 0; }
long long getSlipBoundary() { return this->slipBoundaryFlags; }
bool hasSlipBoundary() { return (slipBoundaryFlags != 0); }
bool hasSlipBoundaryFlag(const int &direction)
{
return (((slipBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) != 0);
}
short getSlipSecondaryOption(const int &direction)
{
return (short)(((slipBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) - 1);
}
void setNormalVector(const float &nx1, const float &nx2, const float &nx3)
{
this->nx1 = nx1;
this->nx2 = nx2;
this->nx3 = nx3;
}
UbTupleFloat3 getNormalVector() { return makeUbTuple(nx1, nx2, nx3); }
/*============== Velocity Boundary ========================*/
void setVelocityBoundaryFlag(const int &direction, const short &secOpt = 0)
{
this->setFlagBits(velocityBoundaryFlags, direction, secOpt);
}
void unsetVelocityBoundaryFlag(const int &direction)
{
this->velocityBoundaryFlags &= ~(maxOptionVal << (direction * optionDigits));
}
void unsetVelocityBoundary() { this->velocityBoundaryFlags = 0; }
long long getVelocityBoundary() { return this->velocityBoundaryFlags; }
bool hasVelocityBoundary() { return this->velocityBoundaryFlags != 0; }
bool hasVelocityBoundaryFlag(const int &direction)
{
return (((velocityBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) != 0);
}
short getVelocitySecondaryOption(const int &direction)
{
return (short)(((velocityBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) - 1);
}
void setBoundaryVelocity(const Vector3D &vx)
{
setBoundaryVelocityX1((float)vx[0]);
setBoundaryVelocityX2((float)vx[1]);
setBoundaryVelocityX3((float)vx[2]);
}
void setBoundaryVelocityX1(const float &vx1) { this->bcVelocityX1 = vx1; }
void setBoundaryVelocityX2(const float &vx2) { this->bcVelocityX2 = vx2; }
void setBoundaryVelocityX3(const float &vx3) { this->bcVelocityX3 = vx3; }
float getBoundaryVelocityX1() { return this->bcVelocityX1; }
float getBoundaryVelocityX2() { return this->bcVelocityX2; }
float getBoundaryVelocityX3() { return this->bcVelocityX3; }
float getBoundaryVelocity(const int &direction)
{
switch (direction) {
case D3Q27System::E:
return (float)(UbMath::c4o9 *
(+bcVelocityX1)); //(2/cs^2)(=6)*rho_0(=1 bei inkompr)*wi*u*ei mit cs=1/sqrt(3)
case D3Q27System::W:
return (float)(UbMath::c4o9 *
(-bcVelocityX1)); // z.B. aus paper manfred MRT LB models in three dimensions (2002)
case D3Q27System::N:
return (float)(UbMath::c4o9 * (+bcVelocityX2));
case D3Q27System::S:
return (float)(UbMath::c4o9 * (-bcVelocityX2));
case D3Q27System::T:
return (float)(UbMath::c4o9 * (+bcVelocityX3));
case D3Q27System::B:
return (float)(UbMath::c4o9 * (-bcVelocityX3));
case D3Q27System::NE:
return (float)(UbMath::c1o9 * (+bcVelocityX1 + bcVelocityX2));
case D3Q27System::SW:
return (float)(UbMath::c1o9 * (-bcVelocityX1 - bcVelocityX2));
case D3Q27System::SE:
return (float)(UbMath::c1o9 * (+bcVelocityX1 - bcVelocityX2));
case D3Q27System::NW:
return (float)(UbMath::c1o9 * (-bcVelocityX1 + bcVelocityX2));
case D3Q27System::TE:
return (float)(UbMath::c1o9 * (+bcVelocityX1 + bcVelocityX3));
case D3Q27System::BW:
return (float)(UbMath::c1o9 * (-bcVelocityX1 - bcVelocityX3));
case D3Q27System::BE:
return (float)(UbMath::c1o9 * (+bcVelocityX1 - bcVelocityX3));
case D3Q27System::TW:
return (float)(UbMath::c1o9 * (-bcVelocityX1 + bcVelocityX3));
case D3Q27System::TN:
return (float)(UbMath::c1o9 * (+bcVelocityX2 + bcVelocityX3));
case D3Q27System::BS:
return (float)(UbMath::c1o9 * (-bcVelocityX2 - bcVelocityX3));
case D3Q27System::BN:
return (float)(UbMath::c1o9 * (+bcVelocityX2 - bcVelocityX3));
case D3Q27System::TS:
return (float)(UbMath::c1o9 * (-bcVelocityX2 + bcVelocityX3));
case D3Q27System::TNE:
return (float)(UbMath::c1o36 * (+bcVelocityX1 + bcVelocityX2 + bcVelocityX3));
case D3Q27System::BSW:
return (float)(UbMath::c1o36 * (-bcVelocityX1 - bcVelocityX2 - bcVelocityX3));
case D3Q27System::BNE:
return (float)(UbMath::c1o36 * (+bcVelocityX1 + bcVelocityX2 - bcVelocityX3));
case D3Q27System::TSW:
return (float)(UbMath::c1o36 * (-bcVelocityX1 - bcVelocityX2 + bcVelocityX3));
case D3Q27System::TSE:
return (float)(UbMath::c1o36 * (+bcVelocityX1 - bcVelocityX2 + bcVelocityX3));
case D3Q27System::BNW:
return (float)(UbMath::c1o36 * (-bcVelocityX1 + bcVelocityX2 - bcVelocityX3));
case D3Q27System::BSE:
return (float)(UbMath::c1o36 * (+bcVelocityX1 - bcVelocityX2 - bcVelocityX3));
case D3Q27System::TNW:
return (float)(UbMath::c1o36 * (-bcVelocityX1 + bcVelocityX2 + bcVelocityX3));
default:
throw UbException(UB_EXARGS, "unknown error");
}
}
//Multiphase
void setBoundaryPhaseField(const float &phiBC) { this->bcPhaseField = phiBC; }
float getBoundaryPhaseField() { return this->bcPhaseField; }
/*============== Density Boundary ========================*/
void setDensityBoundaryFlag(const int &direction, const short &secOpt = 0)
{
this->setFlagBits(densityBoundaryFlags, direction, secOpt);
}
void unsetDensityBoundaryFlag(const int &direction)
{
this->densityBoundaryFlags &= ~(maxOptionVal << (direction * optionDigits));
}
void unsetDensityBoundary() { this->densityBoundaryFlags = 0; }
long long getDensityBoundary() { return this->densityBoundaryFlags; }
bool hasDensityBoundary() { return (this->densityBoundaryFlags != 0); }
bool hasDensityBoundaryFlag(const int &direction)
{
return (((densityBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) != 0);
}
short getDensitySecondaryOption(const int &direction)
{
return (short)(((densityBoundaryFlags >> (optionDigits * direction)) & maxOptionVal) - 1);
}
void setBoundaryDensity(float density) { this->bcDensity = density; }
float getBoundaryDensity() { return this->bcDensity; }
/*======================= Qs =============================*/
void setQ(const float &val, const int &direction) { q[direction] = val; }
float getQ(const int &direction) { return q[direction]; }
virtual std::vector<std::string> getBCNames()
{
std::vector<std::string> tmp;
tmp.push_back("NoSlipBC");
tmp.push_back("SlipBC");
tmp.push_back("VelocityBC");
tmp.push_back("DensityBC");
return tmp;
}
virtual std::vector<long long> getBCFlags()
{
std::vector<long long> tmp;
tmp.push_back(noslipBoundaryFlags);
tmp.push_back(slipBoundaryFlags);
tmp.push_back(velocityBoundaryFlags);
tmp.push_back(densityBoundaryFlags);
return tmp;
}
static bool hasFlagForDirection(const long long &flag, const int &direction)
{
return (((flag >> (optionDigits * direction)) & maxOptionVal) != 0);
}
void setBcAlgorithmType(char alg) { algorithmType = alg; }
char getBcAlgorithmType() { return algorithmType; }
public:
static const int optionDigits = 2; //--> 2 bits for secondary Option --> maxOptionVal = 7
static const long long maxOptionVal; // = ( 1<<optionDigits ) - 1; //2^3-1 -> 7
protected:
float q[D3Q27System::FENDDIR + 1];
long long noslipBoundaryFlags{ 0 };
long long slipBoundaryFlags{ 0 };
long long velocityBoundaryFlags{ 0 };
long long densityBoundaryFlags{ 0 };
long long wallModelBoundaryFlags{ 0 };
float bcVelocityX1{ 0.0f };
float bcVelocityX2{ 0.0f };
float bcVelocityX3{ 0.0f };
float bcDensity{ 0.0f };
float bcPhaseField{ 0.0f };
float nx1{ 0.0f }, nx2{ 0.0f }, nx3{ 0.0f };
char algorithmType { -1 };
private:
friend class MPIIORestartCoProcessor;
friend class MPIIOMigrationCoProcessor;
friend class MPIIOMigrationBECoProcessor;
};
#endif