/* This file is part of the OpenLB library
*
* Copyright (C) 2006, 2007 Jonas Latt
* 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 MRT (multiple relaxation
* time) dynamics. This file is all about efficiency.
* The generic template code is specialized for commonly used Lattices,
* so that a maximum performance can be taken out of each case.
*/
#ifndef D3Q13_HELPERS_H
#define D3Q13_HELPERS_H
#include "latticeDescriptors.h"
#include "core/cell.h"
#include "core/util.h"
namespace olb {
/// Helper functions for the (somewhat special) D3Q13 lattice
template
struct d3q13Helpers {
typedef descriptors::D3Q13<> DESCRIPTOR;
/// BGK collision step
static T collision( Cell>& cell,
T rho, const T u[DESCRIPTOR::d],
T lambda_nu, T lambda_nu_prime)
{
const T lambda_e = descriptors::lambda_e();
const T lambda_h = descriptors::lambda_h();
T uxSqr = util::sqr(u[0]);
T uySqr = util::sqr(u[1]);
T uzSqr = util::sqr(u[2]);
T uSqr = uxSqr + uySqr + uzSqr;
T s1 = cell[7] + cell[8] + cell[9] + cell[10];
T s2 = cell[11] + cell[12];
T s3 = cell[1] + cell[2] + cell[3] + cell[4];
T s4 = cell[5] + cell[6];
T sTot = s1 + s2 + s3 + s4;
T d1 = cell[7] + cell[8] - cell[9] - cell[10];
T d2 = cell[1] + cell[2] - cell[3] - cell[4];
T M[13]; // The terms M[0]-M[3] are not used (they correspond
// to rho, rho*ux, rho*uy, rho*uz respectively),
// but we still use a 13-component vector to preserve
// the clarity of the code.
M[4] = -(T)12*cell[0] + sTot - (T)11/(T)2;
// The 11/2 correction term in M4 accounts for the fact that
// cell[i] corresponds to f[i]-ti, and not f[i]
M[5] = s1 - (T)2*s2 + s3 - (T)2*s4;
M[6] = d1 + d2;
M[7] = cell[7] - cell[8] + cell[1] - cell[2];
M[8] = cell[11] - cell[12] + cell[5] - cell[6];
M[9] = cell[9] - cell[10] + cell[3] - cell[4];
M[10] = d1 - d2;
M[11] = -cell[7] + cell[8] + s2 + cell[1] - cell[2] - s4;
M[12] = cell[9] - cell[10] - cell[11] + cell[12]
- cell[3] + cell[4] + cell[5] - cell[6];
T Mneq[13]; // The terms Mneq[0]-Mneq[3] are not used (they are
// actually all zero, because of conservation laws),
// but we still use a 13-component vector to preserve
// the clarity of the code.
Mneq[4] = M[4] + (T)11/(T)2*rho - (T)13/(T)2*rho*uSqr;
Mneq[5] = M[5] - rho*( (T)2*uxSqr-(uySqr+uzSqr) );
Mneq[6] = M[6] - rho*( uySqr-uzSqr );
Mneq[7] = M[7] - rho*( u[0]*u[1] );
Mneq[8] = M[8] - rho*( u[1]*u[2] );
Mneq[9] = M[9] - rho*( u[0]*u[2] );
Mneq[10] = M[10];
Mneq[11] = M[11];
Mneq[12] = M[12];
Mneq[4] *= lambda_e / (T)156;
Mneq[5] *= lambda_nu / (T)24;
Mneq[6] *= lambda_nu / (T)8;
Mneq[7] *= lambda_nu_prime / (T)4;
Mneq[8] *= lambda_nu_prime / (T)4;
Mneq[9] *= lambda_nu_prime / (T)4;
Mneq[10] *= lambda_h / (T)8;
Mneq[11] *= lambda_h / (T)8;
Mneq[12] *= lambda_h / (T)8;
T F1 = Mneq[4] + Mneq[5] + Mneq[6];
T F2 = Mneq[4] + Mneq[5] - Mneq[6];
T F3 = Mneq[4] - (T)2*Mneq[5];
cell[0] -= (T)-12*Mneq[4];
cell[1] -= F1 + Mneq[7] -Mneq[10]+Mneq[11];
cell[2] -= F1 - Mneq[7] -Mneq[10]-Mneq[11];
cell[3] -= F2 +Mneq[9]+Mneq[10] -Mneq[12];
cell[4] -= F2 -Mneq[9]+Mneq[10] +Mneq[12];
cell[5] -= F3 +Mneq[8] -Mneq[11]+Mneq[12];
cell[6] -= F3 -Mneq[8] -Mneq[11]-Mneq[12];
cell[7] -= F1 + Mneq[7] +Mneq[10]-Mneq[11];
cell[8] -= F1 - Mneq[7] +Mneq[10]+Mneq[11];
cell[9] -= F2 +Mneq[9]-Mneq[10] +Mneq[12];
cell[10] -= F2 -Mneq[9]-Mneq[10] -Mneq[12];
cell[11] -= F3 +Mneq[8] +Mneq[11]-Mneq[12];
cell[12] -= F3 -Mneq[8] +Mneq[11]+Mneq[12];
return uSqr;
}
/// BGK collision step with density correction
static T constRhoCollision( Cell>& cell,
T rho, const T u[DESCRIPTOR::d],
T ratioRho,
T lambda_nu, T lambda_nu_prime)
{
const T uSqr = util::normSqr(u);
return uSqr;
}
}; // struct d3q13helpers
} // namespace olb
#endif