OpenLB 1.7
Loading...
Searching...
No Matches
cum.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 Louis Kronberg, Pavel Eichler, Stephan Simonis
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 CUM_H
25#define CUM_H
26
27namespace olb {
28
29 namespace descriptors {
30 namespace tag {
31 struct CUM : public CATEGORY, public DESCRIPTOR_TAG { };
32 }
33 namespace cum_data
34 {
36
37
38 template <unsigned D, unsigned Q>
39 Fraction K[Q] = {};
40
41 template <unsigned D, unsigned Q>
42 int velocityIndices[Q][D] = {};
43
44 template <>
46 {10, 8, 26}, {12, 22, 24}, {6, 3, 20}, {4, 2, 18},
47 {1, 0, 14}, {5, 15, 17}, {11, 9, 25}, {7, 16, 19},
48 {13, 21, 23},
49
50 {10, 6, 12}, {4, 1, 5}, {11, 7, 13}, {8, 3, 22},
51 {2, 0, 15}, {9, 16, 21}, {26, 20, 24}, {18, 14, 17},
52 {25, 19, 23},
53
54 {10, 4, 11}, {6, 1, 7}, {12, 5, 13}, {8, 2, 9},
55 {3, 0, 16}, {22, 15, 21}, {26, 18, 25}, {20, 14, 19},
56 {24, 17, 23},
57 };
58
59 // these are the constant parameters K that are computed from the weights of the respective lattice.
60 template <>
62 {1}, 0, {1, 3}, 0, 0, 0, {1, 3}, 0, {1, 9},
63 {1, 6}, 0, {1, 18}, {2, 3}, 0, {2, 9}, {1, 6}, 0, {1, 18},
64 {1, 36}, {1, 9}, {1, 36}, {1, 9}, {4, 9}, {1, 9}, {1, 36}, {1, 9}, {1, 36}
65 };
66 }
67
68 template <typename T, unsigned D, unsigned Q>
69 constexpr T t(unsigned iPop, tag::CUM) any_platform
70 {
71 return data::t<D,Q>[iPop].template as<T>();
72 }
73 template <typename T, unsigned D, unsigned Q>
74 constexpr T constantK(unsigned iPop) any_platform
75 {
76 return cum_data::K<D,Q>[iPop].template as<T>();
77 }
78 }
79
80 template <typename DESCRIPTOR>
81 struct cum {
82 static_assert(std::is_same<typename DESCRIPTOR::category_tag, descriptors::tag::CUM>::value, "DESCRIPTOR is tagged as CUM");
83
89 template <typename MOMENTA, typename CELL, typename U, typename V = typename CELL::value_t>
90 static void computeMomenta(MOMENTA &momenta, CELL &cell, U &u) any_platform {
91 // initialize momenta with the populations
92 for (int i = 0; i < DESCRIPTOR::q; i++)
93 {
94 momenta[i] = cell[i];
95 }
96 constexpr auto passes = DESCRIPTOR::q / DESCRIPTOR::d;
97 for(int i = DESCRIPTOR::d - 1; i >= 0; i--){
98 for(int j = 0; j < passes; j++){
99 auto [a, b, c] = descriptors::cum_data::velocityIndices<DESCRIPTOR::d, DESCRIPTOR::q>[passes * i + j];
100
101 V k = descriptors::constantK<V, DESCRIPTOR::d, DESCRIPTOR::q>(passes * i + j);
102 V sum = momenta[a] + momenta[c];
103 V difference = momenta[c] - momenta[a];
104 momenta[a] = momenta[a] + momenta[b] + momenta[c];
105 momenta[b] = difference - (momenta[a] + k) * u[i];
106 momenta[c] = sum - V(2) * difference * u[i] + u[i] * u[i] * (momenta[a] + k);
107 }
108 }
109 }
110
111
115 template <typename MOMENTA, typename CELL, typename U, typename V = typename CELL::value_t>
116 static void computePopulations(MOMENTA &momenta, CELL &cell, U &u) any_platform {
117
118 constexpr auto passes = DESCRIPTOR::q / DESCRIPTOR::d;
119 for(int i = 0; i < DESCRIPTOR::d; i++){
120 for(int j = 0; j < passes; j++){
121 auto [a, b, c] = descriptors::cum_data::velocityIndices<DESCRIPTOR::d, DESCRIPTOR::q>[passes * i + j];
122 V k = descriptors::constantK<V, DESCRIPTOR::d, DESCRIPTOR::q>(passes * i + j);
123
124
125 V ma = ((momenta[c] - momenta[b]) * V(0.5) + momenta[b] * u[i] + (momenta[a] + k) * (u[i] * u[i] - u[i]) * V(0.5));
126 V mb = (momenta[a] - momenta[c]) - V(2) * momenta[b] * u[i] - (momenta[a] + k) * u[i] * u[i];
127 V mc = ((momenta[c] + momenta[b]) * V(0.5) + momenta[b] * u[i] + (momenta[a] + k) * (u[i] * u[i] + u[i]) * V(0.5));
128
129 momenta[a] = ma;
130 momenta[b] = mb;
131 momenta[c] = mc;
132 }
133 }
134
135 // initialize momenta with the populations
136 for (int i = 0; i < DESCRIPTOR::q; i++){
137 cell[i] = momenta[i];
138 }
139 }
140
141 template <typename CELL, typename U, typename V = typename CELL::value_t>
142 static V cumCollision(CELL &cell, const V& omega, V& rho, U& u) any_platform {
143 V drho = rho - 1;
144 V inverse_rho = 1. / rho;
145 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
146
147
148 // compute central moments from the populations and save them in `moments`
149 V moments[DESCRIPTOR::q];
150 computeMomenta(moments, cell, u);
151 auto [mbbb, mabb, mbab, mbba, maab, macb, maba, mabc, mbaa, mbac, maaa, maac, maca, macc, mcbb, mbcb, mbbc, mccb, mcab, mcbc, mcba, mbcc, mbca, mccc, mcca, mcac, mcaa] = moments;
152
153 const V omega2 = 1; // If modified, constants A and B must be modified too!!!
154 const V omega3 = 1;
155 const V omega4 = 1;
156 const V omega5 = 1;
157 const V omega6 = 1;
158 const V omega7 = 1;
159 const V omega10 = 1; // Collision of the sixth order cumulant
160
161 // COMPUTE cumulant moments
162 V CUMcbb = mcbb - ((mcaa + 1. / 3) * mabb + 2 * mbba * mbab) * inverse_rho;
163 V CUMbcb = mbcb - ((maca + 1. / 3) * mbab + 2 * mbba * mabb) * inverse_rho;
164 V CUMbbc = mbbc - ((maac + 1. / 3) * mbba + 2 * mbab * mabb) * inverse_rho;
165
166 V CUMcca = mcca - (((mcaa * maca + 2 * mbba * mbba) + 1. / 3 * (mcaa + maca)) * inverse_rho - 1. / 9 * (drho * inverse_rho));
167 V CUMcac = mcac - (((mcaa * maac + 2 * mbab * mbab) + 1. / 3 * (mcaa + maac)) * inverse_rho - 1. / 9 * (drho * inverse_rho));
168 V CUMacc = macc - (((maac * maca + 2 * mabb * mabb) + 1. / 3 * (maac + maca)) * inverse_rho - 1. / 9 * (drho * inverse_rho));
169
170 // fifth order cumulant moments
171 V CUMbcc = mbcc - ((maac * mbca + maca * mbac + 4 * mabb * mbbb + 2 * (mbab * macb + mbba * mabc)) + 1. / 3 * (mbca + mbac)) * inverse_rho;
172 V CUMcbc = mcbc - ((maac * mcba + mcaa * mabc + 4 * mbab * mbbb + 2 * (mabb * mcab + mbba * mbac)) + 1. / 3 * (mcba + mabc)) * inverse_rho;
173 V CUMccb = mccb - ((mcaa * macb + maca * mcab + 4 * mbba * mbbb + 2 * (mbab * mbca + mabb * mcba)) + 1. / 3 * (macb + mcab)) * inverse_rho;
174
175 // sixth order cumulant moments
176 V CUMccc = mccc + ((-4 * mbbb * mbbb - (mcaa * macc + maca * mcac + maac * mcca) - 4 * (mabb * mcbb + mbab * mbcb + mbba * mbbc)
177 - 2 * (mbca * mbac + mcba * mabc + mcab * macb)) * inverse_rho
178 + (4 * (mbab * mbab * maca + mabb * mabb * mcaa + mbba * mbba * maac)
179 + 2 * (mcaa * maca * maac) + 16 * mbba * mbab * mabb) * inverse_rho * inverse_rho
180 - 1. / 3 * (macc + mcac + mcca) * inverse_rho
181 - 1. / 9 * (mcaa + maca + maac) * inverse_rho
182 + (2 * (mbab * mbab + mabb * mabb + mbba * mbba)
183 + (maac * maca + maac * mcaa + maca * mcaa)
184 + 1. / 3 * (maac + maca + mcaa)) * inverse_rho * inverse_rho * 2. / 3
185 + 1. / 27 * ((drho * drho - drho) * inverse_rho * inverse_rho));
186
187 // Moment renaming
188 V mxxPyyPzz = mcaa + maca + maac;
189 V mxxMyy = mcaa - maca;
190 V mxxMzz = mcaa - maac;
191
192 V mxxyPyzz = mcba + mabc;
193 V mxxyMyzz = mcba - mabc;
194
195 V mxxzPyyz = mcab + macb;
196 V mxxzMyyz = mcab - macb;
197
198 V mxyyPxzz = mbca + mbac;
199 V mxyyMxzz = mbca - mbac;
200
201 // Relaxation of second order cumulants with no correction terms
202 mxxPyyPzz += omega2 * (maaa - mxxPyyPzz);
203 mxxMyy += -(-omega) * (-mxxMyy);
204 mxxMzz += -(-omega) * (-mxxMzz);
205
206 mabb += omega * (-mabb);
207 mbab += omega * (-mbab);
208 mbba += omega * (-mbba);
209
210 // Relaxation of third order cumulants
211 // no limiter
212 mbbb += omega4 * (-mbbb);
213 mxxyPyzz += omega3 * (-mxxyPyzz);
214 mxxyMyzz += omega4 * (-mxxyMyzz);
215 mxxzPyyz += omega3 * (-mxxzPyyz);
216 mxxzMyyz += omega4 * (-mxxzMyyz);
217 mxyyPxzz += omega3 * (-mxyyPxzz);
218 mxyyMxzz += omega4 * (-mxyyMxzz);
219
220 // Compute inverse linear combinations of second and third order cumulants
221 mcaa = 1. / 3 * (mxxMyy + mxxMzz + mxxPyyPzz);
222 maca = 1. / 3 * (-2 * mxxMyy + mxxMzz + mxxPyyPzz);
223 maac = 1. / 3 * (mxxMyy - 2 * mxxMzz + mxxPyyPzz);
224
225 mcba = (mxxyMyzz + mxxyPyzz) * 0.5;
226 mabc = (-mxxyMyzz + mxxyPyzz) * 0.5;
227 mcab = (mxxzMyyz + mxxzPyyz) * 0.5;
228 macb = (-mxxzMyyz + mxxzPyyz) * 0.5;
229 mbca = (mxyyMxzz + mxyyPxzz) * 0.5;
230 mbac = (-mxyyMxzz + mxyyPxzz) * 0.5;
231
232 CUMacc = (1 - omega6) * (CUMacc);
233 CUMcac = (1 - omega6) * (CUMcac);
234 CUMcca = (1 - omega6) * (CUMcca);
235 CUMbbc = (1 - omega6) * (CUMbbc);
236 CUMbcb = (1 - omega6) * (CUMbcb);
237 CUMcbb = (1 - omega6) * (CUMcbb);
238
239 CUMbcc += omega7 * (-CUMbcc);
240 CUMcbc += omega7 * (-CUMcbc);
241 CUMccb += omega7 * (-CUMccb);
242
243 CUMccc += omega10 * (-CUMccc);
244
245 // Compute central moments from post collision cumulants
246 mcbb = CUMcbb + 1. / 3 * ((3 * mcaa + 1) * mabb + 6 * mbba * mbab) * inverse_rho;
247 mbcb = CUMbcb + 1. / 3 * ((3 * maca + 1) * mbab + 6 * mbba * mabb) * inverse_rho;
248 mbbc = CUMbbc + 1. / 3 * ((3 * maac + 1) * mbba + 6 * mbab * mabb) * inverse_rho;
249
250 mcca = CUMcca + (((mcaa * maca + 2 * mbba * mbba) * 9 + 3 * (mcaa + maca)) * inverse_rho - (drho * inverse_rho)) * 1. / 9;
251 mcac = CUMcac + (((mcaa * maac + 2 * mbab * mbab) * 9 + 3 * (mcaa + maac)) * inverse_rho - (drho * inverse_rho)) * 1. / 9;
252 macc = CUMacc + (((maac * maca + 2 * mabb * mabb) * 9 + 3 * (maac + maca)) * inverse_rho - (drho * inverse_rho)) * 1. / 9;
253
254 mbcc = CUMbcc + 1. / 3 * (3 * (maac * mbca + maca * mbac + 4 * mabb * mbbb + 2 * (mbab * macb + mbba * mabc)) + (mbca + mbac)) * inverse_rho;
255 mcbc = CUMcbc + 1. / 3 * (3 * (maac * mcba + mcaa * mabc + 4 * mbab * mbbb + 2 * (mabb * mcab + mbba * mbac)) + (mcba + mabc)) * inverse_rho;
256 mccb = CUMccb + 1. / 3 * (3 * (mcaa * macb + maca * mcab + 4 * mbba * mbbb + 2 * (mbab * mbca + mabb * mcba)) + (macb + mcab)) * inverse_rho;
257
258 mccc = CUMccc - ((-4 * mbbb * mbbb - (mcaa * macc + maca * mcac + maac * mcca)
259 - 4 * (mabb * mcbb + mbab * mbcb + mbba * mbbc)
260 - 2 * (mbca * mbac + mcba * mabc + mcab * macb)) * inverse_rho
261 + (4 * (mbab * mbab * maca + mabb * mabb * mcaa + mbba * mbba * maac)
262 + 2 * (mcaa * maca * maac) + 16 * mbba * mbab * mabb) * inverse_rho * inverse_rho
263 - 1. / 9 * (macc + mcac + mcca) * inverse_rho
264 - 1. / 9 * (mcaa + maca + maac) * inverse_rho
265 + (2 * (mbab * mbab + mabb * mabb + mbba * mbba) + (maac * maca + maac * mcaa + maca * mcaa)
266 + 1. / 3 * (maac + maca + mcaa)) * inverse_rho * inverse_rho * 2. / 3
267 + 1. / 27 * ((drho * drho - drho) * inverse_rho * inverse_rho));
268
269 // Add acceleration (body force) to first order cumulants
270 mbaa = -mbaa;
271 maba = -maba;
272 maab = -maab;
273
274 // Chimera transform from central moments to well conditioned distributions
275 computePopulations(moments, cell, u);
276
277 return uSqr;
278 }
279 };
280}
281#endif
Floating-point independent fraction type.
Definition fraction.h:34
int velocityIndices[Q][D]
Definition cum.h:42
int velocityIndices< 3, 27 >[27][3]
Definition cum.h:45
constexpr T constantK(unsigned iPop) any_platform
Definition cum.h:74
constexpr T t(unsigned iPop, tag::CUM) any_platform
Definition cum.h:69
Top level namespace for all of OpenLB.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:78
Definition cum.h:81
static V cumCollision(CELL &cell, const V &omega, V &rho, U &u) any_platform
Definition cum.h:142
static void computePopulations(MOMENTA &momenta, CELL &cell, U &u) any_platform
Backwards Chimera Transformation to compute population distribution from the central moments FIXME: S...
Definition cum.h:116
static void computeMomenta(MOMENTA &momenta, CELL &cell, U &u) any_platform
Uses the Chimera Transformation to compute central moments from the population distribution.
Definition cum.h:90
Base of a descriptor tag.
Base of all tags describing the category of a descriptor.