24#ifndef FINITE_DIFFERENCE_3D_H
25#define FINITE_DIFFERENCE_3D_H
41 return u_xm1 + u_ym1 + u_zm1 + u_xp1 + u_yp1 + u_zp1 - T{6}*u_0;
46constexpr T
laplacian3D(T u_xm2, T u_ym2, T u_zm2, T u_xm1, T u_ym1, T u_zm1,
47 T u_0, T u_xp1, T u_yp1, T u_zp1, T u_xp2, T u_yp2, T u_zp2)
any_platform
49 return (-T{90}*u_0 + T{16}*(u_xm1 + u_ym1 + u_zm1 + u_xp1 + u_yp1 + u_zp1)
50 - (u_xm2 + u_ym2 + u_zm2 + u_xp2 + u_yp2 + u_zp2)) / T{12};
56template<
typename T,
typename DESCRIPTOR,
57 int direction,
int orientation,
int deriveDirection,
62 int iX,
int iY,
int iZ );
65 int iX,
int iY,
int iZ );
67 template <
typename CELL>
73template<
typename T,
typename DESCRIPTOR,
74 int direction,
int orientation,
int deriveDirection>
76 deriveDirection, true> {
78 int iX,
int iY,
int iZ)
80 return blockLattice.
isInside(iX,iY,iZ)
81 && blockLattice.
isInside(iX+(direction==0 ? (-orientation):0),
82 iY+(direction==1 ? (-orientation):0),
83 iZ+(direction==2 ? (-orientation):0))
84 && blockLattice.
isInside(iX+(direction==0 ? (-2*orientation):0),
85 iY+(direction==1 ? (-2*orientation):0),
86 iZ+(direction==2 ? (-2*orientation):0));
91 int iX,
int iY,
int iZ)
95 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
97 blockLattice.
get(iX,iY,iZ).computeU(u0);
99 iX+(direction==0 ? (-orientation):0),
100 iY+(direction==1 ? (-orientation):0),
101 iZ+(direction==2 ? (-orientation):0) ).computeU(u1);
103 iX+(direction==0 ? (-2*orientation):0),
104 iY+(direction==1 ? (-2*orientation):0),
105 iZ+(direction==2 ? (-2*orientation):0) ).computeU(u2);
107 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
114 int iX,
int iY,
int iZ)
119 T rho0 = blockLattice.
get(iX,iY,iZ).computeRho();
120 T rho1 = blockLattice.
get (
121 iX+(direction==0 ? (-orientation):0),
122 iY+(direction==1 ? (-orientation):0),
123 iZ+(direction==2 ? (-orientation):0) ).computeRho();
124 T rho2 = blockLattice.
get (
125 iX+(direction==0 ? (-2*orientation):0),
126 iY+(direction==1 ? (-2*orientation):0),
127 iZ+(direction==2 ? (-2*orientation):0) ).computeRho();
132 template <
typename CELL>
138 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
141 cell.neighbor({(direction==0 ? (-orientation):0),
142 (direction==1 ? (-orientation):0),
143 (direction==2 ? (-orientation):0)}).computeU(u1);
144 cell.neighbor({(direction==0 ? (-2*orientation):0),
145 (direction==1 ? (-2*orientation):0),
146 (direction==2 ? (-2*orientation):0)}).computeU(u2);
148 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
155template<
typename T,
typename DESCRIPTOR,
156 int direction,
int orientation,
int deriveDirection>
158 deriveDirection, false> {
160 int iX,
int iY,
int iZ)
162 return blockLattice.
isInside(iX+(deriveDirection==0 ? 1:0),
163 iY+(deriveDirection==1 ? 1:0),
164 iZ+(deriveDirection==2 ? 1:0))
165 && blockLattice.
isInside(iX+(deriveDirection==0 ? (-1):0),
166 iY+(deriveDirection==1 ? (-1):0),
167 iZ+(deriveDirection==2 ? (-1):0));
172 int iX,
int iY,
int iZ)
176 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
179 iX+(deriveDirection==0 ? 1:0),
180 iY+(deriveDirection==1 ? 1:0),
181 iZ+(deriveDirection==2 ? 1:0) ).computeU(u_p1);
184 iX+(deriveDirection==0 ? (-1):0),
185 iY+(deriveDirection==1 ? (-1):0),
186 iZ+(deriveDirection==2 ? (-1):0) ).computeU(u_m1);
188 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
195 int iX,
int iY,
int iZ)
199 T rho_p1 = blockLattice.
get (
200 iX+(deriveDirection==0 ? 1:0),
201 iY+(deriveDirection==1 ? 1:0),
202 iZ+(deriveDirection==2 ? 1:0) ).computeRho();
204 T rho_m1 = blockLattice.
get (
205 iX+(deriveDirection==0 ? (-1):0),
206 iY+(deriveDirection==1 ? (-1):0),
207 iZ+(deriveDirection==2 ? (-1):0) ).computeRho();
213 template <
typename CELL>
219 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
221 cell.neighbor({(deriveDirection==0 ? 1:0),
222 (deriveDirection==1 ? 1:0),
223 (deriveDirection==2 ? 1:0)}).computeU(u_p1);
224 cell.neighbor({(deriveDirection==0 ? (-1):0),
225 (deriveDirection==1 ? (-1):0),
226 (deriveDirection==2 ? (-1):0)}).computeU(u_m1);
228 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
Platform-abstracted block lattice for external access and inter-block interaction.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
bool isInside(LatticeR< D > latticeR) const
Return whether location is valid.
constexpr T laplacian3D(T u_xm1, T u_ym1, T u_zm1, T u_0, T u_xp1, T u_yp1, T u_zp1) any_platform
Second order Laplacian (symmetric, u_xp1 = u(x+1,y,z))
constexpr T centralGradient(T u_p1, T u_m1) any_platform
Second-order central gradient (u_p1 = u(x+1))
constexpr T boundaryGradient(T u_0, T u_1, T u_2) any_platform
Second-order asymmetric gradient (u_1 = u(x+1))
Top level namespace for all of OpenLB.
static bool canInterpolateVector(BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateScalar(T &rhoDeriv, BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], CELL &cell) any_platform
static void interpolateScalar(T &rhoDeriv, BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], CELL &cell) any_platform
static bool canInterpolateVector(BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateScalar(T &rhoDeriv, BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], CELL &cell) any_platform
static void interpolateVector(T velDeriv[DESCRIPTOR::d], BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY, int iZ)