/* This file is part of the OpenLB library
*
* Copyright (C) 2017 Albert Mink
* 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 RTLBM_BOUNDARY_DYNAMICS_HH
#define RTLBM_BOUNDARY_DYNAMICS_HH
#include "rtlbmBoundaryDynamics.h"
#include "dynamics/lbHelpers.h"
namespace olb {
// flat diffuse
template
RtlbmDiffuseBoundaryDynamics::RtlbmDiffuseBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
typedef DESCRIPTOR L;
T dirichletTemperature = this->_momenta.computeRho(cell);
std::vector const missing_iPop = util::subIndexOutgoing();
// compute summ of weights for all missing directions
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
// construct missing directions such that 0th moment equals emposed dirichletTemperature
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseBoundaryDynamics::setOmega(T omega_)
{
}
// edge diffuse
template
RtlbmDiffuseEdgeBoundaryDynamics::RtlbmDiffuseEdgeBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseEdgeBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseEdgeBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
typedef DESCRIPTOR L;
T dirichletTemperature = this->_momenta.computeRho(cell);
std::vector missing_iPop = util::subIndexOutgoing3DonEdges();
// compute summ of weights for all missing directions
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
// construct missing directions such that 0th moment equals emposed dirichletTemperature
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseEdgeBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseEdgeBoundaryDynamics::setOmega(T omega_)
{
}
// corner diffuse
template
RtlbmDiffuseCornerBoundaryDynamics::RtlbmDiffuseCornerBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseCornerBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseCornerBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
typedef DESCRIPTOR L;
T dirichletTemperature = this->_momenta.computeRho(cell);
std::vector const missing_iPop = util::subIndexOutgoing3DonCorners();
// compute summ of weights for all missing directions
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
// construct missing directions such that 0th moment equals emposed dirichletTemperature
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseCornerBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseCornerBoundaryDynamics::setOmega(T omega_)
{
}
// flat diffuse constant density
template
RtlbmDiffuseConstBoundaryDynamics::RtlbmDiffuseConstBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseConstBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseConstBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
// For direction i \in I_in define
// cell_i = w_i * dirichlet/sumWeights - w_i
// For direction i \in I_out defube
// cell_i = - w_i
// This construction yields
// sum_{i=0}^{q-1} cell_i == dirichlet - 1
typedef DESCRIPTOR L;
// shift all: cell_i = f_i - weight_i
for ( int iPop = 0; iPop < L::q; ++iPop ) {
cell[iPop] = - descriptors::t(iPop);
}
std::vector const missing_iPop = util::subIndexOutgoing();
// compute summ of weights for all missing directions
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
// construct missing directions such that 0th moment equals emposed dirichletTemperature
T dirichletTemperature = this->_momenta.computeRho(cell);
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseConstBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseConstBoundaryDynamics::setOmega(T omega_)
{
}
// edge diffuse with constant density
template
RtlbmDiffuseConstEdgeBoundaryDynamics::RtlbmDiffuseConstEdgeBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseConstEdgeBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseConstEdgeBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
// For direction i \in I_in define
// cell_i = w_i * dirichlet/sumWeights - w_i
// For direction i \in I_out defube
// cell_i = - w_i
// This construction yields
// sum_{i=0}^{q-1} cell_i == dirichlet - 1
typedef DESCRIPTOR L;
// shift all: cell_i = f_i - weight_i
for ( int iPop = 0; iPop < L::q; ++iPop ) {
cell[iPop] = - descriptors::t(iPop);
}
std::vector missing_iPop = util::subIndexOutgoing3DonEdges();
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
T dirichletTemperature = this->_momenta.computeRho(cell);
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseConstEdgeBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseConstEdgeBoundaryDynamics::setOmega(T omega_)
{
}
// corner diffuse with constant density
template
RtlbmDiffuseConstCornerBoundaryDynamics::RtlbmDiffuseConstCornerBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDiffuseConstCornerBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return descriptors::t(iPop)*rho - descriptors::t(iPop);
}
template
void RtlbmDiffuseConstCornerBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
// For direction i \in I_in define
// cell_i = w_i * dirichlet/sumWeights - w_i
// For direction i \in I_out defube
// cell_i = - w_i
// This construction yields
// sum_{i=0}^{q-1} cell_i == dirichlet - 1
typedef DESCRIPTOR L;
// shift all: cell_i = f_i - weight_i
for ( int iPop = 0; iPop < L::q; ++iPop ) {
cell[iPop] = - descriptors::t(iPop);
}
std::vector const missing_iPop = util::subIndexOutgoing3DonCorners();
double sumWeights = 0;
for ( int i : missing_iPop ) {
sumWeights += descriptors::t(i);
}
T dirichletTemperature = this->_momenta.computeRho(cell);
for ( int i : missing_iPop ) {
cell[i] = descriptors::t(i)*dirichletTemperature/sumWeights - descriptors::t(i);
}
}
template
T RtlbmDiffuseConstCornerBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDiffuseConstCornerBoundaryDynamics::setOmega(T omega_)
{
}
// directed wall
template
RtlbmDirectedBoundaryDynamics::RtlbmDirectedBoundaryDynamics( T omega_, Momenta& momenta_)
: BasicDynamics(momenta_)
{
}
template
T RtlbmDirectedBoundaryDynamics::computeEquilibrium(int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
return lbHelpers::equilibriumFirstOrder( iPop, rho, u );
}
template
void RtlbmDirectedBoundaryDynamics::collide(Cell& cell,LatticeStatistics& statistics)
{
typedef DESCRIPTOR L;
T dirichletTemperature = this->_momenta.computeRho(cell);
for( int iPop = 0; iPop < L::q; ++iPop ) {
cell[iPop] = - descriptors::t(iPop);
}
std::vector const missingDiagonal = util::subIndexOutgoing();
for ( int i : missingDiagonal ) {
// compute norm of c_iPopMissing
// is direction axis parallel
if ( util::normSqr(descriptors::c(i)) == 1 ) {
cell[i] = dirichletTemperature - descriptors::t(i);
}
}
}
template
T RtlbmDirectedBoundaryDynamics::getOmega() const
{
return T(-1);
}
template
void RtlbmDirectedBoundaryDynamics::setOmega(T omega_)
{
}
} // namespace olb
#endif