30#ifndef DYNAMICS_MOMENTA_ELEMENTS_H
31#define DYNAMICS_MOMENTA_ELEMENTS_H
48template<
typename T,
typename DESCRIPTOR>
class CellD;
50template<
typename T,
typename DESCRIPTOR,
int direction,
int orientation>
59template<
int direction,
int orientation,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
62 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
63 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
66 for (
auto e : onWallIndices) {
71 for (
auto e : normalIndices) {
75 return (V{2}*rhoNormal+rhoOnWall+V{1}) / (V{1}+orientation*u[direction]);
78template<
int direction,
int orientation,
typename CELL,
typename U,
typename FLUX,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
81 V rho = velocityBMRho<direction,orientation>(cell, u);
82 rho -= orientation * flux / (V{1} + orientation * u[direction]);
90 template <
typename TYPE,
typename CELL,
typename RHO,
typename DESCRIPTOR=
typename CELL::descriptor_t>
96 template <
typename TYPE,
typename CELL,
typename RHO>
99 template <
typename TYPE,
typename CELL>
102 template <
typename TYPE,
typename CELL,
typename RHO>
106 return "ZeroDensity";
111 template <
typename TYPE,
typename CELL,
typename RHO,
typename DESCRIPTOR=
typename CELL::descriptor_t>
117 template <
typename TYPE,
typename CELL,
typename RHO>
120 template <
typename TYPE,
typename CELL>
123 template <
typename TYPE,
typename CELL,
typename RHO>
133 template <
typename TYPE,
typename CELL,
typename RHO,
typename DESCRIPTOR=
typename CELL::descriptor_t>
139 template <
typename TYPE,
typename CELL,
typename RHO>
142 template <
typename TYPE,
typename CELL>
145 template <
typename TYPE,
typename CELL,
typename RHO>
149 return "BulkDensity";
153template<
typename DENSITY>
155 template <
typename TYPE,
typename CELL,
typename RHO>
158 const auto source = cell.template getField<descriptors::SOURCE>();
159 DENSITY().template compute<TYPE>(cell, rho);
163 template <
typename TYPE,
typename CELL,
typename RHO>
166 template <
typename TYPE,
typename CELL>
169 template <
typename TYPE,
typename CELL,
typename RHO>
172 const auto source = cell.template getField<descriptors::SOURCE>();
177 return "SourcedDensity<" + DENSITY().getName() +
">";
185 template <
typename TYPE,
typename CELL,
typename R>
188 rho = cell.template getField<RHO>();
191 template <
typename TYPE,
typename CELL,
typename R>
194 cell.template setField<RHO>(rho);
197 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t>
200 cell.template setField<RHO>(V{1});
203 template <
typename TYPE,
typename CELL,
typename RHO>
207 return "FixedDensity";
213 template <
typename TYPE,
typename CELL,
typename RHO>
216 rho = cell.template getField<descriptors::FORCE>()[0];
219 template <
typename TYPE,
typename CELL,
typename RHO>
222 cell.template getFieldPointer<descriptors::FORCE>()[0] = rho;
225 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t>
228 cell.template getFieldPointer<descriptors::FORCE>()[0] = V{1};
231 template <
typename TYPE,
typename CELL,
typename RHO>
235 return "FreeEnergyInletOutletDensity";
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>
247 const auto uNS = cell.template getField<descriptors::VELOCITY>();
249 V conduction[DESCRIPTOR::d];
250 TYPE().computeU(cell, conduction);
251 rho = heatFluxBMRho<direction,orientation>(cell, uNS.data(), conduction[direction]);
254 template <
typename TYPE,
typename CELL,
typename RHO>
257 template <
typename TYPE,
typename CELL>
260 template <
typename TYPE,
typename CELL,
typename RHO>
264 return "HeatFluxBoundaryDensity";
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>
275 TYPE().computeU(cell, u);
276 rho = velocityBMRho<direction,orientation>(cell, u);
279 template <
typename TYPE,
typename CELL,
typename RHO>
282 template <
typename TYPE,
typename CELL>
285 template <
typename TYPE,
typename CELL,
typename RHO>
289 return "VelocityBoundaryDensity<" + std::to_string(direction) +
"," + std::to_string(orientation) +
">";
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>
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};
305 template <
typename TYPE,
typename CELL,
typename RHO>
308 template <
typename TYPE,
typename CELL>
311 template <
typename TYPE,
typename CELL,
typename RHO>
315 return "InnerCornerDensity2D";
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>
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);
332 template <
typename TYPE,
typename CELL,
typename RHO>
335 template <
typename TYPE,
typename CELL>
338 template <
typename TYPE,
typename CELL,
typename RHO>
342 return "InnerCornerDensity3D";
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>
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);
358 template <
typename TYPE,
typename CELL,
typename RHO>
361 template <
typename TYPE,
typename CELL>
364 template <
typename TYPE,
typename CELL,
typename RHO>
368 return "InnerEdgeDensity3D";
380 template <
typename TYPE,
typename CELL,
typename J,
typename DESCRIPTOR=
typename CELL::descriptor_t>
387 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
391 const V rho = TYPE().computeRho(cell);
392 for (
int iD=0; iD < DESCRIPTOR::d; ++iD) {
398 template <
typename TYPE,
typename CELL,
typename U>
401 template <
typename TYPE,
typename CELL>
404 template <
typename TYPE,
typename CELL,
typename U>
408 return "BulkMomentum";
417 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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;
428 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
431 const auto uExt = cell.template getField<VELOCITY>();
432 for (
int iD=0; iD < DESCRIPTOR::d; ++iD) {
438 template <
typename TYPE,
typename CELL,
typename U>
441 cell.template setField<VELOCITY>(u);
444 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
448 cell.template setField<VELOCITY>(u);
451 template <
typename TYPE,
typename CELL,
typename U>
455 return "FixedVelocityMomentumGeneric";
462template <
int direction,
int orientation>
467 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
470 computeU<TYPE>(cell, j);
471 const V rho = TYPE().computeRho(cell);
472 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
478 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
481 auto values = cell.template getField<VELOCITY>();
482 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
485 const V rho = TYPE().computeRho(cell);
487 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
488 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
491 for (
auto e : onWallIndices) {
492 rhoOnWall += cell[e];
496 for (
auto e : normalIndices) {
497 rhoNormal += cell[e];
500 u[direction] = orientation * ((V{2}*rhoNormal+rhoOnWall+V{1}) / rho-V{1});
504 template <
typename TYPE,
typename CELL,
typename U>
507 cell.template setField<VELOCITY>(u);
510 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
513 V u[DESCRIPTOR::d] { V{} };
514 cell.template setField<VELOCITY>(u);
517 template <
typename TYPE,
typename CELL,
typename U>
521 return "FixedPressureMomentum";
528 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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;
539 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
542 auto uExt = cell.template getField<descriptors::VELOCITY>();
543 for (
int iD=0; iD < DESCRIPTOR::d; ++iD) {
549 template <
typename TYPE,
typename CELL,
typename U>
552 cell.template setField<descriptors::VELOCITY>(u);
555 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
558 const V u[DESCRIPTOR::d] = { V{} };
559 cell.template setField<descriptors::VELOCITY>(u);
562 template <
typename TYPE,
typename CELL,
typename U>
566 return "FixedVelocityMomentum";
574template <
int direction,
int orientation>
577 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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];
589 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
592 constexpr auto onWallIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,0>();
593 constexpr auto normalIndices = util::populationsContributingToVelocity<DESCRIPTOR,direction,orientation>();
595 const V temp = TYPE().computeRho(cell);
596 const auto uNS = cell.template getField<descriptors::VELOCITY>();
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]]
603 * descriptors::c<DESCRIPTOR>(onWallIndices[fIndex],iD);
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]]
612 * descriptors::c<DESCRIPTOR>(normalIndices[fIndex],iD);
616 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
617 u[iD] = uOnWall[iD] + V(2) * uNormal[iD];
622 template <
typename TYPE,
typename CELL,
typename U>
625 template <
typename TYPE,
typename CELL>
628 template <
typename TYPE,
typename CELL,
typename U>
632 return "FixedTemperatureMomentum";
646 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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];
658 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
661 const auto uExt = cell.template getFieldPointer<VELOCITY>();
662 for (
int iD=0; iD < DESCRIPTOR::d; ++iD) {
668 template <
typename TYPE,
typename CELL,
typename U>
671 cell.template setField<VELOCITY>(u);
674 template <
typename TYPE,
typename CELL,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
677 V u[DESCRIPTOR::d] = { V{} };
678 cell.template setField<VELOCITY>(u);
681 template <
typename TYPE,
typename CELL,
typename U>
685 return "FixedVelocityMomentumAD";
690template<
int direction,
int orientation>
692 template <
typename TYPE,
typename CELL,
typename J>
698 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
701 for (
int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
704 u[direction] = cell.template getFieldPointer<descriptors::FORCE>()[1];
707 template <
typename TYPE,
typename CELL,
typename U>
710 cell.template getFieldPointer<descriptors::FORCE>()[1] = u[direction];
713 template <
typename TYPE,
typename CELL>
718 template <
typename TYPE,
typename CELL,
typename U>
722 return "FreeEnergyInletOutletMomentum";
728 template <
typename TYPE,
typename CELL,
typename J,
typename DESCRIPTOR=
typename CELL::descriptor_t>
734 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
737 auto force = cell.template getField<descriptors::FORCE>();
738 for (
int iVel=0; iVel<DESCRIPTOR::d; ++iVel) {
739 u[iVel] = force[iVel];
743 template <
typename TYPE,
typename CELL,
typename U>
746 template <
typename TYPE,
typename CELL>
749 template <
typename TYPE,
typename CELL,
typename U>
753 return "FreeEnergyMomentum";
760 template <
typename TYPE,
typename CELL,
typename J,
typename DESCRIPTOR=
typename CELL::descriptor_t>
767 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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>();
776 auto bodyF = cell.template getFieldPointer<descriptors::BODY_FORCE>();
778 for (
int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
779 u[iDim] += 0.5*epsilon*bodyF[iDim];
782 const V uMag =
util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
785 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
788 for (
int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
789 u[iDim] /= (c_0 +
util::sqrt(c_0*c_0 + c_1*uMag));
794 template <
typename TYPE,
typename CELL,
typename U>
797 template <
typename TYPE,
typename CELL>
800 template <
typename TYPE,
typename CELL,
typename U>
804 return "GuoZhaoMomentum";
815 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
818 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
823 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
826 const auto distances = cell.template getFieldPointer<DISTANCES>();
827 const auto velocities = cell.template getFieldPointer<VELOCITY>();
829 for (
int iD = 0; iD < DESCRIPTOR::d; iD++) {
832 unsigned counter = 0;
833 for (
int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
835 for (
int iD = 0; iD < DESCRIPTOR::d; iD++) {
836 u[iD] += velocities[3*iPop + iD];
842 for (
int iD = 0; iD < DESCRIPTOR::d; iD++) {
848 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
851 const auto distances = cell.template getFieldPointer<DISTANCES>();
852 auto velocities = cell.template getFieldPointer<VELOCITY>();
853 auto velocityCoefficient = cell.template getFieldPointer<VELOCITY_COEFFICIENTS>();
855 for (
int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
857 velocityCoefficient[iPop] = 0;
859 for (
int sum = 0; sum < DESCRIPTOR::d; sum++) {
860 velocityCoefficient[iPop] -= descriptors::c<DESCRIPTOR>(iPop,sum)*u[sum];
863 velocityCoefficient[iPop] *= 2*descriptors::invCs2<V,DESCRIPTOR>() * descriptors::t<V,DESCRIPTOR>(iPop);
865 for (
int iD = 0; iD < DESCRIPTOR::d; iD++) {
866 velocities[3 * iPop + iD] = u[iD];
872 template <
typename TYPE,
typename CELL,
typename DESCRIPTOR=
typename CELL::descriptor_t>
875 auto distances = cell.template getFieldPointer<DISTANCES>();
876 for (
int iPop = 0; iPop < DESCRIPTOR::q; iPop++) {
877 distances[iPop] = -1;
881 template <
typename TYPE,
typename CELL,
typename U>
885 return "OffBoundaryMomentum";
892 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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);
899 std::array<V,DESCRIPTOR::d> moment1;
900 moment1.fill( V(0) );
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];
907 for (
int iDim = 0; iDim < DESCRIPTOR::d; ++iDim) {
908 j[iDim] = moment1[iDim];
912 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
915 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
920 template <
typename TYPE,
typename CELL,
typename U>
923 template <
typename TYPE,
typename CELL>
926 template <
typename TYPE,
typename CELL,
typename U>
937 template <
typename TYPE,
typename CELL,
typename J,
typename DESCRIPTOR=
typename CELL::descriptor_t>
943 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
946 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
951 template <
typename TYPE,
typename CELL,
typename U>
954 template <
typename TYPE,
typename CELL>
957 template <
typename TYPE,
typename CELL,
typename U>
961 return "PoissonMomentum";
968 template <
typename TYPE,
typename CELL,
typename J,
typename DESCRIPTOR=
typename CELL::descriptor_t>
975 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
980 const V porosity = cell.template getField<descriptors::POROSITY>();
981 for (
int iDim=0; iDim<DESCRIPTOR::d; ++iDim) {
987 template <
typename TYPE,
typename CELL,
typename U>
990 template <
typename TYPE,
typename CELL>
993 template <
typename TYPE,
typename CELL,
typename U>
997 return "PorousGuoMomentum";
1002template<
typename MOMENTUM>
1004 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1007 MOMENTUM().template compute<TYPE>(cell, j);
1010 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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>()
1022 u[i] += V(0.5) * rho * u_tmp[i];
1027 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1030 MOMENTUM().template define<TYPE>(cell, u);
1033 template <
typename TYPE,
typename CELL>
1036 MOMENTUM().template initialize<TYPE>(cell);
1039 template <
typename TYPE,
typename CELL,
typename U>
1043 return "PorousParticleMomentum<" + MOMENTUM().getName() +
">";
1050 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1053 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
1058 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1061 for (
int iD=0; iD<DESCRIPTOR::d; ++iD) {
1066 template <
typename TYPE,
typename CELL,
typename U>
1069 template <
typename TYPE,
typename CELL>
1072 template <
typename TYPE,
typename CELL,
typename U>
1076 return "ZeroMomentum";
1081template<
typename MOMENTUM>
1083 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1086 MOMENTUM().template compute<TYPE>(cell, j);
1089 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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);
1099 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1102 MOMENTUM().template define<TYPE>(cell, u);
1105 template <
typename TYPE,
typename CELL>
1108 MOMENTUM().template initialize<TYPE>(cell);
1111 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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);
1120 return "ForcedMomentum<" + MOMENTUM().getName() +
">";
1124template<
typename MOMENTUM>
1126 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1129 MOMENTUM().template compute<TYPE>(cell, j);
1132 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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>();
1141 const V uMag =
util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1143 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
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));
1152 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1155 MOMENTUM().template define<TYPE>(cell, u);
1158 template <
typename TYPE,
typename CELL>
1161 MOMENTUM().template initialize<TYPE>(cell);
1164 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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>();
1171 const V uMag =
util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1173 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
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;
1183 return "GuoZhaoForcedMomentum<" + MOMENTUM().getName() +
">";
1187template<
typename MOMENTUM>
1189 template <
typename TYPE,
typename CELL,
typename J,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1192 MOMENTUM().template compute<TYPE>(cell, j);
1195 template <
typename TYPE,
typename CELL,
typename U,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
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;
1205 template <
typename TYPE,
typename CELL,
typename U,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1208 MOMENTUM().template define<TYPE>(cell, u);
1211 template <
typename TYPE,
typename CELL>
1214 MOMENTUM().template initialize<TYPE>(cell);
1217 template <
typename TYPE,
typename CELL,
typename U>
1221 return "PorousMomentum<" + MOMENTUM().getName() +
">";
1232 template <
typename TYPE,
typename CELL,
typename RHO,
typename U,
typename PI,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1239 return "BulkStress";
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>
1254 return "RegularizedBoundaryStress";
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>
1265 cell.template getField<descriptors::POPULATION>());
1266 int v[DESCRIPTOR::d] = { -normalX, -normalY };
1267 int unknownF = util::findVelocity<DESCRIPTOR >(v);
1269 if (unknownF != DESCRIPTOR::q) {
1270 int oppositeF = descriptors::opposite<DESCRIPTOR>(unknownF);
1272 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
1274 newCell[unknownF] = newCell[oppositeF]
1283 return "InnerCornerStress2D";
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>
1293 auto newCell = cell.template getField<descriptors::POPULATION>();
1294 int v[DESCRIPTOR::d] = { -normalX, -normalY, -normalZ };
1295 int unknownF = util::findVelocity<DESCRIPTOR >(v);
1297 if (unknownF != DESCRIPTOR::q) {
1298 int oppositeF = descriptors::opposite<DESCRIPTOR>(unknownF);
1300 V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
1302 newCell[unknownF] = newCell[oppositeF]
1311 return "InnerCornerStress3D";
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>
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]
1336 return "InnerEdgeStress3D";
1342 template <
typename TYPE,
typename CELL,
typename RHO,
typename U,
typename PI>
1356 template <
typename TYPE,
typename CELL,
typename RHO,
typename U,
typename PI,
typename V=
typename CELL::value_t,
typename DESCRIPTOR=
typename CELL::descriptor_t>
1359 for (
int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1365 return "ZeroStress";
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>
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];
1379 STRESS().template compute<TYPE>(cell, rho, uNew, pi);
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]);
1390 for (
int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1391 pi[iPi] += forceTensor[iPi];
1396 return "ForcedStress<" + STRESS().getName() +
">";
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>
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>();
1411 const V uMag =
util::sqrt( util::normSqr<V,DESCRIPTOR::d>(u) );
1413 const V c_0 = 0.5*(1 + 0.5*epsilon*nu/k);
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;
1419 STRESS().template compute<TYPE>(cell, rho, uNew, pi);
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]);
1430 for (
int iPi=0; iPi < util::TensorVal<DESCRIPTOR>::n; ++iPi) {
1431 pi[iPi] += forceTensor[iPi];
1436 return "GuoZhaoForcedStress<" + STRESS().getName() +
">";
Definition of a LB cell – generic implementation.
Descriptor for all types of 2D and 3D lattices.
V velocityBMRho(CELL &cell, const U &u) any_platform
V heatFluxBMRho(CELL &cell, const U &u, FLUX &flux) any_platform
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
bool nearZero(const ADf< T, DIM > &a)
Top level namespace for all of OpenLB.
All boundary helper functions are inside this structure.
static void computeStress(CELL &cell, T rho, const T u[DESCRIPTOR::d], T pi[util::TensorVal< DESCRIPTOR >::n]) any_platform
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.
static V firstOrder(int iPop, const RHO &rho, const U &u) any_platform
Computation of equilibrium distribution, first order in u.
Collection of common computations for LBM.
static void computeJ(CELL &cell, J &j) any_platform
Computation of momentum.
static V computeRho(CELL &cell) any_platform
Computation of density.
static void computeStress(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Computation of stress tensor.
static void computeRhoU(CELL &cell, RHO &rho, U &u) any_platform
Computation of hydrodynamic variables.
Standard computation for density in the bulk as zeroth moment of the population.
void inverseShift(CELL &cell, RHO &rho) any_platform
static std::string getName()
void compute(CELL &cell, RHO &rho) any_platform
void define(CELL &cell, const RHO &rho) any_platform
void initialize(CELL &cell) any_platform
Standard computation for momentum in the bulk as first moment of the population.
void computeU(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
Standard stress computation as second moment of the population.
static std::string getName()
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
The density is fixed and stored in the external field RHO.
void inverseShift(CELL &cell, RHO &rho) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, R &rho) any_platform
static std::string getName()
void define(CELL &cell, const R &rho) any_platform
The velocity is stored in the external field U, except for the component "direction",...
void compute(CELL &cell, J &j) any_platform
void initialize(CELL &cell) any_platform
void computeU(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
void inverseShift(CELL &cell, U &u) any_platform
static std::string getName()
The conduction is computed from density and population.
void computeU(CELL &cell, U &u) any_platform
void compute(CELL &cell, J &j) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
The first moment (the heat conduction) is fixed.
void inverseShift(CELL &cell, U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void define(CELL &cell, const U &u) any_platform
static std::string getName()
void initialize(CELL &cell) any_platform
The velocity is fixed and stored in the external field U.
void define(CELL &cell, const U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
The velocity is stored in the external field descriptors::VELOCITY.
void inverseShift(CELL &cell, U &u) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
void computeU(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
static std::string getName()
static std::string getName()
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
The density is stored in descriptors::FORCE[0] (TODO: absurd, to be changed)
void define(CELL &cell, const RHO &rho) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
void computeU(CELL &cell, U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
static std::string getName()
void initialize(CELL &cell) any_platform
void define(CELL &cell, const U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void computeU(CELL &cell, U &u) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
static std::string getName()
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
static std::string getName()
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
For fixed heat flux, the density is computed from flux, velocity and populations, similar to fixed ve...
static std::string getName()
void initialize(CELL &cell) any_platform
void define(CELL &cell, const RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
void define(CELL &cell, const RHO &rho) any_platform
static std::string getName()
void initialize(CELL &cell) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
void define(CELL &cell, const RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
Computation of the stress tensor in an inner corner (2D case)
void compute(CELL &cell, RHO &rho, const U &u, PI &pi) any_platform
static std::string getName()
Computation of the stress tensor in an inner corner (3D case)
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
static std::string getName()
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void initialize(CELL &cell) any_platform
void define(CELL &cell, const RHO &rho) any_platform
static std::string getName()
Computation of the stress tensor in an inner edge.
static std::string getName()
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Access to the stress computation is forbidden and raises an error.
static std::string getName()
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
For offLattice boundary conditions.
void computeU(CELL &cell, U &u) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
void define(CELL &cell, const RHO &rho) any_platform
static std::string getName()
void compute(CELL &cell, RHO &rho) any_platform
void initialize(CELL &cell) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
Momentum computation for P1 dynamics.
void inverseShift(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
static std::string getName()
void compute(CELL &cell, J &j) any_platform
void computeU(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
Momentum computation for Poisson dynamics.
void inverseShift(CELL &cell, U &u) any_platform
static std::string getName()
void compute(CELL &cell, J &j) any_platform
void define(CELL &cell, const U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
void computeU(CELL &cell, U &u) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void initialize(CELL &cell) any_platform
void compute(CELL &cell, J &j) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
void define(CELL &cell, const U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void computeU(CELL &cell, U &u) any_platform
void inverseShift(CELL &cell, U &u) any_platform
void define(CELL &cell, const U &u) any_platform
static std::string getName()
void inverseShift(CELL &cell, U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void initialize(CELL &cell) any_platform
Computation of the stress tensor for regularized boundary nodes.
void compute(CELL &cell, RHO &rho, const U &u, PI &pi) any_platform
static std::string getName()
static std::string getName()
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void define(CELL &cell, const RHO &rho) any_platform
void initialize(CELL &cell) any_platform
Density computation for fixed velocity boundary.
void initialize(CELL &cell) any_platform
static std::string getName()
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void define(CELL &cell, const RHO &rho) any_platform
void inverseShift(CELL &cell, RHO &rho) any_platform
void compute(CELL &cell, RHO &rho) any_platform
void initialize(CELL &cell) any_platform
void define(CELL &cell, const RHO &rho) any_platform
static std::string getName()
Momentum is zero at solid material.
void inverseShift(CELL &cell, U &u) any_platform
void computeU(CELL &cell, U &u) any_platform
void compute(CELL &cell, J &j) any_platform
void define(CELL &cell, const U &u) any_platform
void initialize(CELL &cell) any_platform
static std::string getName()
The stress is always zero.
static std::string getName()
void compute(CELL &cell, const RHO &rho, const U &u, PI &pi) any_platform
Compute number of elements of a symmetric d-dimensional tensor.
Set of functions commonly used in LB computations – header file.
efficient implementation of a vector class