OpenLB 1.7
Loading...
Searching...
No Matches
elements.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2006 Jonas Latt
4 * 2021 Julius Jessberger, Adrian Kummerländer
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
30#ifndef DYNAMICS_MOMENTA_ELEMENTS_H
31#define DYNAMICS_MOMENTA_ELEMENTS_H
32
33#include <type_traits>
34#include <functional>
35
37#include "dynamics/lbm.h"
38#include "core/vector.h"
39
40#include "core/util.h"
41#include "core/cell.hh"
42
43
44namespace olb {
45
46
47// forward declarations
48template<typename T, typename DESCRIPTOR> class CellD;
49template<typename DESCRIPTOR> struct lbHelpers;
50template<typename T, typename DESCRIPTOR, int direction, int orientation>
51struct BoundaryHelpers;
52
53
54namespace momenta {
55
56
57// --------------------- EXTRACTED HELPER FUNCTIONS ---------------------------
58
59template<int direction, int orientation, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
60V velocityBMRho(CELL& cell, const U& u) any_platform
61{
62 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
63 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
64
65 V rhoOnWall{};
66 for (auto e : onWallIndices) {
67 rhoOnWall += cell[e];
68 }
69
70 V rhoNormal{};
71 for (auto e : normalIndices) {
72 rhoNormal += cell[e];
73 }
74
75 return (V{2}*rhoNormal+rhoOnWall+V{1}) / (V{1}+orientation*u[direction]);
76}
77
78template<int direction, int orientation, typename CELL, typename U, typename FLUX, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
79V heatFluxBMRho(CELL& cell, const U& u, FLUX& flux) any_platform
80{
81 V rho = velocityBMRho<direction,orientation>(cell, u);
82 rho -= orientation * flux / (V{1} + orientation * u[direction]);
83 return rho;
84}
85
86
87// ---------------------- DENSITY STRUCTURES ----------------------------------
88
90 template <typename TYPE, typename CELL, typename RHO, typename DESCRIPTOR=typename CELL::descriptor_t>
91 void compute(CELL& cell, RHO& rho) any_platform
92 {
93 rho = 0;
94 }
95
96 template <typename TYPE, typename CELL, typename RHO>
97 void define(CELL& cell, const RHO& rho) any_platform {};
98
99 template <typename TYPE, typename CELL>
100 void initialize(CELL& cell) any_platform {};
101
102 template <typename TYPE, typename CELL, typename RHO>
103 void inverseShift(CELL& cell, RHO& rho) any_platform {};
104
105 static std::string getName(){
106 return "ZeroDensity";
107 }
108};
109
111 template <typename TYPE, typename CELL, typename RHO, typename DESCRIPTOR=typename CELL::descriptor_t>
112 void compute(CELL& cell, RHO& rho) any_platform
113 {
114 rho = 1;
115 }
116
117 template <typename TYPE, typename CELL, typename RHO>
118 void define(CELL& cell, const RHO& rho) any_platform {};
119
120 template <typename TYPE, typename CELL>
121 void initialize(CELL& cell) any_platform {};
122
123 template <typename TYPE, typename CELL, typename RHO>
124 void inverseShift(CELL& cell, RHO& rho) any_platform {};
125
126 static std::string getName(){
127 return "OneDensity";
128 }
129};
130
133 template <typename TYPE, typename CELL, typename RHO, typename DESCRIPTOR=typename CELL::descriptor_t>
134 void compute(CELL& cell, RHO& rho) any_platform
135 {
136 rho = lbm<DESCRIPTOR>::computeRho(cell);
137 }
138
139 template <typename TYPE, typename CELL, typename RHO>
140 void define(CELL& cell, const RHO& rho) any_platform {};
141
142 template <typename TYPE, typename CELL>
143 void initialize(CELL& cell) any_platform {};
144
145 template <typename TYPE, typename CELL, typename RHO>
146 void inverseShift(CELL& cell, RHO& rho) any_platform {};
147
148 static std::string getName(){
149 return "BulkDensity";
150 }
151};
152
153template<typename DENSITY>
155 template <typename TYPE, typename CELL, typename RHO>
156 void compute(CELL& cell, RHO& rho) any_platform
157 {
158 const auto source = cell.template getField<descriptors::SOURCE>();
159 DENSITY().template compute<TYPE>(cell, rho);
160 rho += 0.5 * source;
161 }
162
163 template <typename TYPE, typename CELL, typename RHO>
164 void define(CELL& cell, const RHO& rho) any_platform {};
165
166 template <typename TYPE, typename CELL>
167 void initialize(CELL& cell) any_platform {};
168
169 template <typename TYPE, typename CELL, typename RHO>
170 void inverseShift(CELL& cell, RHO& rho) any_platform
171 {
172 const auto source = cell.template getField<descriptors::SOURCE>();
173 rho -= 0.5 * source;
174 }
175
176 static std::string getName(){
177 return "SourcedDensity<" + DENSITY().getName() + ">";
178 }
179};
180
183 struct RHO : public descriptors::FIELD_BASE<1, 0, 0> { };
184
185 template <typename TYPE, typename CELL, typename R>
186 void compute(CELL& cell, R& rho) any_platform
187 {
188 rho = cell.template getField<RHO>();
189 }
190
191 template <typename TYPE, typename CELL, typename R>
192 void define(CELL& cell, const R& rho) any_platform
193 {
194 cell.template setField<RHO>(rho);
195 }
196
197 template <typename TYPE, typename CELL, typename V=typename CELL::value_t>
198 void initialize(CELL& cell) any_platform
199 {
200 cell.template setField<RHO>(V{1});
201 }
202
203 template <typename TYPE, typename CELL, typename RHO>
204 void inverseShift(CELL& cell, RHO& rho) any_platform {};
205
206 static std::string getName(){
207 return "FixedDensity";
208 }
209};
210
213 template <typename TYPE, typename CELL, typename RHO>
214 void compute(CELL& cell, RHO& rho) any_platform
215 {
216 rho = cell.template getField<descriptors::FORCE>()[0];
217 }
218
219 template <typename TYPE, typename CELL, typename RHO>
220 void define(CELL& cell, const RHO& rho) any_platform
221 {
222 cell.template getFieldPointer<descriptors::FORCE>()[0] = rho;
223 }
224
225 template <typename TYPE, typename CELL, typename V=typename CELL::value_t>
226 void initialize(CELL& cell) any_platform
227 {
228 cell.template getFieldPointer<descriptors::FORCE>()[0] = V{1};
229 }
230
231 template <typename TYPE, typename CELL, typename RHO>
232 void inverseShift(CELL& cell, RHO& rho) any_platform {};
233
234 static std::string getName(){
235 return "FreeEnergyInletOutletDensity";
236 }
237};
238
242template <int direction, int orientation>
244 template <typename TYPE, typename CELL, typename RHO, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
245 void compute(CELL& cell, RHO& rho) any_platform
246 {
247 const auto uNS = cell.template getField<descriptors::VELOCITY>();
248
249 V conduction[DESCRIPTOR::d];
250 TYPE().computeU(cell, conduction);
251 rho = heatFluxBMRho<direction,orientation>(cell, uNS.data(), conduction[direction]);
252 }
253
254 template <typename TYPE, typename CELL, typename RHO>
255 void define(CELL& cell, const RHO& rho) any_platform {};
256
257 template <typename TYPE, typename CELL>
258 void initialize(CELL& cell) any_platform {};
259
260 template <typename TYPE, typename CELL, typename RHO>
261 void inverseShift(CELL& cell, RHO& rho) any_platform {};
262
263 static std::string getName(){
264 return "HeatFluxBoundaryDensity";
265 }
266};
267
269template <int direction, int orientation>
271 template <typename TYPE, typename CELL, typename RHO, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
272 void compute(CELL& cell, RHO& rho) any_platform
273 {
274 V u[DESCRIPTOR::d];
275 TYPE().computeU(cell, u);
276 rho = velocityBMRho<direction,orientation>(cell, u);
277 }
278
279 template <typename TYPE, typename CELL, typename RHO>
280 void define(CELL& cell, const RHO& rho) any_platform {};
281
282 template <typename TYPE, typename CELL>
283 void initialize(CELL& cell) any_platform {};
284
285 template <typename TYPE, typename CELL, typename RHO>
286 void inverseShift(CELL& cell, RHO& rho) any_platform {};
287
288 static std::string getName(){
289 return "VelocityBoundaryDensity<" + std::to_string(direction) + "," + std::to_string(orientation) + ">";
290 }
291};
292
293template <int normalX, int normalY>
295 template <typename TYPE, typename CELL, typename RHO, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
296 void compute(CELL& cell, RHO& rho) any_platform
297 {
298 V u[DESCRIPTOR::d];
299 TYPE().computeU(cell, u);
300 const V rhoX = velocityBMRho<0,normalX>(cell, u);
301 const V rhoY = velocityBMRho<1,normalY>(cell, u);
302 rho = (rhoX + rhoY) / V{2};
303 }
304
305 template <typename TYPE, typename CELL, typename RHO>
306 void define(CELL& cell, const RHO& rho) any_platform {};
307
308 template <typename TYPE, typename CELL>
309 void initialize(CELL& cell) any_platform {};
310
311 template <typename TYPE, typename CELL, typename RHO>
312 void inverseShift(CELL& cell, RHO& rho) any_platform {};
313
314 static std::string getName(){
315 return "InnerCornerDensity2D";
316 }
317};
318
319template <int normalX, int normalY, int normalZ>
321 template <typename TYPE, typename CELL, typename RHO, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
322 void compute(CELL& cell, RHO& rho) any_platform
323 {
324 V u[DESCRIPTOR::d];
325 TYPE().computeU(cell, u);
326 const V rhoX = velocityBMRho<0,normalX>(cell, u);
327 const V rhoY = velocityBMRho<1,normalY>(cell, u);
328 const V rhoZ = velocityBMRho<2,normalZ>(cell, u);
329 rho = (rhoX + rhoY + rhoZ) / V(3);
330 }
331
332 template <typename TYPE, typename CELL, typename RHO>
333 void define(CELL& cell, const RHO& rho) any_platform {};
334
335 template <typename TYPE, typename CELL>
336 void initialize(CELL& cell) any_platform {};
337
338 template <typename TYPE, typename CELL, typename RHO>
339 void inverseShift(CELL& cell, RHO& rho) any_platform {};
340
341 static std::string getName(){
342 return "InnerCornerDensity3D";
343 }
344};
345
346template <int plane, int normal1, int normal2>
348 template <typename TYPE, typename CELL, typename RHO, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
349 void compute(CELL& cell, RHO& rho) any_platform
350 {
351 V u[DESCRIPTOR::d];
352 TYPE().computeU(cell, u);
353 const V rho1 = velocityBMRho<(plane+1)%3, normal1>(cell, u);
354 const V rho2 = velocityBMRho<(plane+2)%3, normal2>(cell, u);
355 rho = (rho1 + rho2) / V(2);
356 }
357
358 template <typename TYPE, typename CELL, typename RHO>
359 void define(CELL& cell, const RHO& rho) any_platform {};
360
361 template <typename TYPE, typename CELL>
362 void initialize(CELL& cell) any_platform {};
363
364 template <typename TYPE, typename CELL, typename RHO>
365 void inverseShift(CELL& cell, RHO& rho) any_platform {};
366
367 static std::string getName(){
368 return "InnerEdgeDensity3D";
369 }
370};
371
372
373// ---------------------- MOMENTUM STRUCTURES ---------------------------------
374
379 // compute the momentum
380 template <typename TYPE, typename CELL, typename J, typename DESCRIPTOR=typename CELL::descriptor_t>
381 void compute(CELL& cell, J& j) any_platform
382 {
384 }
385
386 // compute the velocity
387 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
388 void computeU(CELL& cell, U& u) any_platform
389 {
391 const V rho = TYPE().computeRho(cell);
392 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
393 u[iD] /= rho;
394 }
395 }
396
397 // define the velocity
398 template <typename TYPE, typename CELL, typename U>
399 void define(CELL& cell, const U& u) any_platform {};
400
401 template <typename TYPE, typename CELL>
402 void initialize(CELL& cell) any_platform {};
403
404 template <typename TYPE, typename CELL, typename U>
405 void inverseShift(CELL& cell, U& u) any_platform {};
406
407 static std::string getName() {
408 return "BulkMomentum";
409 }
410};
411
414 struct VELOCITY : public descriptors::FIELD_BASE<0, 1, 0> { };
415
416 // compute the momentum
417 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
418 void compute(CELL& cell, J& j) any_platform
419 {
420 const V rho = TYPE().computeRho(cell);
421 auto uExt = cell.template getField<VELOCITY>();
422 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
423 j[iD] = uExt[iD] * rho;
424 }
425 }
426
427 // compute the velocity
428 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
429 void computeU(CELL& cell, U& u) any_platform
430 {
431 const auto uExt = cell.template getField<VELOCITY>();
432 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
433 u[iD] = uExt[iD];
434 }
435 }
436
437 // define the velocity
438 template <typename TYPE, typename CELL, typename U>
439 void define(CELL& cell, const U& u) any_platform
440 {
441 cell.template setField<VELOCITY>(u);
442 }
443
444 template <typename TYPE, typename CELL, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
445 void initialize(CELL& cell) any_platform
446 {
448 cell.template setField<VELOCITY>(u);
449 }
450
451 template <typename TYPE, typename CELL, typename U>
452 void inverseShift(CELL& cell, U& u) any_platform {};
453
454 static std::string getName() {
455 return "FixedVelocityMomentumGeneric";
456 }
457};
458
462template <int direction, int orientation>
464 struct VELOCITY : public descriptors::FIELD_BASE<0, 1, 0> { };
465
466 // compute the momentum
467 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
468 void compute(CELL& cell, J& j) any_platform
469 {
470 computeU<TYPE>(cell, j);
471 const V rho = TYPE().computeRho(cell);
472 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
473 j[iD] *= rho;
474 }
475 }
476
477 // compute the velocity
478 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
479 void computeU(CELL& cell, U& u) any_platform
480 {
481 auto values = cell.template getField<VELOCITY>();
482 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
483 u[iD] = values[iD];
484 }
485 const V rho = TYPE().computeRho(cell);
486
487 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
488 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
489
490 V rhoOnWall = V{};
491 for (auto e : onWallIndices) {
492 rhoOnWall += cell[e];
493 }
494
495 V rhoNormal = V{};
496 for (auto e : normalIndices) {
497 rhoNormal += cell[e];
498 }
499
500 u[direction] = orientation * ((V{2}*rhoNormal+rhoOnWall+V{1}) / rho-V{1});
501 }
502
503 // define the velocity
504 template <typename TYPE, typename CELL, typename U>
505 void define(CELL& cell, const U& u) any_platform
506 {
507 cell.template setField<VELOCITY>(u);
508 }
509
510 template <typename TYPE, typename CELL, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
511 void initialize(CELL& cell) any_platform
512 {
513 V u[DESCRIPTOR::d] { V{} };
514 cell.template setField<VELOCITY>(u);
515 }
516
517 template <typename TYPE, typename CELL, typename U>
518 void inverseShift(CELL& cell, U& u) any_platform {};
519
520 static std::string getName() {
521 return "FixedPressureMomentum";
522 }
523};
524
527 // compute the momentum
528 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
529 void compute(CELL& cell, J& j) any_platform
530 {
531 const V rho = TYPE().computeRho(cell);
532 auto uExt = cell.template getField<descriptors::VELOCITY>();
533 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
534 j[iD] = uExt[iD] * rho;
535 }
536 }
537
538 // compute the velocity
539 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
540 void computeU(CELL& cell, U& u) any_platform
541 {
542 auto uExt = cell.template getField<descriptors::VELOCITY>();
543 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
544 u[iD] = uExt[iD];
545 }
546 }
547
548 // define the velocity
549 template <typename TYPE, typename CELL, typename U>
550 void define(CELL& cell, const U& u) any_platform
551 {
552 cell.template setField<descriptors::VELOCITY>(u);
553 }
554
555 template <typename TYPE, typename CELL, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
556 void initialize(CELL& cell) any_platform
557 {
558 const V u[DESCRIPTOR::d] = { V{} };
559 cell.template setField<descriptors::VELOCITY>(u);
560 }
561
562 template <typename TYPE, typename CELL, typename U>
563 void inverseShift(CELL& cell, U& u) any_platform {};
564
565 static std::string getName() {
566 return "FixedVelocityMomentum";
567 }
568};
569
574template <int direction, int orientation>
576 // compute (heat) transport
577 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
578 void compute(CELL& cell, J& j) any_platform
579 {
580 const V temp = TYPE().computeRho(cell);
581 const auto uNS = cell.template getFieldPointer<descriptors::VELOCITY>();
582 computeU<TYPE>(cell, j);
583 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
584 j[iD] += temp * uNS[iD];
585 }
586 }
587
588 // compute (heat) conduction
589 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
590 void computeU(CELL& cell, U& u) any_platform
591 {
592 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
593 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
594
595 const V temp = TYPE().computeRho(cell);
596 const auto uNS = cell.template getField<descriptors::VELOCITY>();
597
598 V uOnWall[DESCRIPTOR::d] = { V{} };
599 for (unsigned fIndex=0; fIndex<onWallIndices.size(); ++fIndex) {
600 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
601 uOnWall[iD] += (cell[onWallIndices[fIndex]]
602 - equilibrium<DESCRIPTOR>::firstOrder(onWallIndices[fIndex],temp,uNS.data()))
603 * descriptors::c<DESCRIPTOR>(onWallIndices[fIndex],iD);
604 }
605 }
606
607 V uNormal[DESCRIPTOR::d] = { V{} };
608 for (unsigned fIndex=0; fIndex<normalIndices.size(); ++fIndex) {
609 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
610 uNormal[iD] += (cell[normalIndices[fIndex]]
611 - equilibrium<DESCRIPTOR>::firstOrder(normalIndices[fIndex],temp,uNS.data()))
612 * descriptors::c<DESCRIPTOR>(normalIndices[fIndex],iD);
613 }
614 }
615
616 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
617 u[iD] = uOnWall[iD] + V(2) * uNormal[iD];
618 }
619 }
620
621 // define the conduction
622 template <typename TYPE, typename CELL, typename U>
623 void define(CELL& cell, const U& u) any_platform {};
624
625 template <typename TYPE, typename CELL>
626 void initialize(CELL& cell) any_platform {};
627
628 template <typename TYPE, typename CELL, typename U>
629 void inverseShift(CELL& cell, U& u) any_platform {};
630
631 static std::string getName() {
632 return "FixedTemperatureMomentum";
633 }
634};
635
636
643 struct VELOCITY : public descriptors::FIELD_BASE<0, 1, 0> { };
644
645 // compute (heat) transport
646 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
647 void compute(CELL& cell, J& j) any_platform
648 {
649 const V temp = TYPE().computeRho(cell);
650 const auto uNS = cell.template getFieldPointer<descriptors::VELOCITY>();
651 computeU<TYPE>(cell, j);
652 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
653 j[iD] += temp * uNS[iD];
654 }
655 }
656
657 // compute (heat) conduction
658 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
659 void computeU(CELL& cell, U& u) any_platform
660 {
661 const auto uExt = cell.template getFieldPointer<VELOCITY>();
662 for (int iD=0; iD < DESCRIPTOR::d; ++iD) {
663 u[iD] = uExt[iD];
664 }
665 }
666
667 // define the conduction
668 template <typename TYPE, typename CELL, typename U>
669 void define(CELL& cell, const U& u) any_platform
670 {
671 cell.template setField<VELOCITY>(u);
672 }
673
674 template <typename TYPE, typename CELL, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
675 void initialize(CELL& cell) any_platform
676 {
677 V u[DESCRIPTOR::d] = { V{} };
678 cell.template setField<VELOCITY>(u);
679 }
680
681 template <typename TYPE, typename CELL, typename U>
682 void inverseShift(CELL& cell, U& u) any_platform {};
683
684 static std::string getName() {
685 return "FixedVelocityMomentumAD";
686 }
687};
688
689
690template<int direction, int orientation>
692 template <typename TYPE, typename CELL, typename J>
693 void compute(CELL& cell, J& j) any_platform
694 {
695 FixedPressureMomentum<direction,orientation>().template compute<TYPE>(cell, j);
696 }
697
698 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
699 void computeU(CELL& cell, U& u) any_platform
700 {
701 for (int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
702 u[iVel] = V(0);
703 }
704 u[direction] = cell.template getFieldPointer<descriptors::FORCE>()[1];
705 }
706
707 template <typename TYPE, typename CELL, typename U>
708 void define(CELL& cell, const U& u) any_platform
709 {
710 cell.template getFieldPointer<descriptors::FORCE>()[1] = u[direction];
711 }
712
713 template <typename TYPE, typename CELL>
714 void initialize(CELL& cell) any_platform {
715 FixedPressureMomentum<direction,orientation>().template initialize<TYPE>(cell);
716 }
717
718 template <typename TYPE, typename CELL, typename U>
719 void inverseShift(CELL& cell, U& u) any_platform{};
720
721 static std::string getName() {
722 return "FreeEnergyInletOutletMomentum";
723 }
724};
725
726
728 template <typename TYPE, typename CELL, typename J, typename DESCRIPTOR=typename CELL::descriptor_t>
729 void compute(CELL& cell, J& j) any_platform
730 {
732 }
733
734 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
735 void computeU(CELL& cell, U& u) any_platform
736 {
737 auto force = cell.template getField<descriptors::FORCE>();
738 for (int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
739 u[iVel] = force[iVel];
740 }
741 }
742
743 template <typename TYPE, typename CELL, typename U>
744 void define(CELL& cell, const U& u) any_platform {}
745
746 template <typename TYPE, typename CELL>
747 void initialize(CELL& cell) any_platform {}
748
749 template <typename TYPE, typename CELL, typename U>
750 void inverseShift(CELL& cell, U& u) any_platform {};
751
752 static std::string getName() {
753 return "FreeEnergyMomentum";
754 }
755};
756
757
759 // compute the momentum
760 template <typename TYPE, typename CELL, typename J, typename DESCRIPTOR=typename CELL::descriptor_t>
761 void compute(CELL& cell, J& j) any_platform
762 {
764 }
765
766 // compute the velocity
767 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
768 void computeU(CELL& cell, U& u) any_platform
769 {
771
772 const V epsilon = cell.template getField<descriptors::EPSILON>();
773 const V nu = cell.template getField<descriptors::NU>();
774 const V k = cell.template getField<descriptors::K>();
775
776 auto bodyF = cell.template getFieldPointer<descriptors::BODY_FORCE>();
777
778 for (int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
779 u[iDim] += 0.5*epsilon*bodyF[iDim];
780 }
781
782 const V uMag = util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
783 const V Fe = 0.;//1.75/util::sqrt(150.*util::pow(epsilon,3));
784
785 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
786 const V c_1 = 0.5*epsilon*Fe/util::sqrt(k);
787
788 for (int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
789 u[iDim] /= (c_0 + util::sqrt(c_0*c_0 + c_1*uMag));
790 }
791 }
792
793 // define the velocity
794 template <typename TYPE, typename CELL, typename U>
795 void define(CELL& cell, const U& u) any_platform { }
796
797 template <typename TYPE, typename CELL>
798 void initialize(CELL& cell) any_platform { }
799
800 template <typename TYPE, typename CELL, typename U>
801 void inverseShift(CELL& cell, U& u) any_platform {};
802
803 static std::string getName() {
804 return "GuoZhaoMomentum";
805 }
806};
807
808
811 struct DISTANCES : public descriptors::FIELD_BASE<0, 0, 1> { };
812 struct VELOCITY : public descriptors::FIELD_BASE<0, 0, 3> { };
813 struct VELOCITY_COEFFICIENTS : public descriptors::FIELD_BASE<0, 0, 1> { };
814
815 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
816 void compute(CELL& cell, J& j) any_platform
817 {
818 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
819 j[iD] = V{};
820 }
821 }
822
823 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
824 void computeU(CELL& cell, U& u) any_platform
825 {
826 const auto distances = cell.template getFieldPointer<DISTANCES>();
827 const auto velocities = cell.template getFieldPointer<VELOCITY>();
828
829 for (int iD = 0; iD < DESCRIPTOR::d; iD++) {
830 u[iD] = V{};
831 }
832 unsigned counter = 0;
833 for (int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
834 if ( !util::nearZero(distances[iPop]+1) ) {
835 for (int iD = 0; iD < DESCRIPTOR::d; iD++) {
836 u[iD] += velocities[3*iPop + iD];
837 }
838 counter++;
839 }
840 }
841 if (counter!=0) {
842 for (int iD = 0; iD < DESCRIPTOR::d; iD++) {
843 u[iD] /= counter;
844 }
845 }
846 }
847
848 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
849 void define(CELL& cell, const U& u) any_platform
850 {
851 const auto distances = cell.template getFieldPointer<DISTANCES>();
852 auto velocities = cell.template getFieldPointer<VELOCITY>();
853 auto velocityCoefficient = cell.template getFieldPointer<VELOCITY_COEFFICIENTS>();
854
855 for (int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
856 if ( !util::nearZero(distances[iPop]+1) ) {
857 velocityCoefficient[iPop] = 0;
858 // scalar product of c(iPop) and u
859 for (int sum = 0; sum < DESCRIPTOR::d; sum++) { // +/- problem because of first stream than postprocess
860 velocityCoefficient[iPop] -= descriptors::c<DESCRIPTOR>(iPop,sum)*u[sum];
861 }
862 // compute summand for boundary condition
863 velocityCoefficient[iPop] *= 2*descriptors::invCs2<V,DESCRIPTOR>() * descriptors::t<V,DESCRIPTOR>(iPop);
864
865 for (int iD = 0; iD < DESCRIPTOR::d; iD++) {
866 velocities[3 * iPop + iD] = u[iD];
867 }
868 }
869 }
870 }
871
872 template <typename TYPE, typename CELL, typename DESCRIPTOR=typename CELL::descriptor_t>
873 void initialize(CELL& cell) any_platform
874 {
875 auto distances = cell.template getFieldPointer<DISTANCES>();
876 for (int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
877 distances[iPop] = -1;
878 }
879 }
880
881 template <typename TYPE, typename CELL, typename U>
882 void inverseShift(CELL& cell, U& u) any_platform {}
883
884 static std::string getName() {
885 return "OffBoundaryMomentum";
886 }
887};
888
889
892 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
893 void compute(CELL& cell, J& j) any_platform
894 {
895 std::array<V,DESCRIPTOR::q> cellShifted;
896 for (int iPop = 0; iPop <DESCRIPTOR::q; ++iPop) {
897 cellShifted[iPop] = cell[iPop] + descriptors::t<V,DESCRIPTOR>(iPop);
898 }
899 std::array<V,DESCRIPTOR::d> moment1;
900 moment1.fill( V(0) );
901 // sum_j v_j f_j
902 for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
903 for (int iDim = 0; iDim < DESCRIPTOR::d; ++iDim) {
904 moment1[iDim] += descriptors::c<DESCRIPTOR>(iPop,iDim)*cellShifted[iPop];
905 }
906 }
907 for (int iDim = 0; iDim < DESCRIPTOR::d; ++iDim) {
908 j[iDim] = moment1[iDim];
909 }
910 }
911
912 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
913 void computeU(CELL& cell, U& u) any_platform
914 {
915 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
916 u[iD] = V{};
917 }
918 }
919
920 template <typename TYPE, typename CELL, typename U>
921 void define(CELL& cell, const U& u) any_platform {}
922
923 template <typename TYPE, typename CELL>
924 void initialize(CELL& cell) any_platform {}
925
926 template <typename TYPE, typename CELL, typename U>
927 void inverseShift(CELL& cell, U& u) any_platform {}
928
929 static std::string getName() {
930 return "P1Momentum";
931 }
932};
933
934
937 template <typename TYPE, typename CELL, typename J, typename DESCRIPTOR=typename CELL::descriptor_t>
938 void compute(CELL& cell, J& j) any_platform
939 {
941 }
942
943 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
944 void computeU(CELL& cell, U& u) any_platform
945 {
946 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
947 u[iD] = V{};
948 }
949 }
950
951 template <typename TYPE, typename CELL, typename U>
952 void define(CELL& cell, const U& u) any_platform {}
953
954 template <typename TYPE, typename CELL>
955 void initialize(CELL& cell) any_platform {}
956
957 template <typename TYPE, typename CELL, typename U>
958 void inverseShift(CELL& cell, U& u) any_platform {}
959
960 static std::string getName() {
961 return "PoissonMomentum";
962 }
963};
964
965
967 // compute the momentum
968 template <typename TYPE, typename CELL, typename J, typename DESCRIPTOR=typename CELL::descriptor_t>
969 void compute(CELL& cell, J& j) any_platform
970 {
972 }
973
974 // compute the velocity
975 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
976 void computeU(CELL& cell, U& u) any_platform
977 {
979
980 const V porosity = cell.template getField<descriptors::POROSITY>();
981 for (int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
982 u[iDim] *= porosity;
983 }
984 }
985
986 // define the velocity
987 template <typename TYPE, typename CELL, typename U>
988 void define(CELL& cell, const U& u) any_platform { }
989
990 template <typename TYPE, typename CELL>
991 void initialize(CELL& cell) any_platform { }
992
993 template <typename TYPE, typename CELL, typename U>
994 void inverseShift(CELL& cell, U& u) any_platform {}
995
996 static std::string getName() {
997 return "PorousGuoMomentum";
998 }
999};
1000
1001
1002template<typename MOMENTUM>
1004 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1005 void compute(CELL& cell, J& j) any_platform
1006 {
1007 MOMENTUM().template compute<TYPE>(cell, j);
1008 }
1009
1010 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1011 void computeU(CELL& cell, U& u) any_platform
1012 {
1013 V rho{};
1014 lbm<DESCRIPTOR>::computeRhoU(cell, rho, u);
1015 V u_tmp[3] = {0., 0., 0.};
1016 if (cell.template getFieldPointer<descriptors::VELOCITY_DENOMINATOR>()[0] > std::numeric_limits<V>::epsilon()) {
1017 for (int i=0; i<DESCRIPTOR::d; i++) {
1018 u_tmp[i] = (V(1) - cell.template getField<descriptors::POROSITY>())
1019 * ( cell.template getFieldPointer<descriptors::VELOCITY_NUMERATOR>()[i]
1020 / cell.template getField<descriptors::VELOCITY_DENOMINATOR>()
1021 - u[i] );
1022 u[i] += V(0.5) * rho * u_tmp[i];
1023 }
1024 }
1025 }
1026
1027 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
1028 void define(CELL& cell, const U& u) any_platform
1029 {
1030 MOMENTUM().template define<TYPE>(cell, u);
1031 }
1032
1033 template <typename TYPE, typename CELL>
1034 void initialize(CELL& cell) any_platform
1035 {
1036 MOMENTUM().template initialize<TYPE>(cell);
1037 }
1038
1039 template <typename TYPE, typename CELL, typename U>
1040 void inverseShift(CELL& cell, U& u) any_platform {}
1041
1042 static std::string getName() {
1043 return "PorousParticleMomentum<" + MOMENTUM().getName() + ">";
1044 }
1045};
1046
1047
1050 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1051 void compute(CELL& cell, J& j) any_platform
1052 {
1053 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
1054 j[iD] = V{};
1055 }
1056 }
1057
1058 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1059 void computeU(CELL& cell, U& u) any_platform
1060 {
1061 for (int iD=0; iD<DESCRIPTOR::d; ++iD) {
1062 u[iD] = V{};
1063 }
1064 }
1065
1066 template <typename TYPE, typename CELL, typename U>
1067 void define(CELL& cell, const U& u) any_platform {}
1068
1069 template <typename TYPE, typename CELL>
1070 void initialize(CELL& cell) any_platform {}
1071
1072 template <typename TYPE, typename CELL, typename U>
1073 void inverseShift(CELL& cell, U& u) any_platform {}
1074
1075 static std::string getName() {
1076 return "ZeroMomentum";
1077 }
1078};
1079
1080
1081template<typename MOMENTUM>
1083 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1084 void compute(CELL& cell, J& j) any_platform
1085 {
1086 MOMENTUM().template compute<TYPE>(cell, j);
1087 }
1088
1089 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1090 void computeU(CELL& cell, U& u) any_platform
1091 {
1092 MOMENTUM().template computeU<TYPE>(cell, u);
1093 const auto force = cell.template getFieldPointer<descriptors::FORCE>();
1094 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
1095 u[iVel] += force[iVel] * V(0.5);
1096 }
1097 }
1098
1099 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
1100 void define(CELL& cell, const U& u) any_platform
1101 {
1102 MOMENTUM().template define<TYPE>(cell, u);
1103 }
1104
1105 template <typename TYPE, typename CELL>
1106 void initialize(CELL& cell) any_platform
1107 {
1108 MOMENTUM().template initialize<TYPE>(cell);
1109 }
1110
1111 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1112 void inverseShift(CELL& cell, U& u) any_platform {
1113 const auto force = cell.template getFieldPointer<descriptors::FORCE>();
1114 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
1115 u[iVel] -= force[iVel] * V(0.5);
1116 }
1117 }
1118
1119 static std::string getName() {
1120 return "ForcedMomentum<" + MOMENTUM().getName() + ">";
1121 }
1122};
1123
1124template<typename MOMENTUM>
1126 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1127 void compute(CELL& cell, J& j) any_platform
1128 {
1129 MOMENTUM().template compute<TYPE>(cell, j);
1130 }
1131
1132 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1133 void computeU(CELL& cell, U& u) any_platform
1134 {
1135 MOMENTUM().template computeU<TYPE>(cell, u);
1136 const V epsilon = cell.template getField<descriptors::EPSILON>();
1137 const V nu = cell.template getField<descriptors::NU>();
1138 const V k = cell.template getField<descriptors::K>();
1139 const auto bodyF = cell.template getFieldPointer<descriptors::BODY_FORCE>();
1140
1141 const V uMag = util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1142 const V Fe = 0.;//1.75/util::sqrt(150.*util::pow(epsilon,3));
1143 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
1144 const V c_1 = 0.5*epsilon*Fe/util::sqrt(k);
1145
1146 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
1147 u[iVel] += bodyF[iVel] * V(0.5) * epsilon;
1148 u[iVel] /= (c_0 + util::sqrt(c_0*c_0 + c_1*uMag));
1149 }
1150 }
1151
1152 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
1153 void define(CELL& cell, const U& u) any_platform
1154 {
1155 MOMENTUM().template define<TYPE>(cell, u);
1156 }
1157
1158 template <typename TYPE, typename CELL>
1159 void initialize(CELL& cell) any_platform
1160 {
1161 MOMENTUM().template initialize<TYPE>(cell);
1162 }
1163
1164 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1165 void inverseShift(CELL& cell, U& u) any_platform {
1166 const V epsilon = cell.template getField<descriptors::EPSILON>();
1167 const V nu = cell.template getField<descriptors::NU>();
1168 const V k = cell.template getField<descriptors::K>();
1169 const auto bodyF = cell.template getFieldPointer<descriptors::BODY_FORCE>();
1170
1171 const V uMag = util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1172 const V Fe = 0.;//1.75/util::sqrt(150.*util::pow(epsilon,3));
1173 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
1174 const V c_1 = 0.5*epsilon*Fe/util::sqrt(k);
1175
1176 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
1177 u[iVel] *= (c_0 + util::sqrt(c_0*c_0 + c_1*uMag));
1178 u[iVel] -= bodyF[iVel] * V(0.5) * epsilon;
1179 }
1180 }
1181
1182 static std::string getName() {
1183 return "GuoZhaoForcedMomentum<" + MOMENTUM().getName() + ">";
1184 }
1185};
1186
1187template<typename MOMENTUM>
1189 template <typename TYPE, typename CELL, typename J, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1190 void compute(CELL& cell, J& j) any_platform
1191 {
1192 MOMENTUM().template compute<TYPE>(cell, j);
1193 }
1194
1195 template <typename TYPE, typename CELL, typename U, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1196 void computeU(CELL& cell, U& u) any_platform
1197 {
1198 MOMENTUM().template computeU<TYPE>(cell, u);
1199 const V porosity = cell.template getField<descriptors::POROSITY>();
1200 for (int iVel=0; iVel < DESCRIPTOR::d; ++iVel) {
1201 u[iVel] *= porosity;
1202 }
1203 }
1204
1205 template <typename TYPE, typename CELL, typename U, typename DESCRIPTOR=typename CELL::descriptor_t>
1206 void define(CELL& cell, const U& u) any_platform
1207 {
1208 MOMENTUM().template define<TYPE>(cell, u);
1209 }
1210
1211 template <typename TYPE, typename CELL>
1212 void initialize(CELL& cell) any_platform
1213 {
1214 MOMENTUM().template initialize<TYPE>(cell);
1215 }
1216
1217 template <typename TYPE, typename CELL, typename U>
1218 void inverseShift(CELL& cell, U& u) any_platform {}
1219
1220 static std::string getName() {
1221 return "PorousMomentum<" + MOMENTUM().getName() + ">";
1222 }
1223};
1224
1225
1226// ---------------------- STRESS STRUCTURES -----------------------------------
1227
1232 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename DESCRIPTOR=typename CELL::descriptor_t>
1233 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1234 {
1235 lbm<DESCRIPTOR>::computeStress(cell, rho, u, pi);
1236 }
1237
1238 static std::string getName() {
1239 return "BulkStress";
1240 }
1241};
1242
1244template <int direction, int orientation>
1246 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1247 void compute(CELL& cell, RHO& rho, const U& u, PI& pi) any_platform
1248 {
1250 cell, rho, u, pi);
1251 }
1252
1253 static std::string getName() {
1254 return "RegularizedBoundaryStress";
1255 }
1256};
1257
1259template <int normalX, int normalY>
1261 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1262 void compute(CELL& cell, RHO& rho, const U& u, PI& pi) any_platform
1263 {
1265 cell.template getField<descriptors::POPULATION>());
1266 int v[DESCRIPTOR::d] = { -normalX, -normalY };
1267 int unknownF = util::findVelocity<DESCRIPTOR >(v);
1268
1269 if (unknownF != DESCRIPTOR::q) {
1270 int oppositeF = descriptors::opposite<DESCRIPTOR>(unknownF);
1271
1272 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
1273
1274 newCell[unknownF] = newCell[oppositeF]
1275 - equilibrium<DESCRIPTOR>::secondOrder(oppositeF, rho, u, uSqr)
1276 + equilibrium<DESCRIPTOR>::secondOrder(unknownF, rho, u, uSqr);
1277 }
1278
1279 lbm<DESCRIPTOR>::computeStress(newCell, rho, u, pi);
1280 }
1281
1282 static std::string getName() {
1283 return "InnerCornerStress2D";
1284 }
1285};
1286
1288template <int normalX, int normalY, int normalZ>
1290 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1291 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1292 {
1293 auto newCell = cell.template getField<descriptors::POPULATION>();
1294 int v[DESCRIPTOR::d] = { -normalX, -normalY, -normalZ };
1295 int unknownF = util::findVelocity<DESCRIPTOR >(v);
1296
1297 if (unknownF != DESCRIPTOR::q) {
1298 int oppositeF = descriptors::opposite<DESCRIPTOR>(unknownF);
1299
1300 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
1301
1302 newCell[unknownF] = newCell[oppositeF]
1303 - equilibrium<DESCRIPTOR>::secondOrder(oppositeF, rho, u, uSqr)
1304 + equilibrium<DESCRIPTOR>::secondOrder(unknownF, rho, u, uSqr);
1305 }
1306
1307 lbm<DESCRIPTOR>::computeStress(newCell, rho, u, pi);
1308 }
1309
1310 static std::string getName() {
1311 return "InnerCornerStress3D";
1312 }
1313};
1314
1316template <int plane, int normal1, int normal2>
1318 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1319 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1320 {
1321 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
1322 auto newCell = cell.template getField<descriptors::POPULATION>();
1323 for (int iPop=0; iPop<DESCRIPTOR::q; ++iPop) {
1324 if ( (descriptors::c<DESCRIPTOR>(iPop,(plane+1)%3) == -normal1) &&
1325 (descriptors::c<DESCRIPTOR>(iPop,(plane+2)%3) == -normal2) ) {
1326 int opp = descriptors::opposite<DESCRIPTOR>(iPop);
1327 newCell[iPop] = newCell[opp]
1328 - equilibrium<DESCRIPTOR>::secondOrder(opp, rho, u, uSqr)
1329 + equilibrium<DESCRIPTOR>::secondOrder(iPop, rho, u, uSqr);
1330 }
1331 }
1332 lbm<DESCRIPTOR>::computeStress(newCell, rho, u, pi);
1333 }
1334
1335 static std::string getName() {
1336 return "InnerEdgeStress3D";
1337 }
1338};
1339
1341struct NoStress {
1342 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI>
1343 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1344 {
1345 // TODO: Re-enable and fix downstream issue
1346 //throw std::bad_function_call();
1347 }
1348
1349 static std::string getName() {
1350 return "NoStress";
1351 }
1352};
1353
1356 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1357 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1358 {
1359 for (int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1360 pi[iPi] = V{};
1361 }
1362 }
1363
1364 static std::string getName() {
1365 return "ZeroStress";
1366 }
1367};
1368
1369template<typename STRESS>
1371 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1372 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1373 {
1374 V uNew[DESCRIPTOR::d] { };
1375 const auto force = cell.template getFieldPointer<descriptors::FORCE>();
1376 for (unsigned iD=0; iD < DESCRIPTOR::d; ++iD) {
1377 uNew[iD] = u[iD] - V{0.5} * force[iD];
1378 }
1379 STRESS().template compute<TYPE>(cell, rho, uNew, pi);
1380 V forceTensor[util::TensorVal<DESCRIPTOR>::n];
1381 // Creation of body force tensor (rho/2.)*(G_alpha*U_beta + U_alpha*G_Beta)
1382 int iPi = 0;
1383 for (int iAlpha=0; iAlpha < DESCRIPTOR::d; ++iAlpha) {
1384 for (int iBeta=iAlpha; iBeta < DESCRIPTOR::d; ++iBeta) {
1385 forceTensor[iPi] = V{0.5} * rho * (force[iAlpha]*uNew[iBeta] + uNew[iAlpha]*force[iBeta]);
1386 ++iPi;
1387 }
1388 }
1389 // Creation of second-order moment off-equilibrium tensor
1390 for (int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1391 pi[iPi] += forceTensor[iPi];
1392 }
1393 }
1394
1395 static std::string getName() {
1396 return "ForcedStress<" + STRESS().getName() + ">";
1397 }
1398};
1399
1400template<typename STRESS>
1402 template <typename TYPE, typename CELL, typename RHO, typename U, typename PI, typename V=typename CELL::value_t, typename DESCRIPTOR=typename CELL::descriptor_t>
1403 void compute(CELL& cell, const RHO& rho, const U& u, PI& pi) any_platform
1404 {
1405 V uNew[DESCRIPTOR::d] { };
1406 const V epsilon = cell.template getField<descriptors::EPSILON>();
1407 const V nu = cell.template getField<descriptors::NU>();
1408 const V k = cell.template getField<descriptors::K>();
1409 const auto bodyF = cell.template getFieldPointer<descriptors::BODY_FORCE>();
1410
1411 const V uMag = util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1412 const V Fe = 0.;//1.75/util::sqrt(150.*util::pow(epsilon,3));
1413 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
1414 const V c_1 = 0.5*epsilon*Fe/util::sqrt(k);
1415
1416 for (unsigned iD=0; iD < DESCRIPTOR::d; ++iD) {
1417 uNew[iD] = u[iD] * (c_0 + util::sqrt(c_0*c_0 + c_1*uMag)) - V{0.5} * bodyF[iD] * epsilon;
1418 }
1419 STRESS().template compute<TYPE>(cell, rho, uNew, pi);
1420 V forceTensor[util::TensorVal<DESCRIPTOR>::n];
1421 // Creation of body force tensor (rho/2.)*(G_alpha*U_beta + U_alpha*G_Beta)
1422 int iPi = 0;
1423 for (int iAlpha=0; iAlpha < DESCRIPTOR::d; ++iAlpha) {
1424 for (int iBeta=iAlpha; iBeta < DESCRIPTOR::d; ++iBeta) {
1425 forceTensor[iPi] = V{0.5} * rho * (bodyF[iAlpha]*uNew[iBeta] + uNew[iAlpha]*bodyF[iBeta]);
1426 ++iPi;
1427 }
1428 }
1429 // Creation of second-order moment off-equilibrium tensor
1430 for (int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1431 pi[iPi] += forceTensor[iPi];
1432 }
1433 }
1434
1435 static std::string getName() {
1436 return "GuoZhaoForcedStress<" + STRESS().getName() + ">";
1437 }
1438};
1439
1440} // namespace momenta
1441
1442} // namespace olb
1443
1444#endif
Definition of a LB cell – generic implementation.
Plain old scalar vector.
Definition vector.h:47
Descriptor for all types of 2D and 3D lattices.
V velocityBMRho(CELL &cell, const U &u) any_platform
Definition elements.h:60
V heatFluxBMRho(CELL &cell, const U &u, FLUX &flux) any_platform
Definition elements.h:79
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
bool nearZero(const ADf< T, DIM > &a)
Definition aDiff.h:1087
Top level namespace for all of OpenLB.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:78
All boundary helper functions are inside this structure.
Definition helper.h:34
static void computeStress(CELL &cell, T rho, const T u[DESCRIPTOR::d], T pi[util::TensorVal< DESCRIPTOR >::n]) any_platform
Definition helper.h:36
Base of a field whose size is defined by [C,U_1,...,U_N]^T * [1,V_1,...V_N].
static V secondOrder(int iPop, const RHO &rho, const U &u, const USQR &uSqr) any_platform
Computation of equilibrium distribution, second order in u.
Definition lbm.h:51
static V firstOrder(int iPop, const RHO &rho, const U &u) any_platform
Computation of equilibrium distribution, first order in u.
Definition lbm.h:37
Collection of common computations for LBM.
Definition lbm.h:182
static void computeJ(CELL &cell, J &j) any_platform
Computation of momentum.
Definition lbm.h:197
static V computeRho(CELL &cell) any_platform
Computation of density.
Definition lbm.h:185
static void computeStress(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Computation of stress tensor.
Definition lbm.h:229
static void computeRhoU(CELL &cell, RHO &rho, U &u) any_platform
Computation of hydrodynamic variables.
Definition lbm.h:219
Standard computation for density in the bulk as zeroth moment of the population.
Definition elements.h:132
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:146
static std::string getName()
Definition elements.h:148
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:134
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:140
void initialize(CELL &cell) any_platform
Definition elements.h:143
Standard computation for momentum in the bulk as first moment of the population.
Definition elements.h:378
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:388
void define(CELL &cell, const U &u) any_platform
Definition elements.h:399
void compute(CELL &cell, J &j) any_platform
Definition elements.h:381
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:405
void initialize(CELL &cell) any_platform
Definition elements.h:402
static std::string getName()
Definition elements.h:407
Standard stress computation as second moment of the population.
Definition elements.h:1231
static std::string getName()
Definition elements.h:1238
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1233
The density is fixed and stored in the external field RHO.
Definition elements.h:182
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:204
void initialize(CELL &cell) any_platform
Definition elements.h:198
void compute(CELL &cell, R &rho) any_platform
Definition elements.h:186
static std::string getName()
Definition elements.h:206
void define(CELL &cell, const R &rho) any_platform
Definition elements.h:192
The velocity is stored in the external field U, except for the component "direction",...
Definition elements.h:463
void compute(CELL &cell, J &j) any_platform
Definition elements.h:468
void initialize(CELL &cell) any_platform
Definition elements.h:511
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:479
void define(CELL &cell, const U &u) any_platform
Definition elements.h:505
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:518
static std::string getName()
Definition elements.h:520
The conduction is computed from density and population.
Definition elements.h:575
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:590
void compute(CELL &cell, J &j) any_platform
Definition elements.h:578
void define(CELL &cell, const U &u) any_platform
Definition elements.h:623
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:629
void initialize(CELL &cell) any_platform
Definition elements.h:626
The first moment (the heat conduction) is fixed.
Definition elements.h:642
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:682
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:659
void compute(CELL &cell, J &j) any_platform
Definition elements.h:647
void define(CELL &cell, const U &u) any_platform
Definition elements.h:669
void initialize(CELL &cell) any_platform
Definition elements.h:675
The velocity is fixed and stored in the external field U.
Definition elements.h:413
void define(CELL &cell, const U &u) any_platform
Definition elements.h:439
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:429
void initialize(CELL &cell) any_platform
Definition elements.h:445
void compute(CELL &cell, J &j) any_platform
Definition elements.h:418
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:452
The velocity is stored in the external field descriptors::VELOCITY.
Definition elements.h:526
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:563
static std::string getName()
Definition elements.h:565
void define(CELL &cell, const U &u) any_platform
Definition elements.h:550
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:540
void initialize(CELL &cell) any_platform
Definition elements.h:556
void compute(CELL &cell, J &j) any_platform
Definition elements.h:529
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:1090
void initialize(CELL &cell) any_platform
Definition elements.h:1106
void compute(CELL &cell, J &j) any_platform
Definition elements.h:1084
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:1112
void define(CELL &cell, const U &u) any_platform
Definition elements.h:1100
static std::string getName()
Definition elements.h:1119
static std::string getName()
Definition elements.h:1395
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1372
The density is stored in descriptors::FORCE[0] (TODO: absurd, to be changed)
Definition elements.h:212
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:220
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:232
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:214
void initialize(CELL &cell) any_platform
Definition elements.h:226
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:699
void compute(CELL &cell, J &j) any_platform
Definition elements.h:693
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:719
void initialize(CELL &cell) any_platform
Definition elements.h:714
void define(CELL &cell, const U &u) any_platform
Definition elements.h:708
void compute(CELL &cell, J &j) any_platform
Definition elements.h:729
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:750
void initialize(CELL &cell) any_platform
Definition elements.h:747
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:735
static std::string getName()
Definition elements.h:752
void define(CELL &cell, const U &u) any_platform
Definition elements.h:744
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:1165
void define(CELL &cell, const U &u) any_platform
Definition elements.h:1153
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:1133
void initialize(CELL &cell) any_platform
Definition elements.h:1159
void compute(CELL &cell, J &j) any_platform
Definition elements.h:1127
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1403
static std::string getName()
Definition elements.h:1435
void define(CELL &cell, const U &u) any_platform
Definition elements.h:795
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:768
static std::string getName()
Definition elements.h:803
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:801
void initialize(CELL &cell) any_platform
Definition elements.h:798
void compute(CELL &cell, J &j) any_platform
Definition elements.h:761
For fixed heat flux, the density is computed from flux, velocity and populations, similar to fixed ve...
Definition elements.h:243
void initialize(CELL &cell) any_platform
Definition elements.h:258
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:255
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:245
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:261
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:296
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:312
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:306
static std::string getName()
Definition elements.h:314
void initialize(CELL &cell) any_platform
Definition elements.h:309
void initialize(CELL &cell) any_platform
Definition elements.h:336
static std::string getName()
Definition elements.h:341
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:333
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:322
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:339
Computation of the stress tensor in an inner corner (2D case)
Definition elements.h:1260
void compute(CELL &cell, RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1262
static std::string getName()
Definition elements.h:1282
Computation of the stress tensor in an inner corner (3D case)
Definition elements.h:1289
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1291
static std::string getName()
Definition elements.h:1310
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:365
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:349
void initialize(CELL &cell) any_platform
Definition elements.h:362
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:359
static std::string getName()
Definition elements.h:367
Computation of the stress tensor in an inner edge.
Definition elements.h:1317
static std::string getName()
Definition elements.h:1335
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1319
Access to the stress computation is forbidden and raises an error.
Definition elements.h:1341
static std::string getName()
Definition elements.h:1349
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1343
For offLattice boundary conditions.
Definition elements.h:810
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:824
static std::string getName()
Definition elements.h:884
void define(CELL &cell, const U &u) any_platform
Definition elements.h:849
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:882
void initialize(CELL &cell) any_platform
Definition elements.h:873
void compute(CELL &cell, J &j) any_platform
Definition elements.h:816
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:118
static std::string getName()
Definition elements.h:126
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:112
void initialize(CELL &cell) any_platform
Definition elements.h:121
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:124
Momentum computation for P1 dynamics.
Definition elements.h:891
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:927
void define(CELL &cell, const U &u) any_platform
Definition elements.h:921
static std::string getName()
Definition elements.h:929
void compute(CELL &cell, J &j) any_platform
Definition elements.h:893
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:913
void initialize(CELL &cell) any_platform
Definition elements.h:924
Momentum computation for Poisson dynamics.
Definition elements.h:936
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:958
static std::string getName()
Definition elements.h:960
void compute(CELL &cell, J &j) any_platform
Definition elements.h:938
void define(CELL &cell, const U &u) any_platform
Definition elements.h:952
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:944
void initialize(CELL &cell) any_platform
Definition elements.h:955
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:976
static std::string getName()
Definition elements.h:996
void define(CELL &cell, const U &u) any_platform
Definition elements.h:988
void initialize(CELL &cell) any_platform
Definition elements.h:991
void compute(CELL &cell, J &j) any_platform
Definition elements.h:969
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:994
void initialize(CELL &cell) any_platform
Definition elements.h:1212
static std::string getName()
Definition elements.h:1220
void define(CELL &cell, const U &u) any_platform
Definition elements.h:1206
void compute(CELL &cell, J &j) any_platform
Definition elements.h:1190
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:1196
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:1218
void define(CELL &cell, const U &u) any_platform
Definition elements.h:1028
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:1040
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:1011
void compute(CELL &cell, J &j) any_platform
Definition elements.h:1005
void initialize(CELL &cell) any_platform
Definition elements.h:1034
Computation of the stress tensor for regularized boundary nodes.
Definition elements.h:1245
void compute(CELL &cell, RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1247
static std::string getName()
Definition elements.h:176
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:170
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:156
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:164
void initialize(CELL &cell) any_platform
Definition elements.h:167
Density computation for fixed velocity boundary.
Definition elements.h:270
void initialize(CELL &cell) any_platform
Definition elements.h:283
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:286
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:272
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:280
void inverseShift(CELL &cell, RHO &rho) any_platform
Definition elements.h:103
void compute(CELL &cell, RHO &rho) any_platform
Definition elements.h:91
void initialize(CELL &cell) any_platform
Definition elements.h:100
void define(CELL &cell, const RHO &rho) any_platform
Definition elements.h:97
static std::string getName()
Definition elements.h:105
Momentum is zero at solid material.
Definition elements.h:1049
void inverseShift(CELL &cell, U &u) any_platform
Definition elements.h:1073
void computeU(CELL &cell, U &u) any_platform
Definition elements.h:1059
void compute(CELL &cell, J &j) any_platform
Definition elements.h:1051
void define(CELL &cell, const U &u) any_platform
Definition elements.h:1067
void initialize(CELL &cell) any_platform
Definition elements.h:1070
static std::string getName()
Definition elements.h:1075
The stress is always zero.
Definition elements.h:1355
static std::string getName()
Definition elements.h:1364
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Definition elements.h:1357
Compute number of elements of a symmetric d-dimensional tensor.
Definition util.h:210
Set of functions commonly used in LB computations – header file.
efficient implementation of a vector class