OpenLB 1.8.1
Loading...
Searching...
No Matches
forcing.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Adrian Kummerlaender
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 DYNAMICS_FORCING_H
25#define DYNAMICS_FORCING_H
26
27#include "lbm.h"
28#include "descriptor/fields.h"
30
31namespace olb {
32
34namespace forcing {
35
37template <template <typename> typename Forced = momenta::Forced>
38struct Guo {
39 static std::string getName() {
40 return "GuoForcing";
41 }
42
43 template <typename DESCRIPTOR, typename MOMENTA>
44 using combined_momenta = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
45
46 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
47 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,Forced<MOMENTA>>;
48
49 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
51 using MomentaF = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
52 using CollisionO = typename COLLISION::template type<DESCRIPTOR,Forced<MOMENTA>,EQUILIBRIUM>;
53
54 constexpr static bool is_vectorizable = dynamics::is_vectorizable_v<CollisionO>;
55
56 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
57 "COLLISION must be parametrized using relaxation frequency OMEGA");
58
59 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
60 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
61 V rho, u[DESCRIPTOR::d];
62 MomentaF().computeRhoU(cell, rho, u);
63 //cell.template setField<descriptors::VELOCITY>(u);
64 CollisionO().apply(cell, parameters);
65 const V omega = parameters.template get<descriptors::OMEGA>();
66 const auto force = cell.template getField<descriptors::FORCE>();
67 lbm<DESCRIPTOR>::addExternalForce(cell, rho, u, omega, force);
68 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
69 };
70 };
71
72 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
73 using combined_parameters = typename COLLISION::parameters;
74};
75
77//template <template <typename> typename Sourced = momenta::Sourced>
78struct AdeGuo {
79 static std::string getName() {
80 return "AdeGuoForcing";
81 }
82
83 template <typename DESCRIPTOR, typename MOMENTA>
84 using combined_momenta = typename MOMENTA::template type<DESCRIPTOR>;
85
86 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
87 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
88
89 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
91 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
92 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
93
94 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
95 "COLLISION must be parametrized using relaxation frequency OMEGA");
96
97 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
98 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
99 const auto u = cell.template getField<descriptors::VELOCITY>();
100 const V rho = MomentaF().computeRho(cell);
101 CollisionO().apply(cell, parameters);
102 const V omega = parameters.template get<descriptors::OMEGA>();
103 const auto source = cell.template getField<descriptors::SOURCE>();
104 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
105 V sourceTerm{};
106 sourceTerm = source;
107 sourceTerm *= descriptors::t<V,DESCRIPTOR>(iPop);
108 sourceTerm *= (V{1} - omega * V{0.5});
109 cell[iPop] += sourceTerm;
110 }
111 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
112 };
113 };
114
115 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
116 using combined_parameters = typename COLLISION::parameters;
117};
118
120template <template <typename> typename Forced = momenta::Identity>
121struct MCGuo {
122 static std::string getName() {
123 return "MultiComponentGuoForcing";
124 }
125 template <typename DESCRIPTOR, typename MOMENTA>
126 using combined_momenta = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
127 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
128 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,Forced<MOMENTA>>;
129 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
131 using MomentaF = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
132 using CollisionO = typename COLLISION::template type<DESCRIPTOR,Forced<MOMENTA>,EQUILIBRIUM>;
133 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
134 "COLLISION must be parametrized using relaxation frequency OMEGA");
135 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
136 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
137 V rho, u[DESCRIPTOR::d];
138 MomentaF().computeRhoU(cell, rho, u);
139 CollisionO().apply(cell, parameters);
140 const V omega = parameters.template get<descriptors::OMEGA>();
141 const auto force = cell.template getField<descriptors::FORCE>();
142 lbm<DESCRIPTOR>::addExternalForce(cell, rho, u, omega, force);
143 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
144 };
145 };
146 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
147 using combined_parameters = typename COLLISION::parameters;
148};
149
150template <template <typename> typename Forced = momenta::Forced>
151struct Liang {
152 static std::string getName() {
153 return "LiangForcing";
154 }
155
156 template <typename DESCRIPTOR, typename MOMENTA>
157 using combined_momenta = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
158
159 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
160 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,Forced<MOMENTA>>;
161
162 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
164 using MomentaF = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
165 using CollisionO = typename COLLISION::template type<DESCRIPTOR,Forced<MOMENTA>,EQUILIBRIUM>;
166
167 constexpr static bool is_vectorizable = dynamics::is_vectorizable_v<CollisionO>
168 // hacky workaround until vectorizability is deduced by introspection
169 && !std::is_same_v<MOMENTA, momenta::IncBulkTuple<momenta::ForcedMomentum<momenta::IncompressibleBulkMomentum>>>;
170
171 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
172 "COLLISION must be parametrized using relaxation frequency OMEGA");
173
174 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
175 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
176 V u[DESCRIPTOR::d];
177 MomentaF().computeU(cell, u);
178 CollisionO().apply(cell, parameters);
179 const V omega = parameters.template get<descriptors::OMEGA>();
180 const auto force = cell.template getField<descriptors::FORCE>();
181 const auto rho = cell.template getField<descriptors::RHO>();
182 const auto gradRho = cell.template getField<descriptors::NABLARHO>();
183 lbm<DESCRIPTOR>::addLiangForce(cell, rho, gradRho, u, omega, force);
184 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
185 };
186 };
187
188 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
189 using combined_parameters = typename COLLISION::parameters;
190};
191
192template <template <typename> typename Forced = momenta::Forced>
193struct LiangTRT {
194 static std::string getName() {
195 return "LiangTRTForcing";
196 }
197
198 template <typename DESCRIPTOR, typename MOMENTA>
199 using combined_momenta = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
200
201 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
202 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,Forced<MOMENTA>>;
203
204 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
206 using MomentaF = typename Forced<MOMENTA>::template type<DESCRIPTOR>;
207 using CollisionO = typename COLLISION::template type<DESCRIPTOR,Forced<MOMENTA>,EQUILIBRIUM>;
208
209 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
210 "COLLISION must be parametrized using relaxation frequency OMEGA");
211
212 constexpr static bool is_vectorizable = dynamics::is_vectorizable_v<CollisionO>
213 // hacky workaround until vectorizability is deduced by introspection
214 && !std::is_same_v<MOMENTA, momenta::IncBulkTuple<momenta::ForcedMomentum<momenta::IncompressibleBulkMomentum>>>;
215
216 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
217 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
218 V u[DESCRIPTOR::d];
219 MomentaF().computeU(cell, u);
220 CollisionO().apply(cell, parameters);
221 const V omega = parameters.template get<descriptors::OMEGA>();
222 const auto force = cell.template getField<descriptors::FORCE>();
223 const auto rho = cell.template getField<descriptors::RHO>();
224 const auto gradRho = cell.template getField<descriptors::NABLARHO>();
225
226 V fTerm[DESCRIPTOR::q], fTermPlus[DESCRIPTOR::q], fTermMinus[DESCRIPTOR::q];
227
228 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
229 V c_u{};
230 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
231 c_u += descriptors::c<DESCRIPTOR>(iPop,iD)*u[iD];
232 }
233 fTerm[iPop] = 0.;
234 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
235 fTerm[iPop] += descriptors::c<DESCRIPTOR>(iPop,iD) * force[iD] * rho +c_u * descriptors::c<DESCRIPTOR>(iPop,iD) * gradRho[iD];
236 }
238 }
239
240 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
241 fTermPlus[iPop] = V{0.5} * (fTerm[iPop] + fTerm[descriptors::opposite<DESCRIPTOR>(iPop)]);
242 fTermMinus[iPop] = V{0.5} * (fTerm[iPop] - fTerm[descriptors::opposite<DESCRIPTOR>(iPop)]);
243 }
244
245 V tau = V{1} / omega;
246 const V tau2 = parameters.template get<collision::ITRT::TAU_MINUS>();
247 const auto nablaRho = cell.template getField<descriptors::NABLARHO>();
248 V ratio = util::norm<DESCRIPTOR::d>(nablaRho) / parameters.template get<collision::ITRT::MAXNABLARHO>();
249 const V omega2 = V{1} / (tau + ratio * (tau2 - tau));
250
251 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
252 cell[iPop] += ( V{1} - omega * V{0.5} ) * fTermPlus[iPop]
253 + ( V{1} - omega2 * V{0.5} ) * fTermMinus[iPop];
254 }
255
256 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
257 };
258 };
259
260 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
261 using combined_parameters = typename COLLISION::parameters;
262};
263
264struct AllenCahn {
265 static std::string getName() {
266 return "AllenCahnForcing";
267 }
268
269 template <typename DESCRIPTOR, typename MOMENTA>
270 using combined_momenta = typename MOMENTA::template type<DESCRIPTOR>;
271
272 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
273 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
274
275 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
277 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
278 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
279
280 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
281 "COLLISION must be parametrized using relaxation frequency OMEGA");
282
283 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
284 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
285 V phi = MomentaF().computeRho(cell);
286 CollisionO().apply(cell, parameters);
287 const V omega = parameters.template get<descriptors::OMEGA>();
288 const auto force = cell.template getField<descriptors::FORCE>();
289 const auto u = cell.template getField<descriptors::VELOCITY>();
290 const auto source = cell.template getField<descriptors::SOURCE>();
291 lbm<DESCRIPTOR>::addAllenCahnForce(cell, omega, force);
292 lbm<DESCRIPTOR>::addAllenCahnSource(cell, omega, source);
293 return {phi, util::normSqr<V,DESCRIPTOR::d>(u)};
294 };
295 };
296
297 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
298 using combined_parameters = typename COLLISION::parameters;
299};
300
301
303 static std::string getName() {
304 return "WellBalancedCahnHilliardForcing";
305 }
306
307 template <typename DESCRIPTOR, typename MOMENTA>
308 using combined_momenta = typename MOMENTA::template type<DESCRIPTOR>;
309
310 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
311 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
312
313 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
315 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
316 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
317
318 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
319 "COLLISION must be parametrized using relaxation frequency OMEGA");
320
321 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
322 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
323 V phi = MomentaF().computeRho(cell);
324 CollisionO().apply(cell, parameters);
325 const auto source = cell.template getField<descriptors::SOURCE>();
326 const auto u = cell.template getField<descriptors::VELOCITY>();
327 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
328 V c_c{};
329 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
331 }
332 V sourceTerm{};
333 sourceTerm += -V{2} + 0.5*descriptors::invCs2<V,DESCRIPTOR>()*c_c;
334 sourceTerm *= descriptors::t<V,DESCRIPTOR>(iPop)*source;
335 cell[iPop] += sourceTerm;
336 }
337 return {phi, util::normSqr<V,DESCRIPTOR::d>(u)};
338 };
339 };
340
341 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
342 using combined_parameters = typename COLLISION::parameters;
343};
344
347 static std::string getName() {
348 return "KupershtokhForcing";
349 }
350
351 template <typename DESCRIPTOR, typename MOMENTA>
352 using combined_momenta = typename momenta::Forced<MOMENTA>::template type<DESCRIPTOR>;
353
354 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
355 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
356
357 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
359 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
361 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
362
363 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
364 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
365 V u[DESCRIPTOR::d];
366 MomentaF().computeU(cell, u);
367 const auto statistic = CollisionO().apply(cell, parameters);
368 const auto force = cell.template getField<descriptors::FORCE>();
369 V uPlusDeltaU[DESCRIPTOR::d];
370 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
371 uPlusDeltaU[iVel] = u[iVel] + force[iVel];
372 }
373 V fEq[DESCRIPTOR::q] { };
374 V fEq2[DESCRIPTOR::q] { };
375 EquilibriumF().compute(cell, statistic.rho, u, fEq);
376 EquilibriumF().compute(cell, statistic.rho, uPlusDeltaU, fEq2);
377 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
378 cell[iPop] += fEq2[iPop] - fEq[iPop];
379 }
380 return statistic;
381 };
382 };
383
384 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
385 using combined_parameters = typename COLLISION::parameters;
386};
387
389struct Wagner {
390 static std::string getName() {
391 return "WagnerForcing";
392 }
393
394 template <typename DESCRIPTOR, typename MOMENTA>
395 using combined_momenta = typename MOMENTA::template type<DESCRIPTOR>;
396
397 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
398 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
399
400 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
402 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
403 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
404
405 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
406 "COLLISION must be parametrized using relaxation frequency OMEGA");
407
408 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
409 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
410 V rho, u[DESCRIPTOR::d];
411 MomentaF().computeRhoU(cell, rho, u);
412 CollisionO().apply(cell, parameters);
413 const V omega = cell.template getField<descriptors::OMEGA>();
414 const auto force = cell.template getField<descriptors::FORCE>();
415 const V d2_rho = cell.template getField<descriptors::SCALAR>();
417
418 // Forcing scheme
419 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
420 V c_u{};
421 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
422 c_u += descriptors::c<DESCRIPTOR>(iPop,iD)*u[iD];
423 }
425 V forceTerm{};
426 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
427 forceTerm +=
429 + c_u * descriptors::c<DESCRIPTOR>(iPop,iD)
430 ) * force[iD];
431 }
432
433 V delta_ij = 0;
434 for (int n = 0; n < DESCRIPTOR::d; ++n) {
435 for (int m = 0; m < DESCRIPTOR::d; ++m) {
436 int ind = n*DESCRIPTOR::d + m;
437
438 delta_ij = (n == m) ? 1 : 0;
439
440 psi_w[ind] = (V(1.)-omega/V(4.))*force[n]*force[m] + omega/V(12.)*( d2_rho )/rho*delta_ij;
441
442 // Computing the source term
443 forceTerm += V(9.) * ( descriptors::c<DESCRIPTOR>(iPop)[n]
444 * descriptors::c<DESCRIPTOR>(iPop)[m] - V(1./3.)*delta_ij ) / V(2.)
445 * psi_w[ind];
446 }
447 }
448
449 forceTerm *= descriptors::t<V,DESCRIPTOR>(iPop);
450 forceTerm *= rho;
451 cell[iPop] += forceTerm;
452 }
453
454 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
455 };
456 };
457 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
458 using combined_parameters = typename COLLISION::parameters;
459};
460
462class ShanChen {
463private:
464 template <typename EQUILIBRIUM>
465 struct VelocityShiftedEquilibrium {
466 static std::string getName() {
467 return "ShanChen<" + EQUILIBRIUM::getName() + ">";
468 }
469
470 template <typename DESCRIPTOR, typename MOMENTA>
471 struct type {
472 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
473 using EquilibriumF = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
474
475 template <typename CELL, typename RHO, typename U, typename FEQ, typename V=typename CELL::value_t>
476 CellStatistic<V> compute(CELL& cell, RHO& rho, U& u, FEQ& fEq) any_platform {
477 V uSqr{};
478 for (int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
479 uSqr += u[iVel] * u[iVel];
480 }
481 EquilibriumF().compute(cell, rho, u, fEq);
482 return {rho, uSqr};
483 };
484
485 template <typename CELL, typename PARAMETERS, typename FEQ, typename V=typename CELL::value_t>
486 CellStatistic<V> compute(CELL& cell, PARAMETERS& parameters, FEQ& fEq) any_platform {
487 V rho, u[DESCRIPTOR::d];
488 MomentaF().computeRhoU(cell, rho, u);
489 const auto force = cell.template getFieldPointer<descriptors::FORCE>();
490 for (int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
491 u[iVel] += force[iVel] / parameters.template get<descriptors::OMEGA>();
492 }
493 return compute(cell, rho, u, fEq);
494 };
495 };
496 };
497
498public:
499 static std::string getName() {
500 return "ShanChenForcing";
501 }
502
503 template <typename DESCRIPTOR, typename MOMENTA>
504 using combined_momenta = typename momenta::Forced<MOMENTA>::template type<DESCRIPTOR>;
505
506 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
507 using combined_equilibrium = typename VelocityShiftedEquilibrium<EQUILIBRIUM>::template type<DESCRIPTOR,MOMENTA>;
508
509 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
512 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,VelocityShiftedEquilibrium<EQUILIBRIUM>>;
513
514 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
515 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
516 V rho, u[DESCRIPTOR::d] { };
517 MomentaF().computeRhoU(cell, rho, u);
518 CollisionO().apply(cell, parameters);
519 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
520 };
521 };
522
523 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
524 using combined_parameters = typename COLLISION::parameters;
525};
526
528 static std::string getName() {
529 return "LinearVelocityForcing";
530 }
531
532 template <typename DESCRIPTOR, typename MOMENTA>
533 using combined_momenta = typename MOMENTA::template type<DESCRIPTOR>;
534
535 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
536 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
537
538 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
540 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
541 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
542
543 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
544 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) {
545 V rho, u[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
546 MomentaF().computeAllMomenta(cell, rho, u, pi);
547 auto force = cell.template getFieldPointer<descriptors::FORCE>();
548 constexpr int nDim = DESCRIPTOR::d;
549 V forceSave[nDim];
550 // adds a+Bu to force, where
551 // d=2: a1=v[0], a2=v[1], B11=v[2], B12=v[3], B21=v[4], B22=v[5]
552 // d=2: a1=v[0], a2=v[1], a3=v[2], B11=v[3], B12=v[4], B13=v[5], B21=v[6], B22=v[7], B23=v[8], B31=v[9], B32=v[10], B33=v[11]
553 auto v = cell.template getFieldPointer<descriptors::V12>();
554 for (int iDim=0; iDim<nDim; ++iDim) {
555 forceSave[iDim] = force[iDim];
556 force[iDim] += v[iDim];
557 for (int jDim=0; jDim<nDim; ++jDim) {
558 force[iDim] += v[jDim + iDim*nDim + nDim]*u[jDim];
559 }
560 }
561 for (int iVel=0; iVel<nDim; ++iVel) {
562 u[iVel] += force[iVel] / V{2.};
563 }
564
565 auto statistics = CollisionO().apply(cell, parameters);
566 V newOmega = parameters.template get<descriptors::OMEGA>();
567 lbm<DESCRIPTOR>::addExternalForce(cell, rho, u, newOmega, force);
568 // Writing back to froce fector
569 for (int iVel=0; iVel<nDim; ++iVel) {
570 force[iVel] = forceSave[iVel];
571 }
572 return statistics;
573 };
574 };
575
576 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
577 using combined_parameters = typename COLLISION::parameters;
578};
579
581struct HLBM {
582 static std::string getName() {
583 return "HLBM<Kupershtokh>";
584 }
585
586 template <typename DESCRIPTOR, typename MOMENTA>
587 using combined_momenta = typename MOMENTA::template wrap_momentum<
589 >::template type<DESCRIPTOR>;
590
591 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
592 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
593
594 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
596 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
598 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
599
600 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
601 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
602 V rho{};
604 MomentaF().computeRhoU(cell, rho, u);
605
606 const V porosity = cell.template getField<descriptors::POROSITY>();
607 auto statistic = CollisionO().apply(cell, parameters);
608
609 if (porosity < 1) {
610 // This is Kuperstokh forcing
611 Vector<V,DESCRIPTOR::d> uPlus = u;
612 uPlus += (V{1} - porosity)
613 * (cell.template getField<descriptors::VELOCITY>() - u);
614
615 V fEq[DESCRIPTOR::q] { };
616 V fEq2[DESCRIPTOR::q] { };
617 EquilibriumF().compute(cell, statistic.rho, u, fEq);
618 EquilibriumF().compute(cell, statistic.rho, uPlus, fEq2);
619 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
620 cell[iPop] += fEq2[iPop] - fEq[iPop];
621 }
622 return {-1,-1};
623 } else {
624 return statistic;
625 }
626 };
627 };
628
629 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
630 using combined_parameters = typename COLLISION::parameters;
631};
632
634 static std::string getName() {
635 return "ForcedHLBM<Kupershtokh>";
636 }
637
638 template <typename DESCRIPTOR, typename MOMENTA>
640 typename MOMENTA::template wrap_momentum<
642 >
643 >::template type<DESCRIPTOR>;
644
645 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
646 using combined_equilibrium = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
647
648 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
650 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
652 using CollisionO = typename COLLISION::template type<DESCRIPTOR,MOMENTA,EQUILIBRIUM>;
653
654 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
655 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
657 MomentaF().computeU(cell, u);
658
659 auto statistic = CollisionO().apply(cell, parameters);
660
661 const V porosity = cell.template getField<descriptors::POROSITY>();
662 const auto force = cell.template getField<descriptors::FORCE>();
663
664 auto fHLBM = (1 - porosity) * (cell.template getField<descriptors::VELOCITY>() - u);
665
666 // This is Kuperstokh forcing
667 Vector<V,DESCRIPTOR::d> uPlus = u + force + fHLBM;
668
669 V fEq[DESCRIPTOR::q] { };
670 V fEq2[DESCRIPTOR::q] { };
671 EquilibriumF().compute(cell, statistic.rho, u, fEq);
672 EquilibriumF().compute(cell, statistic.rho, uPlus, fEq2);
673 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
674 cell[iPop] += fEq2[iPop] - fEq[iPop];
675 }
676
677 if (porosity < 1) {
678 return {-1,-1};
679 } else {
680 V rho{};
681 MomentaF().computeRhoU(cell, rho, u);
682 return {rho, util::normSqr<V,DESCRIPTOR::d>(u)};
683 }
684 };
685 };
686
687 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM, typename COLLISION>
688 using combined_parameters = typename COLLISION::parameters;
689};
690
691}
692
693}
694
695#endif
Plain old scalar vector.
Dynamics combination rule implementing the forcing scheme by Shan and Chen.
Definition forcing.h:462
static std::string getName()
Definition forcing.h:499
typename VelocityShiftedEquilibrium< EQUILIBRIUM >::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:507
typename COLLISION::parameters combined_parameters
Definition forcing.h:524
typename momenta::Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:504
Interface for post-processing steps – header file.
constexpr T invCs2() any_platform
Definition functions.h:107
constexpr T t(unsigned iPop, tag::CUM) any_platform
Definition cum.h:108
constexpr int c(unsigned iPop, unsigned iDim) any_platform
Definition functions.h:83
constexpr int opposite(unsigned iPop) any_platform
Definition functions.h:95
MOMENTA Identity
Definition interface.h:324
auto normSqr(const ARRAY_LIKE &u) any_platform
Compute norm square of a d-dimensional vector.
Definition util.h:145
T norm(const std::vector< T > &a)
l2 norm of a vector of arbitrary length
Top level namespace for all of OpenLB.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
Return value of any collision.
Definition interface.h:45
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:91
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:98
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:92
Dynamics combination rule implementing the forcing scheme by Guo et al.
Definition forcing.h:78
static std::string getName()
Definition forcing.h:79
typename MOMENTA::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:84
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:87
typename COLLISION::parameters combined_parameters
Definition forcing.h:116
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:278
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:277
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:284
typename MOMENTA::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:270
static std::string getName()
Definition forcing.h:265
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:273
typename COLLISION::parameters combined_parameters
Definition forcing.h:298
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:650
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:652
combined_equilibrium< DESCRIPTOR, MOMENTA, EQUILIBRIUM > EquilibriumF
Definition forcing.h:651
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:655
static std::string getName()
Definition forcing.h:634
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:646
typename momenta::Forced< typename MOMENTA::template wrap_momentum< momenta::MovingPorousMomentum > >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:639
typename COLLISION::parameters combined_parameters
Definition forcing.h:688
static constexpr bool is_vectorizable
Definition forcing.h:54
typename Forced< MOMENTA >::template type< DESCRIPTOR > MomentaF
Definition forcing.h:51
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:60
typename COLLISION::template type< DESCRIPTOR, Forced< MOMENTA >, EQUILIBRIUM > CollisionO
Definition forcing.h:52
Dynamics combination rule implementing the forcing scheme by Guo et al.
Definition forcing.h:38
static std::string getName()
Definition forcing.h:39
typename Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:44
typename EQUILIBRIUM::template type< DESCRIPTOR, Forced< MOMENTA > > combined_equilibrium
Definition forcing.h:47
typename COLLISION::parameters combined_parameters
Definition forcing.h:73
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:601
combined_equilibrium< DESCRIPTOR, MOMENTA, EQUILIBRIUM > EquilibriumF
Definition forcing.h:597
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:598
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:596
Homogenized LBM modelling moving porous media.
Definition forcing.h:581
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:592
typename MOMENTA::template wrap_momentum< momenta::MovingPorousMomentum >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:587
typename COLLISION::parameters combined_parameters
Definition forcing.h:630
static std::string getName()
Definition forcing.h:582
combined_equilibrium< DESCRIPTOR, MOMENTA, EQUILIBRIUM > EquilibriumF
Definition forcing.h:360
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:364
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:359
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:361
Dynamics combination rule implementing the forcing scheme by Kupershtokh et al.
Definition forcing.h:346
typename momenta::Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:352
typename COLLISION::parameters combined_parameters
Definition forcing.h:385
static std::string getName()
Definition forcing.h:347
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:355
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:217
typename Forced< MOMENTA >::template type< DESCRIPTOR > MomentaF
Definition forcing.h:206
typename COLLISION::template type< DESCRIPTOR, Forced< MOMENTA >, EQUILIBRIUM > CollisionO
Definition forcing.h:207
static constexpr bool is_vectorizable
Definition forcing.h:212
typename COLLISION::parameters combined_parameters
Definition forcing.h:261
typename EQUILIBRIUM::template type< DESCRIPTOR, Forced< MOMENTA > > combined_equilibrium
Definition forcing.h:202
static std::string getName()
Definition forcing.h:194
typename Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:199
typename Forced< MOMENTA >::template type< DESCRIPTOR > MomentaF
Definition forcing.h:164
static constexpr bool is_vectorizable
Definition forcing.h:167
typename COLLISION::template type< DESCRIPTOR, Forced< MOMENTA >, EQUILIBRIUM > CollisionO
Definition forcing.h:165
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:175
typename Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:157
typename COLLISION::parameters combined_parameters
Definition forcing.h:189
static std::string getName()
Definition forcing.h:152
typename EQUILIBRIUM::template type< DESCRIPTOR, Forced< MOMENTA > > combined_equilibrium
Definition forcing.h:160
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters)
Definition forcing.h:544
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:541
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:540
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:536
static std::string getName()
Definition forcing.h:528
typename MOMENTA::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:533
typename COLLISION::parameters combined_parameters
Definition forcing.h:577
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:136
typename COLLISION::template type< DESCRIPTOR, Forced< MOMENTA >, EQUILIBRIUM > CollisionO
Definition forcing.h:132
typename Forced< MOMENTA >::template type< DESCRIPTOR > MomentaF
Definition forcing.h:131
Dynamics combination rule implementing the forcing scheme by Guo et al. with barycentric velocity.
Definition forcing.h:121
typename EQUILIBRIUM::template type< DESCRIPTOR, Forced< MOMENTA > > combined_equilibrium
Definition forcing.h:128
typename COLLISION::parameters combined_parameters
Definition forcing.h:147
static std::string getName()
Definition forcing.h:122
typename Forced< MOMENTA >::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:126
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:472
CellStatistic< V > compute(CELL &cell, PARAMETERS &parameters, FEQ &fEq) any_platform
Definition forcing.h:486
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > EquilibriumF
Definition forcing.h:473
CellStatistic< V > compute(CELL &cell, RHO &rho, U &u, FEQ &fEq) any_platform
Definition forcing.h:476
typename COLLISION::template type< DESCRIPTOR, MOMENTA, VelocityShiftedEquilibrium< EQUILIBRIUM > > CollisionO
Definition forcing.h:512
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:515
combined_momenta< DESCRIPTOR, MOMENTA > MomentaF
Definition forcing.h:511
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:403
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:409
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:402
Dynamics combination rule implementing the forcing scheme by A.J. Wagner, Phys. Rev....
Definition forcing.h:389
typename COLLISION::parameters combined_parameters
Definition forcing.h:458
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:398
typename MOMENTA::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:395
static std::string getName()
Definition forcing.h:390
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
Definition forcing.h:316
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
Definition forcing.h:322
typename MOMENTA::template type< DESCRIPTOR > MomentaF
Definition forcing.h:315
typename COLLISION::parameters combined_parameters
Definition forcing.h:342
typename MOMENTA::template type< DESCRIPTOR > combined_momenta
Definition forcing.h:308
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > combined_equilibrium
Definition forcing.h:311
static void addAllenCahnForce(CELL &cell, const OMEGA &omega, const FORCE &force) any_platform
Add a force term after BGK collision for constructing local Allen-Cahn-equation from Liang et al....
Definition lbm.h:589
static void addLiangForce(CELL &cell, const RHO &rho, const NABLARHO &nablarho, const U &u, const OMEGA &omega, const FORCE &force) any_platform
Add a force term after BGK collision for incompressible binary fluid model (Allen-Cahn phase-field) f...
Definition lbm.h:570
static void addAllenCahnSource(CELL &cell, const OMEGA &omega, const SOURCE &source) any_platform
Add a source term after BGK collision for constructing non-local Allen-Cahn-equation from Liu et al....
Definition lbm.h:604
static void addExternalForce(CELL &cell, const RHO &rho, const U &u, const OMEGA &omega, const FORCE &force) any_platform
Add a force term after BGK collision.
Definition lbm.h:545
Momentum of a moving porous medium.
Definition elements.h:1290
Compute number of elements of a symmetric d-dimensional tensor.
Definition util.h:216