/* This file is part of the OpenLB library
*
* Copyright (C) 2012-2015 Mathias J. Krause, Jonas Latt, Patrick Nathen
* 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
* BGK Dynamics with adjusted omega -- generic implementation.
*/
#ifndef SMAGORINSKY_BGK_DYNAMICS_HH
#define SMAGORINSKY_BGK_DYNAMICS_HH
#include "smagorinskyBGKdynamics.h"
#include "core/cell.h"
#include "core/util.h"
#include "lbHelpers.h"
#include "math.h"
#include // For shear kalman Smagorinsky - Populations
namespace olb {
/// Smagorinsky Dynamics
template
SmagorinskyDynamics::SmagorinskyDynamics(T smagoConst_)
: smagoConst(smagoConst_), preFactor(computePreFactor())
{ }
template
T SmagorinskyDynamics::computePreFactor()
{
return (T)smagoConst*smagoConst*descriptors::invCs2()*descriptors::invCs2()*2*sqrt(2);
}
template
T SmagorinskyDynamics::getPreFactor()
{
return preFactor;
}
template
T SmagorinskyDynamics::getSmagoConst()
{
return smagoConst;
}
///////////////////////// ADM BGK /////////////////////////////
/*template
ADMBGKdynamics::ADMBGKdynamics(T omega_, Momenta& momenta_ )
: BGKdynamics(omega_,momenta_), omega(omega_)
{ }
template
void ADMBGKdynamics::collide(Cell& cell, LatticeStatistics& statistics )
{
T uSqr = lbHelpers::bgkCollision(cell, *cell., cell[velocityBeginsAt], omega);
statistics.incrementStats(*cell[rhoIsAt], uSqr);
}*/
///////////////////////// ForcedADM BGK /////////////////////////////
template
ForcedADMBGKdynamics::ForcedADMBGKdynamics (
T omega_, Momenta& momenta_ )
: BGKdynamics(omega_,momenta_),
omega(omega_)
{ }
template
void ForcedADMBGKdynamics::collide (
Cell& cell,
LatticeStatistics& statistics )
{
OstreamManager clout(std::cout,"Forced ADM collide:");
T rho, u[DESCRIPTOR::d], utst[DESCRIPTOR::d];
// this->momenta.computeAllMomenta(cell, rho, utst, pi);
T* rho_fil = cell.template getFieldPointer();
T* u_filX = cell.template getFieldPointer();
T* u_filY = cell.template getFieldPointer();
T* u_filZ = cell.template getFieldPointer();
u[0] = *u_filX;/// *rho_fil;
u[1] = *u_filY;/// *rho_fil;
u[2] = *u_filZ;/// *rho_fil;
T* force = cell.template getFieldPointer();
for (int iVel=0; iVel::bgkCollision(cell, *rho_fil, u, omega);
lbHelpers::addExternalForce(cell, u, omega);
statistics.incrementStats(rho, uSqr);
}
///////////////////// Class ConSmagorinskyBGKdynamics //////////////////////////
/////////////////// Consistent Smagorinsky BGK --> Malaspinas/Sagaut //////////////
template
ConSmagorinskyBGKdynamics::ConSmagorinskyBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
T ConSmagorinskyBGKdynamics::computeEffectiveOmega (Cell& cell)
{
T H[util::TensorVal::n];
T conSmagoR[DESCRIPTOR::q];
T S[util::TensorVal::n];
T tau_mol = 1./this->getOmega();
T cs2 = 1./descriptors::invCs2();
T smagoConst = this->getSmagoConst();
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(2*PiNeqNormSqr);
//Strain rate Tensor
if (PiNeqNorm != 0) {
T Phi = (-0.5*(-rho*tau_mol*cs2+sqrt(rho*rho*tau_mol*tau_mol*cs2*cs2+2.0*(smagoConst*smagoConst)*rho*PiNeqNorm))/(smagoConst*smagoConst*rho*PiNeqNorm));
for (int n = 0; n < util::TensorVal::n; ++n) {
S[n] = Phi*pi[n];
}
} else {
for (int n = 0; n < util::TensorVal::n; ++n) {
S[n] = 0;
}
}
//Strain rate Tensor Norm
T SNormSqr = S[0]*S[0] + 2.0*S[1]*S[1] + S[2]*S[2];
if (util::TensorVal::n == 6) {
SNormSqr += S[2]*S[2] + S[3]*S[3] + 2.0*S[4]*S[4] + S[5]*S[5];
}
T SNorm = sqrt(2*SNormSqr);
//consistent Samagorinsky additional R term
for (int q = 0; q < DESCRIPTOR::q; ++q) {
T t = descriptors::t(q); //lattice weights
//Hermite-Polynom H = c*c-cs^2*kronDelta
H[0] = descriptors::c(q,0)*descriptors::c(q,0)-cs2;
H[1] = descriptors::c(q,0)*descriptors::c(q,1);
H[2] = descriptors::c(q,1)*descriptors::c(q,1)-cs2;//2D
if (util::TensorVal::n == 6) {
H[2] = descriptors::c(q,0)*descriptors::c(q,2);//3D
H[3] = descriptors::c(q,1)*descriptors::c(q,1)-cs2;
H[4] = descriptors::c(q,1)*descriptors::c(q,2);
H[5] = descriptors::c(q,2)*descriptors::c(q,2)-cs2;
}
//contraction or scalar product H*S
T contractHS = H[0]*S[0] + 2.0*H[1]*S[1] + H[2]*S[2];
if (util::TensorVal::n == 6) {
contractHS += H[2]*S[2] + H[3]*S[3] + 2.0*H[4]*S[4] + H[5]*S[5];
}
//additional term
conSmagoR[q] = t*this->getPreFactor()*SNorm*contractHS;
}
return conSmagoR[0];
}
/////////////////// Consistent Strain Smagorinsky BGK --> Malaspinas/Sagaut //////////////
template
ConStrainSmagorinskyBGKdynamics::ConStrainSmagorinskyBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
T ConStrainSmagorinskyBGKdynamics::computeEffectiveOmega(Cell& cell)
{
T S[util::TensorVal::n];
T cs2 = 1./descriptors::invCs2();
T tau_mol = 1./this->getOmega();
T smagoConst_ = this->getSmagoConst();
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2.0*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(2*PiNeqNormSqr);
//Strain Tensor
if ( !util::nearZero(PiNeqNorm) ) {
T Phi = (-0.5*(-rho*tau_mol*cs2+sqrt(rho*rho*tau_mol*tau_mol*cs2*cs2+2.0*(smagoConst_*smagoConst_)*rho*PiNeqNorm))/(smagoConst_*smagoConst_*rho*PiNeqNorm));
for (int n = 0; n < util::TensorVal::n; ++n) {
S[n] = Phi*pi[n];
}
} else {
for (int n = 0; n < util::TensorVal::n; ++n) {
S[n] = 0;
}
}
//Strain Tensor Norm
T SNormSqr = S[0]*S[0] + 2.0*S[1]*S[1] + S[2]*S[2];
if (util::TensorVal::n == 6) {
SNormSqr += S[2]*S[2] + S[3]*S[3] + 2.0*S[4]*S[4] + S[5]*S[5];
}
T SNorm = sqrt(2*SNormSqr);
/// Turbulent realaxation time
T tau_turb = pow(smagoConst_,2)*SNorm/cs2;
/// Effective realaxation time
T tau_eff = tau_mol+tau_turb;
T omega_new= 1./tau_eff;
return omega_new;
}
///////////////////////// DYNAMIC SMAGO BGK /////////////////////////////
template
DynSmagorinskyBGKdynamics::DynSmagorinskyBGKdynamics (
T omega_, Momenta& momenta_)
: SmagorinskyBGKdynamics(omega_, momenta_, T(0.))
{ }
template
T DynSmagorinskyBGKdynamics::computeEffectiveOmega(Cell& cell)
{
// computation of the relaxation time
T v_t = 0;
T* dynSmago = cell.template getFieldPointer();
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
//v_t = *dynSmago*dx*dx*PiNeqNorm;
v_t = *dynSmago*PiNeqNorm;
T tau_t = 3*v_t;
T tau_0 = 1/this->getOmega();
T omega_new = 1/(tau_t+tau_0);
return omega_new;
}
///////////////////SHEAR IMPROVED SMAGORINSKY//////////////////////////
template
ShearSmagorinskyBGKdynamics::ShearSmagorinskyBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
void ShearSmagorinskyBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newOmega = computeEffectiveOmega(cell,statistics.getTime());
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, newOmega);
statistics.incrementStats(rho, uSqr);
}
template
T ShearSmagorinskyBGKdynamics::getEffectiveOmega(Cell& cell)
{
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
// computation of the relaxation time
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
T* avShear = cell.template getFieldPointer();
T tau_0 = 1./this->getOmega();
T PiNeqNorm_SISM = PiNeqNorm - *avShear;
T tau_t = 0.5*(sqrt(tau_0*tau_0+(this->getPreFactor()*PiNeqNorm_SISM/rho))-tau_0);
T omega_new = 1./(tau_t+tau_0);
return omega_new;
}
template
T ShearSmagorinskyBGKdynamics::computeEffectiveOmega(Cell& cell, int iT)
{
OstreamManager clout(std::cout,"shearImprovedCollide");
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
// computation of the relaxation time
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
T* avShear = cell.template getFieldPointer();
*avShear = (*avShear*iT + PiNeqNorm)/(iT+1);
T tau_0 = 1./this->getOmega();
T PiNeqNorm_SISM = PiNeqNorm - *avShear;
T tau_t = 0.5*(sqrt(tau_0*tau_0+(this->getPreFactor()*PiNeqNorm_SISM/rho))-tau_0);
T omega_new = 1./(tau_t+tau_0);
return omega_new;
}
///////////////////////// FORCED SHEAR SMAGO BGK /////////////////////////////
template
ShearSmagorinskyForcedBGKdynamics::ShearSmagorinskyForcedBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyForcedBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
void ShearSmagorinskyForcedBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newOmega = computeEffectiveOmega(cell, statistics.getTime());
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T* force = cell.template getFieldPointer();
for (int iVel=0; iVel::bgkCollision(cell, rho, u, newOmega);
lbHelpers::addExternalForce(cell, u, newOmega, rho);
statistics.incrementStats(rho, uSqr);
}
template
T ShearSmagorinskyForcedBGKdynamics::getEffectiveOmega(Cell& cell)
{
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
// computation of the relaxation time
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
T* avShear = cell.template getFieldPointer();
T tau_0 = 1./this->getOmega();
T PiNeqNorm_SISM = PiNeqNorm - *avShear;
T tau_t = 0.5*(sqrt(tau_0*tau_0+(this->getPreFactor()*PiNeqNorm_SISM/rho))-tau_0);
T omega_new = 1./(tau_t+tau_0);
return omega_new;
}
template
T ShearSmagorinskyForcedBGKdynamics::computeEffectiveOmega(Cell& cell, int iT)
{
OstreamManager clout(std::cout,"shearImprovedCollide");
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
//Creation of body force tensor (rho/2.)*(G_alpha*U_beta + U_alpha*G_Beta)
T ForceTensor[util::TensorVal::n];
int iPi = 0;
for (int Alpha=0; Alpha()[Alpha]*u[Beta] + u[Alpha]*cell.template getFieldPointer()[Beta]);
++iPi;
}
}
// Creation of second-order moment off-equilibrium tensor
for (int iPi=0; iPi < util::TensorVal::n; ++iPi){
pi[iPi] += ForceTensor[iPi];
}
// computation of the relaxation time
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
T* avShear = cell.template getFieldPointer();
*avShear = (*avShear*iT+PiNeqNorm)/(iT+1);
T tau_0 = 1./this->getOmega();
T PiNeqNorm_SISM = PiNeqNorm - *avShear;
T tau_t = 0.5*(sqrt(tau_0*tau_0+(this->getPreFactor()*PiNeqNorm_SISM/rho))-tau_0);
T omega_new = 1./(tau_t+tau_0);
return omega_new;
}
////////////////////// Class SmagorinskyBGKdynamics //////////////////////////
/** \param vs2_ speed of sound
* \param momenta_ a Momenta object to know how to compute velocity momenta
* \param momenta_ a Momenta object to know how to compute velocity momenta
*/
template
SmagorinskyBGKdynamics::SmagorinskyBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyDynamics(smagoConst_),
BGKdynamics(omega_,momenta_)
{ }
template
void SmagorinskyBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newOmega = computeEffectiveOmega(cell);
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, newOmega);
statistics.incrementStats(rho, uSqr);
}
template
T SmagorinskyBGKdynamics::getEffectiveOmega(Cell& cell)
{
T newOmega = computeEffectiveOmega(cell);
return newOmega;
}
template
T SmagorinskyBGKdynamics::computeEffectiveOmega(Cell& cell)
{
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
/// Molecular realaxation time
T tau_mol = 1. /this->getOmega();
/// Turbulent realaxation time
T tau_turb = 0.5*(sqrt(tau_mol*tau_mol + this->getPreFactor()/rho*PiNeqNorm) - tau_mol);
/// Effective realaxation time
T tau_eff = tau_mol+tau_turb;
T omega_new= 1./tau_eff;
return omega_new;
}
///////////////////////// FORCED SMAGO BGK /////////////////////////////
template
SmagorinskyForcedBGKdynamics::SmagorinskyForcedBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyDynamics(smagoConst_),
ForcedBGKdynamics(omega_,momenta_)
{ }
template
void SmagorinskyForcedBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newOmega = computeEffectiveOmega(cell);
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T* force = cell.template getFieldPointer();
for (int iVel=0; iVel::bgkCollision(cell, rho, u, newOmega);
lbHelpers::addExternalForce(cell, u, newOmega, rho);
statistics.incrementStats(rho, uSqr);
}
template
T SmagorinskyForcedBGKdynamics::getEffectiveOmega(Cell& cell)
{
T newOmega = computeEffectiveOmega(cell);
return newOmega;
}
template
T SmagorinskyForcedBGKdynamics::computeEffectiveOmega(Cell& cell)
{
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
//Creation of body force tensor (rho/2.)*(G_alpha*U_beta + U_alpha*G_Beta)
T ForceTensor[util::TensorVal::n];
int iPi = 0;
for (int Alpha=0; Alpha()[Alpha]*u[Beta] + u[Alpha]*cell.template getFieldPointer()[Beta]);
++iPi;
}
}
// Creation of second-order moment off-equilibrium tensor
for (int iPi=0; iPi < util::TensorVal::n; ++iPi){
pi[iPi] += ForceTensor[iPi];
}
T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
if (util::TensorVal::n == 6) {
PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
}
T PiNeqNorm = sqrt(PiNeqNormSqr);
/// Molecular realaxation time
T tau_mol = 1. /this->getOmega();
/// Turbulent realaxation time
T tau_turb = 0.5*(sqrt(tau_mol*tau_mol + this->getPreFactor()/rho*PiNeqNorm) - tau_mol);
/// Effective realaxation time
T tau_eff = tau_mol+tau_turb;
T omega_new= 1./tau_eff;
return omega_new;
}
///////////////////////// External TAU EFF LES BGK /////////////////////////////
template
ExternalTauEffLESBGKdynamics::ExternalTauEffLESBGKdynamics(T omega_, Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
void ExternalTauEffLESBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newTau = *(cell.template getFieldPointer());
T newOmega = 1./newTau;
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, newOmega);
statistics.incrementStats(rho, uSqr);
}
///////////////////////// External TAU EFF FORCED LES BGK /////////////////////////////
template
ExternalTauEffLESForcedBGKdynamics::ExternalTauEffLESForcedBGKdynamics(T omega_, Momenta& momenta_, T smagoConst_)
: SmagorinskyForcedBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
void ExternalTauEffLESForcedBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T newTau = *(cell.template getFieldPointer());
T newOmega = 1./newTau;
T rho, u[DESCRIPTOR::d];
this->_momenta.computeRhoU(cell, rho, u);
T* force = cell.template getFieldPointer();
for (int iVel=0; iVel::bgkCollision(cell, rho, u, newOmega);
lbHelpers::addExternalForce(cell, u, newOmega, rho);
statistics.incrementStats(rho, uSqr);
}
///////////////////////// FORCED Linear Velocity SMAGO BGK /////////////////////////////
template
SmagorinskyLinearVelocityForcedBGKdynamics::SmagorinskyLinearVelocityForcedBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyForcedBGKdynamics(omega_, momenta_, smagoConst_)
{ }
template
void SmagorinskyLinearVelocityForcedBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T rho, u[DESCRIPTOR::d], pi[util::TensorVal::n];
this->_momenta.computeAllMomenta(cell, rho, u, pi);
T newOmega = computeEffectiveOmega(cell);
T* force = cell.template getFieldPointer();
int nDim = DESCRIPTOR::d;
T forceSave[nDim];
// adds a+Bu to force, where
// d=2: a1=v[0], a2=v[1], B11=v[2], B12=v[3], B21=v[4], B22=v[5]
// d=2: a1=v[0], a2=v[1], a3=v[2], B11=v[3], B12=v[4], B13=v[5], B21=v[6], B22=v[7], B23=v[8], B31=v[9], B32=v[10], B33=v[11]
T* v = cell.template getFieldPointer();
for (int iDim=0; iDim::bgkCollision(cell, rho, u, newOmega);
lbHelpers::addExternalForce(cell, u, newOmega, rho);
statistics.incrementStats(rho, uSqr);
// Writing back to froce fector
for (int iVel=0; iVel
KrauseBGKdynamics::KrauseBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_),
preFactor(computePreFactor() )
{ }
template
void KrauseBGKdynamics::collide(Cell& cell,
LatticeStatistics& statistics )
{
T rho, u[DESCRIPTOR::d];
T newOmega[DESCRIPTOR::q];
this->_momenta.computeRhoU(cell, rho, u);
computeEffectiveOmega(this->getOmega(), cell, preFactor, rho, u, newOmega);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, newOmega);
statistics.incrementStats(rho, uSqr);
}
template
T KrauseBGKdynamics::getEffectiveOmega(Cell& cell)
{
T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal::n];
T newOmega[DESCRIPTOR::q];
this->_momenta.computeAllMomenta(cell, rho, uTemp, pi);
computeEffectiveOmega(this->getOmega(), cell, preFactor, rho, uTemp, newOmega);
T newOmega_average = 0.;
for (int iPop=0; iPop
T KrauseBGKdynamics::computePreFactor()
{
return (T)this->getSmagoConst()*this->getSmagoConst()*3*descriptors::invCs2()*descriptors::invCs2()*2*sqrt(2);
}
template
void KrauseBGKdynamics::computeEffectiveOmega(T omega0, Cell& cell, T preFactor_, T rho,
T u[DESCRIPTOR::d], T newOmega[DESCRIPTOR::q])
{
T uSqr = u[0]*u[0];
for (int iDim=0; iDim::equilibrium(iPop, rho, u, uSqr));
/// Turbulent realaxation time
T tau_turb = 0.5*(sqrt(tau_mol*tau_mol + preFactor_/rho*fNeq) - tau_mol);
/// Effective realaxation time
T tau_eff = tau_mol + tau_turb;
newOmega[iPop] = 1./tau_eff;
}
}
////////////////////// Class WALEBGKdynamics //////////////////////////
/** \param vs2_ speed of sound
* \param momenta_ a Momenta object to know how to compute velocity momenta
* \param momenta_ a Momenta object to know how to compute velocity momenta
*/
template
WALEBGKdynamics::WALEBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyBGKdynamics(omega_, momenta_, smagoConst_)
{
this->preFactor = this->getSmagoConst()*this->getSmagoConst();
}
template
T WALEBGKdynamics::computePreFactor()
{
return (T)this->getSmagoConst()*this->getSmagoConst();
}
template
T WALEBGKdynamics::computeEffectiveOmega(Cell& cell_)
{
// velocity gradient tensor
T g[3][3];
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
g[i][j] = *(cell_.template getFieldPointer()+(i*3 + j));
}
}
// strain rate tensor
T s[3][3];
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
s[i][j] = (g[i][j] + g[j][i]) / 2.;
}
}
// traceless symmetric part of the square of the velocity gradient tensor
T G[3][3];
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
G[i][j] = 0.;
}
}
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
for ( int k = 0; k < 3; k++) {
G[i][j] += (g[i][k]*g[k][j] + g[j][k]*g[k][i]) / 2.; // The change
}
}
}
T trace = 0.;
for ( int i = 0; i < 3; i++) {
trace += (1./3.) * g[i][i] * g[i][i];
}
for ( int i = 0; i < 3; i++) {
G[i][i] -= trace;
}
// inner product of the traceless symmetric part of the square of the velocity gradient tensor
T G_ip = 0;
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
G_ip = G[i][j] * G[i][j];
}
}
// inner product of the strain rate
T s_ip = 0;
for ( int i = 0; i < 3; i++) {
for ( int j = 0; j < 3; j++) {
s_ip = s[i][j] * s[i][j];
}
}
// Turbulent relaxation time
T tau_turb = 3. * this->getPreFactor() * (pow(G_ip,1.5) / (pow(s_ip,2.5) + pow(G_ip,1.25)));
if ((pow(s_ip,2.5) + pow(G_ip,1.25)) == 0) {
tau_turb = 0.;
}
// Physical turbulent viscosity must be equal or higher that zero
if (tau_turb < 0.) {
tau_turb = 0.;
}
/// Molecular relaxation time
T tau_mol = 1. /this->getOmega();
/// Effective relaxation time
T tau_eff = tau_mol + tau_turb;
T omega_new = 1. / tau_eff;
return omega_new;
}
////////////////////// Class WALEForcedBGKdynamics //////////////////////////
/** \param vs2_ speed of sound
* \param momenta_ a Momenta object to know how to compute velocity momenta
* \param momenta_ a Momenta object to know how to compute velocity momenta
*/
template
WALEForcedBGKdynamics::WALEForcedBGKdynamics(T omega_,
Momenta& momenta_, T smagoConst_)
: SmagorinskyForcedBGKdynamics(omega_, momenta_, smagoConst_)
{
this->preFactor = this->getSmagoConst()*this->getSmagoConst();
}
template
T WALEForcedBGKdynamics::computePreFactor()
{
return (T)this->getSmagoConst()*this->getSmagoConst();
}
template
T WALEForcedBGKdynamics