/* This file is part of the OpenLB library
*
* Copyright (C) 2018 Robin Trunk, Sam Avis
* 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.
*/
#ifndef FREE_ENERGY_DYNAMICS_HH
#define FREE_ENERGY_DYNAMICS_HH
#include "core/cell.h"
#include "dynamics/firstOrderLbHelpers.h"
#include "dynamics/freeEnergyDynamics.h"
namespace olb {
template
FreeEnergyBGKdynamics::FreeEnergyBGKdynamics (
T omega_, T gamma_, Momenta& momenta )
: BasicDynamics(momenta),
omega(omega_), gamma(gamma_)
{ }
template
void FreeEnergyBGKdynamics::collide (
Cell& cell,
LatticeStatistics& statistics )
{
T rho, u[DESCRIPTOR::d];
for(int iDim=0; iDim()[iDim];
}
rho = this->_momenta.computeRho(cell);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, omega);
statistics.incrementStats(rho, uSqr);
T tmp = gamma * descriptors::invCs2() * cell.template getFieldPointer()[0];
for(int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] -= omega * descriptors::t(iPop) * (rho - tmp);
}
cell[0] += omega * (1.-descriptors::t(0)) * (rho - tmp);
}
template
T FreeEnergyBGKdynamics::computeEquilibrium(
int iPop, T rho, const T u[DESCRIPTOR::d], T ) const
{
T uSqr = 0.;
T equilibrium = lbHelpers::equilibrium(iPop, rho, u, uSqr);
T tmp = 0; //gamma * descriptors::invCs2() * cell.template getFieldPointer()[0];
if (iPop == 0) {
equilibrium += (1.-descriptors::t(0)) * (rho - tmp);
} else {
equilibrium -= descriptors::t(iPop) * (rho - tmp);
}
return equilibrium;
}
template
T FreeEnergyBGKdynamics::getOmega() const
{
return omega;
}
template
void FreeEnergyBGKdynamics::setOmega(T omega_)
{
omega = omega_;
}
template
void FreeEnergyBGKdynamics::computeRhoU (
Cell const& cell, T& rho, T u[DESCRIPTOR::d]) const
{
rho = this->_momenta.computeRho(cell);
computeU(cell, u);
}
template
void FreeEnergyBGKdynamics::computeU (
Cell const& cell, T u[DESCRIPTOR::d]) const
{
for (int iVel=0; iVel()[iVel];
}
}
/////////////// FreeEnergyWallDynamics ////////////////////////////////////////
template
FreeEnergyWallDynamics::FreeEnergyWallDynamics ()
: BounceBack ()
{ }
template
T FreeEnergyWallDynamics::computeEquilibrium(
int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
T equilibrium = lbHelpers::equilibrium(iPop, rho, u, uSqr);
if (iPop == 0) {
equilibrium += (1.-descriptors::t(0)) * rho;
} else {
equilibrium -= descriptors::t(iPop) * rho;
}
return equilibrium;
}
template
T FreeEnergyWallDynamics::getOmega() const
{
return 0.;
}
template
void FreeEnergyWallDynamics::setOmega(T omega_)
{ }
/////////////// FreeEnergyInletOutletDynamics ////////////////////////////////////////
template
FreeEnergyInletOutletDynamics::FreeEnergyInletOutletDynamics (
T omega_, Momenta& momenta )
: BasicDynamics(momenta), omega(omega_)
{ }
template
void FreeEnergyInletOutletDynamics::collide (
Cell& cell,
LatticeStatistics& statistics )
{
typedef DESCRIPTOR L;
// Do a standard collision neglecting the chemical potential term.
T rho, u[DESCRIPTOR::d];
computeRhoU(cell, rho, u);
T uSqr = lbHelpers::bgkCollision(cell, rho, u, omega);
statistics.incrementStats(rho, uSqr);
for(int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
cell[iPop] -= omega * descriptors::t(iPop) * rho;
}
cell[0] += omega * (1.-descriptors::t(0)) * rho;
// Distribute the missing density to the unknown distribution functions.
std::vector missingIndices = util::subIndexOutgoing();
T missingRho = rho - 1.;
T missingWeightSum = 0;
for (int iPop = 0; iPop < L::q; ++iPop) {
if ( std::find(missingIndices.begin(), missingIndices.end(), iPop) != missingIndices.end() ) {
missingWeightSum += descriptors::t(iPop);
} else {
missingRho -= cell[iPop];
}
}
for (unsigned iPop = 0; iPop < missingIndices.size(); ++iPop) {
cell[missingIndices[iPop]] = missingRho * descriptors::t(missingIndices[iPop]) / missingWeightSum;
}
}
template
T FreeEnergyInletOutletDynamics::computeEquilibrium(
int iPop, T rho, const T u[DESCRIPTOR::d], T uSqr) const
{
T equilibrium = lbHelpers::equilibrium(iPop, rho, u, uSqr);
if (iPop == 0) {
equilibrium += (1.-descriptors::t(0)) * rho;
} else {
equilibrium -= descriptors::t(iPop) * rho;
}
return equilibrium;
}
template
T FreeEnergyInletOutletDynamics::getOmega() const
{
return omega;
}
template
void FreeEnergyInletOutletDynamics::setOmega(T omega_)
{
omega = omega_;
}
template
T FreeEnergyInletOutletDynamics::computeRho(
Cell const& cell) const
{
return cell.template getField()[0];
}
template
void FreeEnergyInletOutletDynamics::computeU (
Cell const& cell, T u[DESCRIPTOR::d]) const
{
for (int iVel=0; iVel()[1];
}
template
void FreeEnergyInletOutletDynamics::computeRhoU (
Cell const& cell, T& rho, T u[DESCRIPTOR::d]) const
{
rho = computeRho(cell);
computeU(cell, u);
}
template
void FreeEnergyInletOutletDynamics::defineRho(
Cell& cell, T rho)
{
cell.template getFieldPointer()[0] = rho;
}
template
void FreeEnergyInletOutletDynamics::defineU(
Cell& cell, const T u[DESCRIPTOR::d])
{
cell.template getFieldPointer()[1] = u[direction];
}
}
#endif