OpenLB 1.7
Loading...
Searching...
No Matches
finiteDifference3D.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2006, 2007 Jonas Latt
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef FINITE_DIFFERENCE_3D_H
25#define FINITE_DIFFERENCE_3D_H
26
27#include "finiteDifference.h"
28
29namespace olb {
30
31namespace fd {
32
33// -------------------- Second derivatives ------------------------------------
34// cf. Abramowitz, Stegun: Handbook of Mathematical Functions, 1964, p. 884f.
35// (trivially transferred to 3D)
36
38template<typename T>
39constexpr 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
40{
41 return u_xm1 + u_ym1 + u_zm1 + u_xp1 + u_yp1 + u_zp1 - T{6}*u_0;
42}
43
45template<typename T>
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
48{
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};
51}
52
53
54// -------------------- Interpolation -----------------------------------------
55
56template<typename T, typename DESCRIPTOR,
57 int direction, int orientation, int deriveDirection,
58 bool orthogonal>
60 static void interpolateVector( T velDeriv[DESCRIPTOR::d],
61 BlockLattice<T,DESCRIPTOR> const& blockLattice,
62 int iX, int iY, int iZ );
63 static void interpolateScalar( T& rhoDeriv,
64 BlockLattice<T,DESCRIPTOR> const& blockLattice,
65 int iX, int iY, int iZ );
66
67 template <typename CELL>
68 static void interpolateVector( T velDeriv[DESCRIPTOR::d],
69 CELL& cell ) any_platform;
70};
71
72// Implementation for orthogonal==true; i.e. the derivative is along the boundary normal.
73template<typename T, typename DESCRIPTOR,
74 int direction, int orientation, int deriveDirection>
75struct DirectedGradients3D<T, DESCRIPTOR, direction, orientation,
76 deriveDirection, true> {
77 static bool canInterpolateVector(BlockLattice<T,DESCRIPTOR> const& blockLattice,
78 int iX, int iY, int iZ)
79 {
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));
87 }
88
89 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
90 BlockLattice<T,DESCRIPTOR> const& blockLattice,
91 int iX, int iY, int iZ)
92 {
93 using namespace fd;
94
95 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
96
97 blockLattice.get(iX,iY,iZ).computeU(u0);
98 blockLattice.get (
99 iX+(direction==0 ? (-orientation):0),
100 iY+(direction==1 ? (-orientation):0),
101 iZ+(direction==2 ? (-orientation):0) ).computeU(u1);
102 blockLattice.get (
103 iX+(direction==0 ? (-2*orientation):0),
104 iY+(direction==1 ? (-2*orientation):0),
105 iZ+(direction==2 ? (-2*orientation):0) ).computeU(u2);
106
107 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
108 velDeriv[iD] = -orientation * boundaryGradient(u0[iD], u1[iD], u2[iD]);
109 }
110 }
111
112 static void interpolateScalar(T& rhoDeriv,
113 BlockLattice<T,DESCRIPTOR> const& blockLattice,
114 int iX, int iY, int iZ)
115 {
116 using namespace fd;
117
118 // note that the derivative runs along direction.
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();
128
129 rhoDeriv = -orientation * boundaryGradient(rho0, rho1, rho2);
130 }
131
132 template <typename CELL>
133 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
134 CELL& cell) any_platform
135 {
136 using namespace fd;
137
138 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
139
140 cell.computeU(u0);
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);
147
148 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
149 velDeriv[iD] = -orientation * boundaryGradient(u0[iD], u1[iD], u2[iD]);
150 }
151 }
152};
153
154// Implementation for orthogonal==false; i.e. the derivative is aligned with the boundary.
155template<typename T, typename DESCRIPTOR,
156 int direction, int orientation, int deriveDirection>
157struct DirectedGradients3D<T, DESCRIPTOR, direction, orientation,
158 deriveDirection, false> {
159 static bool canInterpolateVector(BlockLattice<T,DESCRIPTOR> const& blockLattice,
160 int iX, int iY, int iZ)
161 {
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));
168 }
169
170 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
171 BlockLattice<T,DESCRIPTOR> const& blockLattice,
172 int iX, int iY, int iZ)
173 {
174 using namespace fd;
175
176 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
177
178 blockLattice.get (
179 iX+(deriveDirection==0 ? 1:0),
180 iY+(deriveDirection==1 ? 1:0),
181 iZ+(deriveDirection==2 ? 1:0) ).computeU(u_p1);
182
183 blockLattice.get (
184 iX+(deriveDirection==0 ? (-1):0),
185 iY+(deriveDirection==1 ? (-1):0),
186 iZ+(deriveDirection==2 ? (-1):0) ).computeU(u_m1);
187
188 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
189 velDeriv[iD] = centralGradient(u_p1[iD],u_m1[iD]);
190 }
191 }
192
193 static void interpolateScalar(T& rhoDeriv,
194 BlockLattice<T,DESCRIPTOR> const& blockLattice,
195 int iX, int iY, int iZ)
196 {
197 using namespace fd;
198
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();
203
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();
208
209 rhoDeriv = centralGradient(rho_p1, rho_m1);
210
211 }
212
213 template <typename CELL>
214 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
215 CELL& cell) any_platform
216 {
217 using namespace fd;
218
219 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
220
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);
227
228 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
229 velDeriv[iD] = centralGradient(u_p1[iD],u_m1[iD]);
230 }
231 }
232
233};
234
235} // namespace fd
236
237} // namespace olb
238
239
240#endif
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.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:78
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)