OpenLB 1.7
Loading...
Searching...
No Matches
finiteDifference2D.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_2D_H
25#define FINITE_DIFFERENCE_2D_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
37template<typename T>
38constexpr T d2u_dxdy(T u_xm1_ym1, T u_xm1_yp1, T u_xp1_ym1, T u_xp1_yp1) any_platform
39{
40 return (u_xp1_yp1 - u_xp1_ym1 - u_xm1_yp1 + u_xm1_ym1) / T{4};
41}
42
44template<typename T>
45constexpr T d2u_dxdy(T u_xm1_ym1, T u_xm1, T u_ym1,
46 T u_0, T u_xp1, T u_yp1, T u_xp1_yp1) any_platform
47{
48 return - (u_xp1 + u_yp1 + u_xm1 + u_ym1 - T{2}*u_0 - u_xp1_yp1 - u_xm1_ym1) / T{2};
49}
50
52template<typename T>
53constexpr T laplacian2D(T u_xm1, T u_ym1, T u_0, T u_xp1, T u_yp1) any_platform
54{
55 return u_xm1 + u_ym1 + u_xp1 + u_yp1 - T{4}*u_0;
56}
57
59template<typename T>
60constexpr T laplacian2D(T u_xm2, T u_ym2, T u_xm1, T u_ym1,
61 T u_0, T u_xp1, T u_yp1, T u_xp2, T u_yp2) any_platform
62{
63 return (-T{60}*u_0 + T{16}*(u_xm1 + u_ym1 + u_xp1 + u_yp1)
64 - (u_xm2 + u_ym2 + u_xp2 + u_yp2)) / T{12};
65}
66
67
68// -------------------- Interpolation -----------------------------------------
69
70template<typename T, typename DESCRIPTOR,
71 int direction, int orientation,
72 bool orthogonal>
74 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
75 BlockLattice<T,DESCRIPTOR> const& blockLattice,
76 int iX, int iY);
77 static void interpolateScalar(T& rhoDeriv,
78 BlockLattice<T,DESCRIPTOR> const& blockLattice,
79 int iX, int iY);
80
81 template <typename CELL>
82 static void interpolateVector( T velDeriv[DESCRIPTOR::d],
83 CELL& cell ) any_platform;
84};
85
86// Implementation for orthogonal==true; i.e. the derivative is along
87// the boundary normal.
88template<typename T, typename DESCRIPTOR,
89 int direction, int orientation>
90struct DirectedGradients2D<T, DESCRIPTOR, direction, orientation, true> {
91 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
92 BlockLattice<T,DESCRIPTOR> const& blockLattice,
93 int iX, int iY)
94 {
95 using namespace fd;
96
97 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
98
99 blockLattice.get(iX,iY).computeU(u0);
100 blockLattice.get (
101 iX+(direction==0 ? (-orientation):0),
102 iY+(direction==1 ? (-orientation):0) ).computeU(u1);
103 blockLattice.get (
104 iX+(direction==0 ? (-2*orientation):0),
105 iY+(direction==1 ? (-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)
115 {
116 using namespace fd;
117
118 T rho0 = blockLattice.get(iX,iY).computeRho();
119 T rho1 = blockLattice.get (
120 iX+(direction==0 ? (-orientation):0),
121 iY+(direction==1 ? (-orientation):0) ).computeRho();
122 T rho2 = blockLattice.get (
123 iX+(direction==0 ? (-2*orientation):0),
124 iY+(direction==1 ? (-2*orientation):0) ).computeRho();
125
126 rhoDeriv = -orientation * boundaryGradient(rho0, rho1, rho2);
127
128 }
129
130 template <typename CELL>
131 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
132 CELL& cell) any_platform
133 {
134 using namespace fd;
135
136 T u0[DESCRIPTOR::d], u1[DESCRIPTOR::d], u2[DESCRIPTOR::d];
137
138 cell.computeU(u0);
139 cell.neighbor({(direction==0 ? (-orientation):0),
140 (direction==1 ? (-orientation):0)}).computeU(u1);
141 cell.neighbor({(direction==0 ? (-2*orientation):0),
142 (direction==1 ? (-2*orientation):0)}).computeU(u2);
143
144 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
145 velDeriv[iD] = -orientation * boundaryGradient(u0[iD], u1[iD], u2[iD]);
146 }
147 }
148};
149
150
151// Implementation for orthogonal==false; i.e. the derivative is aligned
152// with the boundary.
153template<typename T, typename DESCRIPTOR,
154 int direction, int orientation>
155struct DirectedGradients2D<T, DESCRIPTOR, direction, orientation, false> {
156 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
157 BlockLattice<T,DESCRIPTOR> const& blockLattice,
158 int iX, int iY)
159 {
160 using namespace fd;
161
162 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
163
164 int deriveDirection = 1-direction;
165 blockLattice.get (
166 iX+(deriveDirection==0 ? 1:0),
167 iY+(deriveDirection==1 ? 1:0) ).computeU(u_p1);
168 blockLattice.get (
169 iX+(deriveDirection==0 ? (-1):0),
170 iY+(deriveDirection==1 ? (-1):0) ).computeU(u_m1);
171
172 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
173 velDeriv[iD] = fd::centralGradient(u_p1[iD],u_m1[iD]);
174 }
175 }
176
177 static void interpolateScalar(T& rhoDeriv,
178 BlockLattice<T,DESCRIPTOR> const& blockLattice,
179 int iX, int iY)
180 {
181 using namespace fd;
182
183 int deriveDirection = 1-direction;
184 T rho_p1 = blockLattice.get (
185 iX+(deriveDirection==0 ? 1:0),
186 iY+(deriveDirection==1 ? 1:0) ).computeRho();
187 T rho_m1 = blockLattice.get (
188 iX+(deriveDirection==0 ? (-1):0),
189 iY+(deriveDirection==1 ? (-1):0) ).computeRho();
190
191 rhoDeriv = centralGradient(rho_p1, rho_m1);
192
193 }
194
195 template <typename CELL>
196 static void interpolateVector(T velDeriv[DESCRIPTOR::d],
197 CELL& cell) any_platform
198 {
199 using namespace fd;
200
201 T u_p1[DESCRIPTOR::d], u_m1[DESCRIPTOR::d];
202
203 int deriveDirection = 1-direction;
204 cell.neighbor({(deriveDirection==0 ? 1:0),
205 (deriveDirection==1 ? 1:0)}).computeU(u_p1);
206 cell.neighbor({(deriveDirection==0 ? (-1):0),
207 (deriveDirection==1 ? (-1):0)}).computeU(u_m1);
208
209 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
210 velDeriv[iD] = centralGradient(u_p1[iD],u_m1[iD]);
211 }
212 }
213};
214
215} // namespace fd
216
217} // namespace olb
218
219
220#endif
Platform-abstracted block lattice for external access and inter-block interaction.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
constexpr T centralGradient(T u_p1, T u_m1) any_platform
Second-order central gradient (u_p1 = u(x+1))
constexpr T laplacian2D(T u_xm1, T u_ym1, T u_0, T u_xp1, T u_yp1) any_platform
Second order Laplacian (u_xp1 = u(x+1,y))
constexpr T d2u_dxdy(T u_xm1_ym1, T u_xm1_yp1, T u_xp1_ym1, T u_xp1_yp1) any_platform
Second order mixed derivative (u_xp1_ym1 = u(x+1,y-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 void interpolateScalar(T &rhoDeriv, BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY)
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)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY)
static void interpolateScalar(T &rhoDeriv, BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], CELL &cell) any_platform
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)
static void interpolateVector(T velDeriv[DESCRIPTOR::d], BlockLattice< T, DESCRIPTOR > const &blockLattice, int iX, int iY)