/* This file is part of the OpenLB library
*
* Copyright (C) 2016-2017 Davide Dapelo, Mathias J. Krause
* OpenLB 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
* Helper functions for the implementation of the
* Guo-ZhapLB dynamics.
*/
#ifndef LB_GUOZHAO_HELPERS_H
#define LB_GUOZHAO_HELPERS_H
#include "dynamics/guoZhaoLatticeDescriptors.h"
#include "core/cell.h"
#include "core/util.h"
namespace olb {
// Forward declarations
template struct GuoZhaoLbDynamicsHelpers;
template struct GuoZhaoLbExternalHelpers;
/// This structure forwards the calls to the appropriate Guo Zhao helper class
template
struct GuoZhaoLbHelpers {
static T equilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTOR::d], const T uSqr) {
return GuoZhaoLbDynamicsHelpers
::equilibrium(iPop, epsilon, rho, u, uSqr);
}
static T bgkCollision(Cell& cell, T const& epsilon, T const& rho, const T u[DESCRIPTOR::d], T const& omega) {
return GuoZhaoLbDynamicsHelpers
::bgkCollision(cell, epsilon, rho, u, omega);
}
static void updateGuoZhaoForce(Cell& cell, const T u[DESCRIPTOR::d]) {
GuoZhaoLbExternalHelpers::updateGuoZhaoForce(cell, u);
}
static void addExternalForce(Cell& cell, const T u[DESCRIPTOR::d], T omega, T rho, T epsilon=(T)1)
{
GuoZhaoLbExternalHelpers::addExternalForce(cell, u, omega, rho, epsilon);
}
}; // struct GuoZhaoLbHelpers
/// All Guo Zhao helper functions are inside this structure
template
struct GuoZhaoLbDynamicsHelpers {
/// Computation of Guo Zhao equilibrium distribution - original (compressible) formulation following Guo and Zhao (2002).
static T forceEquilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTORBASE::d], const T force[DESCRIPTORBASE::d], T nu) {
}
/// Computation of Guo Zhao equilibrium distribution - original (compressible) formulation following Guo and Zhao (2002).
static T equilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTORBASE::d], const T uSqr) {
T c_u = T();
for (int iD=0; iD < DESCRIPTORBASE::d; ++iD) {
c_u += descriptors::c(iPop,iD)*u[iD];
}
return rho * descriptors::t(iPop) * (
(T)1 + descriptors::invCs2() * c_u +
descriptors::invCs2() * descriptors::invCs2()/((T)2*epsilon) * c_u*c_u -
descriptors::invCs2()/((T)2*epsilon) * uSqr
) - descriptors::t(iPop);
}
/// Guo Zhao BGK collision step
static T bgkCollision(CellBase& cell, T const& epsilon, T const& rho, const T u[DESCRIPTORBASE::d], T const& omega) {
const T uSqr = util::normSqr(u);
for (int iPop=0; iPop < DESCRIPTORBASE::q; ++iPop) {
cell[iPop] *= (T)1-omega;
cell[iPop] += omega * GuoZhaoLbDynamicsHelpers::equilibrium (
iPop, epsilon, rho, u, uSqr );
}
return uSqr;
}
}; // struct GuoZhaoLbDynamicsHelpers
/// Helper functions for dynamics that access external field
template
/// Updates Guo Zhao porous force
struct GuoZhaoLbExternalHelpers {
static void updateGuoZhaoForce(Cell& cell, const T u[DESCRIPTOR::d]) {
T epsilon = *cell.template getFieldPointer();
T k = *cell.template getFieldPointer();
T nu = *cell.template getFieldPointer();
T* force[DESCRIPTOR::d];
for (int iDim=0; iDim () + iDim;
}
T bodyF[DESCRIPTOR::d];
for (int iDim=0; iDim ()[iDim];
}
T uMag = 0.;
for (int iDim=0; iDim & cell, const T u[DESCRIPTOR::d], T omega, T rho, T epsilon)
{
T* force = cell.template getFieldPointer();
for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
T c_u = T();
for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
c_u += descriptors::c(iPop,iD)*u[iD];
}
c_u *= descriptors::invCs2()*descriptors::invCs2()/epsilon;
T forceTerm = T();
for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
forceTerm +=
( (epsilon*(T)descriptors::c(iPop,iD)-u[iD]) * descriptors::invCs2()/epsilon
+ c_u * descriptors::c(iPop,iD)
)
* force[iD];
}
forceTerm *= descriptors::t(iPop);
forceTerm *= T(1) - omega/T(2);
forceTerm *= rho;
cell[iPop] += forceTerm;
}
}
}; // struct GuoZhaoLbExternalHelpers
} // namespace olb
#endif