/* This file is part of the OpenLB library
*
* Copyright (C) 2017-2019 Albert Mink, Christopher McHardy
* 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
* A collection of radiative transport dynamics classes -- generic implementation.
*/
#ifndef RTLBM_DYNAMICS_HH
#define RTLBM_DYNAMICS_HH
#include "rtlbmDynamics.h"
#include "rtlbmDescriptors.h"
#include "lbHelpers.h"
namespace olb {
//==================================================================//
//============= BGK Model for Advection diffusion anisotropic ===//
//==================================================================//
template
RTLBMdynamicsMcHardy::RTLBMdynamicsMcHardy
(Momenta& momenta, T latticeAbsorption, T latticeScattering, std::array, DESCRIPTOR::q>& anisoMatrix)
: BasicDynamics(momenta), _absorption(latticeAbsorption), _scattering(latticeScattering), _anisoMatrix(anisoMatrix)
{
}
template
T RTLBMdynamicsMcHardy::computeEquilibrium( int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr ) const
{
return lbHelpers::equilibriumFirstOrder( iPop, rho, u );
}
template
void RTLBMdynamicsMcHardy::collide( Cell& cell, LatticeStatistics& statistics )
{
std::array feq = {};
for ( int iPop = 0; iPop < DESCRIPTOR::q; ++iPop ) {
for ( int jPop = 0; jPop < DESCRIPTOR::q; ++jPop ) {
feq[iPop] += (cell[jPop] + descriptors::t(jPop)) * _anisoMatrix[jPop][iPop];
}
feq[iPop] *= descriptors::t(iPop);
}
// execute collision
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = (cell[iPop]+descriptors::t(iPop))
- descriptors::norm_c(iPop)*(_absorption+_scattering) * ( (cell[iPop]+descriptors::t(iPop))- feq[iPop] )
- _absorption*descriptors::norm_c(iPop) *(cell[iPop]+descriptors::t(iPop))
- descriptors::t(iPop);
}
T temperature = lbHelpers::computeRho(cell);
statistics.incrementStats( temperature, T() );
}
template
T RTLBMdynamicsMcHardy::getOmega() const
{
return -1;
}
template
void RTLBMdynamicsMcHardy::setOmega( T omega )
{
}
//==================================================================================//
template
RTLBMdynamicsMcHardyRK::RTLBMdynamicsMcHardyRK
(Momenta& momenta, T latticeAbsorption, T latticeScattering, std::array, DESCRIPTOR::q>& anisoMatrix)
: BasicDynamics(momenta), _absorption(latticeAbsorption), _scattering(latticeScattering), _anisoMatrix(anisoMatrix)
{
}
template
T RTLBMdynamicsMcHardyRK::computeEquilibrium( int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr ) const
{
return lbHelpers::equilibriumFirstOrder( iPop, rho, u );
}
template
void RTLBMdynamicsMcHardyRK::computeEquilibriumAniso(Cell& cell, std::array& feq)
{
feq.fill( T() );
for ( int iPop = 0; iPop < DESCRIPTOR::q; ++iPop ) {
for ( int jPop = 0; jPop < DESCRIPTOR::q; ++jPop ) {
feq[iPop] += cell[jPop] * _anisoMatrix[jPop][iPop];
}
feq[iPop] *= descriptors::t(iPop);
}
}
template
std::array RTLBMdynamicsMcHardyRK::doCollision(Cell& cell, std::array& feq)
{
std::array k;
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
k[iPop] = - descriptors::norm_c(iPop)*(_absorption+_scattering) * (cell[iPop])
+ descriptors::norm_c(iPop)*_scattering * feq[iPop];
}
return k;
}
template
void RTLBMdynamicsMcHardyRK::collide( Cell& cell, LatticeStatistics& statistics )
{
std::array feq;
std::array f_pre_collision;
// separate cell and precollision f_i
for ( int iPop = 0; iPop < DESCRIPTOR::q; ++iPop ) {
f_pre_collision[iPop] = cell[iPop] + descriptors::t(iPop);
}
// shift only first collision und equilibrium and then at the very end
for ( int iPop = 0; iPop < DESCRIPTOR::q; ++iPop ) {
cell[iPop] += descriptors::t(iPop);
}
computeEquilibriumAniso(cell,feq);
std::array k1 = doCollision(cell,feq);
// update cell
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = f_pre_collision[iPop] + 0.5*k1[iPop];
}
computeEquilibriumAniso(cell,feq);
std::array k2 = doCollision(cell,feq);
// update cell
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = f_pre_collision[iPop] + 0.5*k2[iPop];
}
computeEquilibriumAniso(cell,feq);
std::array k3 = doCollision(cell,feq);
// update cell
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = f_pre_collision[iPop] + k3[iPop];
}
computeEquilibriumAniso(cell,feq);
std::array k4 = doCollision(cell,feq);
// update cell
for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] = f_pre_collision[iPop] + 1/6.*(k1[iPop] + 2*k2[iPop] + 2*k3[iPop] + k4[iPop])
- descriptors::t(iPop); // back shift for OpenLB
}
T temperature = lbHelpers::computeRho(cell);
statistics.incrementStats( temperature, T() );
}
template
T RTLBMdynamicsMcHardyRK::getOmega() const
{
return -1;
}
template
void RTLBMdynamicsMcHardyRK::setOmega( T omega )
{
}
} // namespace olb
#endif