24#ifndef SET_BOUZIDI_BOUNDARY_H
25#define SET_BOUZIDI_BOUNDARY_H
56 template <
typename CELL,
typename V =
typename CELL::value_t>
58 using DESCRIPTOR =
typename CELL::descriptor_t;
59 const auto q = x_b.template getFieldPointer<descriptors::BOUZIDI_DISTANCE>();
60 for (
int iPop = 1; iPop < descriptors::q<DESCRIPTOR>(); ++iPop) {
65 auto x_s = x_b.neighbor(c);
68 x_b[iPop_opposite] = (q[iPop] <= V{0.5})
69 * (V{2} * q[iPop] * x_s[iPop] + (V{1} - V{2} * q[iPop]) * x_b[iPop])
71 * (V{0.5} / q[iPop] * x_s[iPop] + V{0.5} * (V{2} * q[iPop] - V{1}) / q[iPop] * x_f[iPop_opposite]);
74 else if (q[iPop] == V{0}) {
76 x_b[iPop_opposite] = x_b[iPop];
90 template <
typename CELL,
typename V =
typename CELL::value_t>
92 using DESCRIPTOR =
typename CELL::descriptor_t;
93 const auto q = x_b.template getFieldPointer<descriptors::BOUZIDI_DISTANCE>();
94 const auto phi_d = x_b.template getFieldPointer<descriptors::BOUZIDI_ADE_DIRICHLET>();
99 for (
int iPop = 1; iPop < descriptors::q<DESCRIPTOR>(); ++iPop) {
101 if (q[iPop] > V{0}) {
104 auto x_s = x_b.neighbor(c);
106 auto source_d = phi_d[iPop] * f;
110 x_b[iPop_opposite] = (q[iPop] <= V{0.5})
111 * (V{-2} * q[iPop] * (x_s[iPop] + t_i) + (V{2} * q[iPop] - V{1}) * (x_b[iPop] + t_i) + source_d)
113 * (V{-1} / (V{2} * q[iPop]) * (x_s[iPop] + t_i) + (V{1} - V{1} / (V{2} * q[iPop])) * (x_f[iPop_opposite] + t_iopp) + (V{1} / (V{2} * q[iPop])) * source_d)
117 else if (q[iPop] == V{0}) {
119 auto source_d = phi_d[iPop] * f;
122 x_b[iPop_opposite] = -(x_b[iPop] + t_i) + source_d - t_iopp;
137 template <
typename CELL,
typename V =
typename CELL::value_t>
139 using DESCRIPTOR =
typename CELL::descriptor_t;
140 const auto q = x_b.template getFieldPointer<descriptors::BOUZIDI_DISTANCE>();
141 const auto veloCoeff = x_b.template getFieldPointer<descriptors::BOUZIDI_VELOCITY>();
142 for (
int iPop=1; iPop < descriptors::q<DESCRIPTOR>(); ++iPop) {
147 auto x_s = x_b.neighbor(c);
151 x_b[iPop_opposite] = (q[iPop] <= V{0.5})
152 * (V{2} * q[iPop] * x_s[iPop] + (V{1} - V{2} * q[iPop]) * x_b[iPop] - V{2} * veloTerm)
154 * (V{0.5} / q[iPop] * x_s[iPop] + V{0.5} * (V{2} * q[iPop] - V{1}) / q[iPop] * x_f[iPop_opposite] - V{1}/q[iPop] * veloTerm);
157 else if (q[iPop] == V{0}) {
160 x_b[iPop_opposite] = x_b[iPop] - V{2} * veloTerm;
175 template <
typename CELL,
typename V =
typename CELL::value_t>
177 using DESCRIPTOR =
typename CELL::descriptor_t;
178 const auto q = x_b.template getFieldPointer<descriptors::BOUZIDI_DISTANCE>();
179 for (
int iPop=1; iPop < descriptors::q<DESCRIPTOR>(); ++iPop) {
183 auto x_s = x_b.neighbor(c);
185 auto f_tmp = x_b[iPop] + q[iPop]*(x_s[iPop] - x_b[iPop]);
186 x_b[iPop_opposite] = f_tmp + q[iPop]/(V{1}+q[iPop]) * (x_f[iPop_opposite] - f_tmp);
193template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
202 for (
int iC=0; iC < load.size(); ++iC) {
204 (bulkIndicator->getBlockIndicatorF(iC)).getBlockGeometry(),
205 boundaryIndicator->getBlockIndicatorF(iC),
206 bulkIndicator->getBlockIndicatorF(iC),
207 indicatorAnalyticalBoundary);
214template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
217 int materialOfSolidObstacle,
219 std::vector<int> bulkMaterials = std::vector<int>(1,1))
225 indicatorAnalyticalBoundary);
230template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
236 bool verbose =
false)
241 const T deltaR = blockGeometry.
getDeltaR();
245 if (boundaryIndicator(solidLatticeR)) {
246 for (
int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
252 if (blockGeometry.
isInside(boundaryLatticeR)) {
253 auto boundaryPhysR = blockGeometry.
getPhysR(boundaryLatticeR);
256 if (bulkIndicator(boundaryLatticeR)) {
260 auto direction = -deltaR * c;
263 if (indicatorAnalyticalBoundary.distance(dist, boundaryPhysR.data(), direction, blockGeometry.
getIcGlob())) {
267 if ((qIpop < 0) || (qIpop > 1)) {
269 clout <<
"Error, non suitable dist. at lattice: (" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction " << iPop <<
". Fall-back to bounce-back." << std::endl;
279 clout <<
"Error, no boundary found at lattice:(" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction: " << iPop <<
".Fall-back to bounce-back." << std::endl;
291 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, qIpop);
295 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
298 if constexpr (std::is_same_v<OPERATOR, BouzidiVelocityPostProcessor>) {
299 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_VELOCITY>(iPop_opposite, 0);
302 if constexpr (std::is_same_v<OPERATOR, BouzidiAdeDirichletPostProcessor>) {
303 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_ADE_DIRICHLET>(iPop_opposite, 0);
306 if (!block.isPadding(boundaryLatticeR)) {
316 if (blockGeometry.
getMaterial(boundaryLatticeR) != 0) {
318 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
320 if constexpr (std::is_same_v<OPERATOR, BouzidiVelocityPostProcessor>) {
321 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_VELOCITY>(iPop_opposite, 0);
324 if constexpr (std::is_same_v<OPERATOR, BouzidiAdeDirichletPostProcessor>) {
325 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_ADE_DIRICHLET>(iPop_opposite, 0);
327 if (!block.isPadding(boundaryLatticeR)) {
341template<
typename T,
typename DESCRIPTOR>
345 std::vector<int> bulkMaterials = std::vector<int>(1,1))
351template<
typename T,
typename DESCRIPTOR>
355 std::vector<int> bulkMaterials = std::vector<int>(1,1))
358 boundaryIndicator->getSuperGeometry().getMaterialIndicator(std::move(bulkMaterials)),
363template<
typename T,
typename DESCRIPTOR>
370 auto& cuboidDecomposition = boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
371 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
372 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
374 boundaryIndicator->getBlockIndicatorF(iCloc),
375 bulkIndicator->getBlockIndicatorF(iCloc),
382template<
typename T,
typename DESCRIPTOR>
391 if (boundaryIndicator(solidLatticeR)) {
392 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
394 if (block.isInside(boundaryLatticeR)) {
396 auto x_b = block.get(boundaryLatticeR);
397 const auto opp_bouzidi_dist = x_b.template getFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite);
400 if (opp_bouzidi_dist >= 0) {
401 T wallVelocity[DESCRIPTOR::d] = { };
402 T physicalIntersection[DESCRIPTOR::d] = { };
403 auto boundaryPhysR = cuboid.
getPhysR(boundaryLatticeR);
406 for (
int i = 0; i< DESCRIPTOR::d; ++i) {
411 u(wallVelocity, physicalIntersection);
416 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_VELOCITY>(iPop_opposite, vel_coeff);
425template<
typename T,
typename DESCRIPTOR,
bool thermalCreep = false>
429 std::vector<int> bulkMaterials = std::vector<int>(1,1))
435template<
typename T,
typename DESCRIPTOR,
bool thermalCreep = false>
439 std::vector<int> bulkMaterials = std::vector<int>(1,1))
442 boundaryIndicator->getSuperGeometry().getMaterialIndicator(std::move(bulkMaterials)),
443 indicatorAnalyticalBoundary);
447template<
typename T,
typename DESCRIPTOR,
bool thermalCreep = false>
454 auto& cuboidDecomposition = boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
455 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
456 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
458 boundaryIndicator->getBlockIndicatorF(iCloc),
459 bulkIndicator->getBlockIndicatorF(iCloc),
461 indicatorAnalyticalBoundary);
467template<
typename T,
typename DESCRIPTOR,
bool thermalCreep = false>
476 if (boundaryIndicator(solidLatticeR)) {
477 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
479 if (block.isInside(boundaryLatticeR)) {
480 if ( bulkIndicator(boundaryLatticeR)) {
481 auto boundaryPhysR = cuboid.
getPhysR(boundaryLatticeR);
483 for (
int i = 0; i< DESCRIPTOR::d; ++i) {
484 block.get(boundaryLatticeR).template setFieldComponent<descriptors::NORMAL>(i,-normal[i]);
488 for(
int iD = 0; iD < DESCRIPTOR::d; iD++){
491 auto wallLatticeR = boundaryLatticeR + normalRound;
492 if(boundaryIndicator(wallLatticeR)) {
494 T temp = block.get(wallLatticeR).template getField<descriptors::TEMPERATURE>();
495 if constexpr(DESCRIPTOR::d==2) {
497 for(
int iPop=1; iPop < DESCR::q; iPop++) {
499 if (boundaryIndicator(solidNeighborR)) {
500 T tempNeighbor = block.get(solidNeighborR).template getField<descriptors::TEMPERATURE>();
501 for(
int iD = 0; iD<DESCRIPTOR::d; iD++) {
503 tempDerivative[iD] = tempNeighbor - temp;
506 tempDerivative[iD] = temp - tempNeighbor;
513 for(
int iPop=1; iPop < DESCR::q; iPop++) {
515 if (boundaryIndicator(solidNeighborR)) {
516 T tempNeighbor = block.get(solidNeighborR).template getField<descriptors::TEMPERATURE>();
517 for(
int iD = 0; iD<DESCRIPTOR::d; iD++) {
519 tempDerivative[iD] = tempNeighbor - temp;
522 tempDerivative[iD] = temp - tempNeighbor;
528 tempDerivative -= (tempDerivative*normal)*normal;
529 block.get(boundaryLatticeR).template setField<descriptors::TEMPGRADIENT>(tempDerivative);
539template<
typename T,
typename DESCRIPTOR>
543 std::vector<int> bulkMaterials = std::vector<int>(1,1))
548template<
typename T,
typename DESCRIPTOR>
552 std::vector<int> bulkMaterials = std::vector<int>(1,1))
557template<
typename T,
typename DESCRIPTOR>
564 auto& cuboidDecomposition = boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
565 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
566 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
568 boundaryIndicator->getBlockIndicatorF(iCloc),
569 bulkIndicator->getBlockIndicatorF(iCloc),
575template<
typename T,
typename DESCRIPTOR>
582 auto& cuboidDecomposition = boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
583 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
584 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
586 boundaryIndicator->getBlockIndicatorF(iCloc),
587 bulkIndicator->getBlockIndicatorF(iCloc),
593template<
typename T,
typename DESCRIPTOR>
597 std::vector<int> bulkMaterials = std::vector<int>(1,1))
600 boundaryIndicator->getSuperGeometry().getMaterialIndicator(std::move(bulkMaterials)),
604template<
typename T,
typename DESCRIPTOR>
608 std::vector<int> bulkMaterials = std::vector<int>(1,1))
611 boundaryIndicator->getSuperGeometry().getMaterialIndicator(std::move(bulkMaterials)),
615template<
typename T,
typename DESCRIPTOR>
623 if (boundaryIndicator(solidLatticeR)) {
624 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
626 if (block.isInside(boundaryLatticeR)) {
628 auto x_b = block.get(boundaryLatticeR);
629 const auto opp_bouzidi_dist = x_b.template getFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite);
632 if (opp_bouzidi_dist >= 0) {
634 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_ADE_DIRICHLET>(iPop_opposite, phi_d);
642template<
typename T,
typename DESCRIPTOR>
650 if (boundaryIndicator(solidLatticeR)) {
651 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
653 if (block.isInside(boundaryLatticeR)) {
655 auto x_b = block.get(boundaryLatticeR);
656 const auto opp_bouzidi_dist = x_b.template getFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite);
659 if (opp_bouzidi_dist >= 0) {
660 T phi_at_cell[1] { };
661 auto boundaryPhysR = cuboid.
getPhysR(boundaryLatticeR);
663 phi_d(phi_at_cell, boundaryPhysR.data());
666 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_ADE_DIRICHLET>(iPop_opposite, phi_at_cell[0]);
680template<
typename T,
typename DESCRIPTOR>
684 int gradientOrder = 1,
685 std::vector<int> bulkMaterials = std::vector<int>(1,1),
686 bool isOuterWall =
true,
bool useDiscreteNormal =
false)
690 indicatorAnalyticalBoundary, gradientOrder, bulkMaterials, isOuterWall,
695template<
typename T,
typename DESCRIPTOR>
699 int gradientOrder = 1,
700 std::vector<int> bulkMaterials = std::vector<int>(1,1),
701 bool isOuterWall =
true,
bool useDiscreteNormal =
false)
704 sLattice, std::forward<
decltype(boundaryIndicator)>(boundaryIndicator),
705 indicatorAnalyticalBoundary,
706 boundaryIndicator->getSuperGeometry().getMaterialIndicator(
707 std::move(bulkMaterials)),
708 gradientOrder, isOuterWall, useDiscreteNormal);
712template<
typename T,
typename DESCRIPTOR>
717 int gradientOrder = 1,
718 bool isOuterWall =
true,
719 bool useDiscreteNormal =
false)
722 auto& cuboidDecomposition =
723 boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
724 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
725 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
727 boundaryIndicator->getBlockIndicatorF(iCloc),
728 indicatorAnalyticalBoundary,
729 bulkIndicator->getBlockIndicatorF(iCloc),
730 cuboid, gradientOrder, isOuterWall, useDiscreteNormal);
734 sLattice, std::forward<
decltype(boundaryIndicator)>(boundaryIndicator),
739template<
typename T,
typename DESCRIPTOR>
745 int gradientOrder = 1,
746 bool isOuterWall =
true,
747 bool useDiscreteNormal =
false)
749 assert((gradientOrder==0) || (gradientOrder==1) || (gradientOrder==2));
751 block.template setParameter<descriptors::FD_DEG>(gradientOrder);
752 auto& blockGeometryStructure = bulkIndicator.getBlockGeometry();
756 if (boundaryIndicator(solidLatticeR)) {
758 blockGeometryStructure.getStatistics().computeNormal(
759 solidLatticeR[0], solidLatticeR[1], solidLatticeR[2]);
760 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
763 if (block.isInside(boundaryLatticeR)) {
765 auto x_b = block.get(boundaryLatticeR);
767 const auto opp_bouzidi_dist = x_b.template getFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite);
770 if (opp_bouzidi_dist >= 0 && (bulkIndicator(boundaryLatticeR))){
771 auto boundaryPhysR = cuboid.
getPhysR(boundaryLatticeR);
773 indicatorAnalyticalBoundary, 0.5 * deltaR);
774 if (!useDiscreteNormal) {
776 indicatorAnalyticalBoundaryLayer.
surfaceNormal(boundaryPhysR.data(),
779 normal = -1 * normal;
781 Vector<T, 3> ceilNormal(ceil(normal[0]), ceil(normal[1]),
783 Vector<T, 3> floorNormal(floor(normal[0]), floor(normal[1]),
785 if (bulkIndicator(ceilNormal + boundaryLatticeR) ||
786 bulkIndicator(floorNormal + boundaryLatticeR)) {
787 block.get(boundaryLatticeR)
788 .template setField<descriptors::NORMAL>(
789 {normal[0], normal[1], normal[2]});
793 block.get(boundaryLatticeR)
794 .template setField<descriptors::NORMAL>({(T) discreteNormal[0],
795 (T) discreteNormal[1],
796 (T) discreteNormal[2]});
799 block.get(boundaryLatticeR)
800 .template setFieldComponent<descriptors::BOUZIDI_VELOCITY>(
801 iPop_opposite, T(0));
810template<
typename T,
typename DESCRIPTOR>
814 std::vector<int> bulkMaterials = std::vector<int>(1,1))
821template<
typename T,
typename DESCRIPTOR>
828 auto& cuboidDecomposition =
829 boundaryIndicator->getSuperGeometry().getCuboidDecomposition();
830 for (
int iCloc = 0; iCloc < load.size(); ++iCloc) {
831 auto& cuboid = cuboidDecomposition.get(load.glob(iCloc));
833 boundaryIndicator->getBlockIndicatorF(iCloc),
834 bulkIndicator->getBlockIndicatorF(iCloc),
841template<
typename T,
typename DESCRIPTOR>
845 std::vector<int> bulkMaterials = std::vector<int>(1,1))
848 sLattice, std::forward<
decltype(boundaryIndicator)>(boundaryIndicator),
849 boundaryIndicator->getSuperGeometry().getMaterialIndicator(
850 std::move(bulkMaterials)),
855template<
typename T,
typename DESCRIPTOR>
862 auto& blockGeometryStructure = bulkIndicator.getBlockGeometry();
863 std::vector<int> discreteNormalOutwards(4, 0);
865 if (boundaryIndicator(solidLatticeR)) {
867 for (
int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
870 if (block.isInside(boundaryLatticeR)) {
872 auto x_b = block.get(boundaryLatticeR);
873 const auto opp_bouzidi_dist =
874 x_b.template getFieldComponent<descriptors::BOUZIDI_DISTANCE>(
878 if ((opp_bouzidi_dist >= 0) && (bulkIndicator(boundaryLatticeR))) {
880 auto boundaryPhysR = cuboid.
getPhysR(boundaryLatticeR);
882 phi_d(phi_at_cell, boundaryPhysR.data());
883 discreteNormalOutwards =
884 blockGeometryStructure.getStatistics().getType(
885 solidLatticeR[0], solidLatticeR[1], solidLatticeR[2]);
887 block.get(boundaryLatticeR)
888 .template setFieldComponent<descriptors::BOUZIDI_WALL_TEMP>(
889 iPop_opposite, phi_at_cell[0]);
890 block.get(boundaryLatticeR)
891 .template setField<descriptors::NORMAL>(
892 {-discreteNormalOutwards[1], -discreteNormalOutwards[2],
893 -discreteNormalOutwards[3]});
902template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
911 for (
int iC=0; iC < load.size(); ++iC) {
913 (bulkIndicator->getBlockIndicatorF(iC)).getBlockGeometry(),
914 boundaryIndicator->getBlockIndicatorF(iC),
915 bulkIndicator->getBlockIndicatorF(iC),
916 indicatorAnalyticalBoundary);
920 communicator.template requestField<descriptors::STATISTIC>();
921 communicator.template requestField<descriptors::BOUNDARY>();
924 communicator.requestOverlap(_overlap, neighborIndicator);
925 communicator.exchangeRequests();
932template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
935 int materialOfSolidObstacle,
937 std::vector<int> bulkMaterials = std::vector<int>(1,1))
943 indicatorAnalyticalBoundary);
948template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
954 bool verbose =
false)
959 const T deltaR = blockGeometry.
getDeltaR();
965 && boundaryIndicator(solidLatticeR)) {
966 std::vector<int> discreteNormal(DESCRIPTOR::d+1, 0);
967 discreteNormal = boundaryIndicator.getBlockGeometry().getStatistics().getType(solidLatticeR[0],solidLatticeR[1]);
969 for (
int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
974 if (blockGeometry.
isInside(boundaryLatticeR)) {
975 auto boundaryPhysR = blockGeometry.
getPhysR(boundaryLatticeR);
977 if (bulkIndicator(boundaryLatticeR.
data())) {
981 auto direction = -deltaR * c;
984 if (indicatorAnalyticalBoundary.distance(dist, boundaryPhysR, direction, blockGeometry.
getIcGlob())) {
988 if ((qIpop < 0) || (qIpop > 1)) {
990 clout <<
"Error, non suitable dist. at lattice: (" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction " << iPop <<
". Fall-back to bounce-back." << std::endl;
1000 clout <<
"Error, no boundary found at lattice:(" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction: " << iPop <<
".Fall-back to bounce-back." << std::endl;
1012 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, qIpop);
1016 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
1019 if (!block.isPadding(boundaryLatticeR)) {
1029 if (blockGeometry.
getMaterial(boundaryLatticeR) != 0) {
1031 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
1032 if (!block.isPadding(boundaryLatticeR)) {
1041 T discreteNormalSum=0;
1042 for (
int iD=0; iD<DESCRIPTOR::d; iD++) {
1043 discreteNormalSum +=
abs(discreteNormal[iD+1]);
1045 if (discreteNormalSum == 0) {
1046 block.addPostProcessor(
1049 block.addPostProcessor(
1059template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
1068 for (
int iC=0; iC < load.size(); ++iC) {
1070 (bulkIndicator->getBlockIndicatorF(iC)).getBlockGeometry(),
1071 boundaryIndicator->getBlockIndicatorF(iC),
1072 bulkIndicator->getBlockIndicatorF(iC),
1073 indicatorAnalyticalBoundary);
1077 communicator.template requestField<descriptors::STATISTIC>();
1078 communicator.template requestField<descriptors::BOUNDARY>();
1081 communicator.requestOverlap(_overlap, neighborIndicator);
1082 communicator.exchangeRequests();
1089template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
1092 int materialOfSolidObstacle,
1094 std::vector<int> bulkMaterials = std::vector<int>(1,1))
1100 indicatorAnalyticalBoundary);
1105template<
typename T,
typename DESCRIPTOR,
typename OPERATOR = Bouz
idiPostProcessor>
1111 bool verbose =
false)
1116 const T deltaR = blockGeometry.
getDeltaR();
1121 && boundaryIndicator(solidLatticeR)) {
1122 std::vector<int> discreteNormal(DESCRIPTOR::d+1, 0);
1123 if constexpr ( DESCRIPTOR::d==2 ) {
1124 discreteNormal = boundaryIndicator.getBlockGeometry().getStatistics().getType(solidLatticeR[0],solidLatticeR[1]);
1125 block.addPostProcessor(
1129 else if constexpr ( DESCRIPTOR::d==3 ) {
1130 discreteNormal = boundaryIndicator.getBlockGeometry().getStatistics().getType(solidLatticeR[0],solidLatticeR[1],solidLatticeR[2]);
1131 block.addPostProcessor(
1136 for (
int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
1141 if (blockGeometry.
isInside(boundaryLatticeR)) {
1142 auto boundaryPhysR = blockGeometry.
getPhysR(boundaryLatticeR);
1144 if (bulkIndicator(boundaryLatticeR.
data())) {
1148 auto direction = -deltaR * c;
1151 if (indicatorAnalyticalBoundary.distance(dist, boundaryPhysR, direction, blockGeometry.
getIcGlob())) {
1152 qIpop = dist /
norm;
1155 if ((qIpop < 0) || (qIpop > 1)) {
1157 clout <<
"Error, non suitable dist. at lattice: (" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction " << iPop <<
". Fall-back to bounce-back." << std::endl;
1167 clout <<
"Error, no boundary found at lattice:(" << boundaryLatticeR <<
"), physical: (" << blockGeometry.
getPhysR(boundaryLatticeR) <<
"), direction: " << iPop <<
".Fall-back to bounce-back." << std::endl;
1179 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, qIpop);
1183 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
1186 if (!block.isPadding(boundaryLatticeR)) {
1196 if (blockGeometry.
getMaterial(boundaryLatticeR) != 0) {
1198 block.get(boundaryLatticeR).template setFieldComponent<descriptors::BOUZIDI_DISTANCE>(iPop_opposite, T{0.5});
1199 if (!block.isPadding(boundaryLatticeR)) {
AnalyticalF are applications from DD to XD, where X is set by the constructor.
Representation of a block geometry.
Vector< T, D > getPhysR(LatticeR< D > latticeR) const
int getMaterial(LatticeR< D > latticeR) const
returns the (iX,iY) entry in the 2D scalar field
int getIcGlob() const
Read only access to the global iC number which is given !=-1 if the block geometries are part of a su...
T getDeltaR() const
Read only access to the voxel size given in SI units (meter)
CellDistance getNeighborhoodRadius(LatticeR< D > latticeR) const
Return maximum valid neighborhood sphere radius w.r.t. latticeR.
bool isInside(LatticeR< D > latticeR) const
Return whether location is valid.
static constexpr OperatorScope scope
void apply(CELL &x_b) any_platform
Post processor for the zero-velocity Bouzidi boundary.
static constexpr OperatorScope scope
void apply(CELL &x_b) any_platform
Post processor for the velocity Bouzidi boundary.
static constexpr OperatorScope scope
void apply(CELL &x_b) any_platform
T getDeltaR() const
Returns spacing of cuboid nodes.
Vector< T, D > getPhysR(LatticeR< D > latticeR) const
Smart pointer for managing the various ways of passing functors around.
virtual Vector< S, 3 > surfaceNormal(const Vector< S, 3 > &pos, const S meshSize)
Return surface normal Uses the fastest, but potentially less accurate method.
indicator function for a layer
class for marking output with some text
void setMultiOutput(bool b)
enable message output for all MPI processes, disabled by default
Representation of a statistic for a parallel 2D geometry.
std::unique_ptr< SuperIndicatorF< T, D > > getMaterialIndicator(std::vector< int > &&materials)
Returns a material indicator using the given vector of materials.
Super class maintaining block lattices for a cuboid decomposition.
SuperCommunicator< T, SuperLattice > & getCommunicator(STAGE stage=STAGE())
Return communicator for given communication stage.
BlockLattice< T, DESCRIPTOR > & getBlock(int locC)
Return BlockLattice with local index locC.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
constexpr const T * data() const any_platform
void apply(CELL &x_b) any_platform
static constexpr OperatorScope scope
PostProcessorPromise< T, DESCRIPTOR > promisePostProcessorForNormal(Vector< int, 2 > n)
constexpr int q() any_platform
constexpr T invCs2() any_platform
constexpr T t(unsigned iPop, tag::CUM) any_platform
constexpr int c(unsigned iPop, unsigned iDim) any_platform
constexpr int opposite(unsigned iPop) any_platform
ADf< T, DIM > round(const ADf< T, DIM > &a)
T norm(const std::vector< T > &a)
l2 norm of a vector of arbitrary length
Top level namespace for all of OpenLB.
void setBouzidiVelocity(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, DESCRIPTOR::d > &superGeometry, int material, AnalyticalF< DESCRIPTOR::d, T, T > &u, std::vector< int > bulkMaterials=std::vector< int >(1, 1))
Set Bouzidi velocity boundary on material cells of sLattice.
void setBouzidiTemperatureJump(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, DESCRIPTOR::d > &superGeometry, int material, AnalyticalF< DESCRIPTOR::d, T, T > &phi_d, std::vector< int > bulkMaterials=std::vector< int >(1, 1))
std::conditional_t< D==2, SuperIndicatorBoundaryNeighbor2D< T >, SuperIndicatorBoundaryNeighbor3D< T > > SuperIndicatorBoundaryNeighbor
void addPoints2CommBC(SuperLattice< T, DESCRIPTOR > &sLattice, FunctorPtr< SuperIndicatorF2D< T > > &&indicator, int _overlap)
Adds needed Cells to the Communicator _commBC in SuperLattice.
void setBouzidiBoundary(SuperLattice< T, DESCRIPTOR > &sLattice, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&boundaryIndicator, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&bulkIndicator, IndicatorF< T, DESCRIPTOR::d > &indicatorAnalyticalBoundary)
Set Bouzidi boundary on indicated cells of sLattice.
void setBouzidiPhaseField(SuperLattice< T, DESCRIPTOR > &sLattice, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&boundaryIndicator, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&bulkIndicator, IndicatorF< T, DESCRIPTOR::d > &indicatorAnalyticalBoundary)
Set Bouzidi boundary with contact angle for phase field models on indicated cells of sLattice.
std::conditional_t< D==2, BlockIndicatorF2D< T >, BlockIndicatorF3D< T > > BlockIndicatorF
std::conditional_t< D==2, IndicatorF2D< T >, IndicatorF3D< T > > IndicatorF
std::enable_if_t< std::is_arithmetic< T >::type::value, T > abs(T x) any_platform
void setBouzidiWellBalanced(SuperLattice< T, DESCRIPTOR > &sLattice, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&boundaryIndicator, FunctorPtr< SuperIndicatorF< T, DESCRIPTOR::d > > &&bulkIndicator, IndicatorF< T, DESCRIPTOR::d > &indicatorAnalyticalBoundary)
Set Bouzidi boundary with contact angle for phase field models on indicated cells of sLattice.
OperatorScope
Block-wide operator application scopes.
@ PerCell
Per-cell application, i.e. OPERATOR::apply is passed a CELL concept implementation.
constexpr T norm(const ScalarVector< T, D, IMPL > &a) any_platform
Euclidean vector norm.
std::conditional_t< D==2, SuperIndicatorF2D< T >, SuperIndicatorF3D< T > > SuperIndicatorF
void setBouzidiAdeDirichlet(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, DESCRIPTOR::d > &superGeometry, int material, T phi_d, std::vector< int > bulkMaterials=std::vector< int >(1, 1))
void setBouzidiKnudsenSlipVelocity(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, DESCRIPTOR::d > &superGeometry, int material, IndicatorF< T, DESCRIPTOR::d > &indicatorAnalyticalBoundary, std::vector< int > bulkMaterials=std::vector< int >(1, 1))
Set Bouzidi velocity boundary on material cells of sLattice.
void setBouzidiSlipVelocity(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, DESCRIPTOR::d > &superGeometry, int material, IndicatorF< T, DESCRIPTOR::d > &indicatorAnalyticalBoundary, int gradientOrder=1, std::vector< int > bulkMaterials=std::vector< int >(1, 1), bool isOuterWall=true, bool useDiscreteNormal=false)
Bouzidi General/Knudsen Slip Velocity 3D Sets slip velocity on general walls.
Communication after propagation.
Communication prior to coupling.