13#include <unordered_set>
29template <MInt nDim, MInt nDist,
class SysEqn>
33 NEW_TIMER_GROUP(tgrp_BC3D,
"Boundary Condition 3D");
34 NEW_TIMER(t_BC3DAll,
"complete BC setup", tgrp_BC3D);
35 RECORD_TIMER_START(t_BC3DAll);
38 m_log <<
"#########################################################################################################"
41 m_log <<
"## " << nDim
42 <<
"D Boundary Conditions "
45 m_log <<
"#########################################################################################################"
50 NEW_SUB_TIMER(t_initMembers,
"init members", t_BC3DAll);
51 RECORD_TIMER_START(t_initMembers);
56 m_rho1 = m_solver->m_rho1;
57 m_rho2 = m_solver->m_rho2;
70 m_lbControlInflow = 0;
71 m_lbControlInflow = Context::getSolverProperty<MInt>(
"lbControlInflow", m_solverId, AT_, &m_lbControlInflow);
84 m_zeroInflowVelocity = 1.0;
85 m_zeroInflowVelocity =
86 Context::getSolverProperty<MFloat>(
"zeroInflowVelocity", m_solverId, AT_, &m_zeroInflowVelocity);
88 RECORD_TIMER_STOP(t_initMembers);
90 if(m_solver->isActive()) {
91 NEW_SUB_TIMER(t_calcWDist,
"calculate wall distances", t_BC3DAll);
92 g_tc_geometry.push_back(std::pair<MString, MInt>(
"calculate wall distances", t_calcWDist));
93 RECORD_TIMER_START(t_calcWDist);
94 if(m_calcSublayerDist) {
95 mAlloc(m_distIntersectionElementId, m_solver->a_noCells(), nDist,
"distIntersectionElementId", -1, AT_);
97 calculateWallDistances();
98 RECORD_TIMER_STOP(t_calcWDist);
100 NEW_SUB_TIMER(t_parInflow,
"apply parabolic inflow", t_BC3DAll);
101 g_tc_geometry.push_back(std::pair<MString, MInt>(
"apply parabolic inflow", t_parInflow));
102 RECORD_TIMER_START(t_parInflow);
104 if(m_lbControlInflow) {
105 switch(m_lbControlInflow) {
113 m_log <<
"LbBndCndDxQy::() unknown index for parabolic inflow " << std::endl;
114 std::stringstream errorMessage;
115 errorMessage <<
"LbBndCndDxQy::() unknown index for parabolic inflow";
116 DEBUG(
"lbbndcnddxqy::parabolicInflow() unknown index for parabolic inflow" << std::endl,
117 MAIA_DEBUG_ASSERTION);
118 TERMM(1, errorMessage.str());
121 RECORD_TIMER_STOP(t_parInflow);
124 m_maxDeltaRho = 1.0 - m_rho1;
142 const MString bounceBackSchemeMb_default =
"BOUZIDI_QUADRATIC";
144 Context::getSolverProperty<MString>(
"bounceBackSchemeMb", m_solverId, AT_, &bounceBackSchemeMb_default));
146 switch(bounceBackSchemeMb) {
149 m_bounceBackFunctionMbCase = 0;
156 m_bounceBackFunctionMbCase = 1;
163 m_bounceBackFunctionMbCase = 2;
169 TERMM(1,
"Bounceback Scheme Mb not set!");
184 m_refillMethodOrder = 2;
185 m_refillMethodOrder = Context::getSolverProperty<MInt>(
"refillMethodOrder", m_solverId, AT_, &m_refillMethodOrder);
187 RECORD_TIMER_STOP(t_BC3DAll);
189 if(m_solver->m_geometry->m_debugParGeom) {
190 DISPLAY_ALL_GROUP_TIMERS(tgrp_BC3D);
194 m_log << std::endl << std::endl;
200template <MInt nDim, MInt nDist,
class SysEqn>
202 if(m_calcSublayerDist)
mDeallocate(m_distIntersectionElementId);
203 if(m_oldWallTemp !=
nullptr)
mDeallocate(m_oldWallTemp);
204 if(m_mucousDist !=
nullptr)
mDeallocate(m_mucousDist);
205 if(m_fluidDist !=
nullptr)
mDeallocate(m_fluidDist);
212template <MInt nDim, MInt nDist,
class SysEqn>
228template <MInt nDim, MInt nDist,
class SysEqn>
233 std::stringstream fname;
234 fname <<
"rim_s" << segmentId <<
"_" << m_solver->domainId() <<
".vtp";
235 ofl.open(fname.str().c_str());
238 ofl <<
"<?xml version=\"1.0\"?>" << std::endl;
239 ofl <<
"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
240 ofl <<
"<PolyData>" << std::endl;
241 ofl <<
"<Piece NumberOfPoints=\"" << num <<
"\" NumberOfVerts=\"" << num <<
"\" NumberOfLines=\"" << 1 <<
"\">"
244 ofl <<
"<PointData TCoords=\"Texture Coordinates\">" << std::endl;
245 ofl <<
"<DataArray type=\"Float32\" Name=\"Array_Position\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;
246 for(
MInt i = 0; i < num; i++)
249 ofl <<
"</DataArray>" << std::endl;
250 ofl <<
"</PointData>" << std::endl;
253 ofl <<
"<Points>" << std::endl;
254 ofl <<
"<DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
255 for(
MInt i = 0; i < num; i++) {
256 for(
MInt d = 0; d < nDim; d++) {
257 ofl << vertices[i][d] <<
" ";
261 ofl <<
"</DataArray>" << std::endl;
262 ofl <<
"</Points>" << std::endl;
282 ofl <<
"<Lines>" << std::endl;
283 ofl <<
"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\">" << std::endl;
284 for(
MInt i = 0; i < num; i++)
286 ofl <<
"0" << std::endl;
287 ofl <<
"</DataArray>" << std::endl;
288 ofl <<
"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">" << std::endl;
291 ofl << num + 1 << std::endl;
292 ofl <<
"</DataArray>" << std::endl;
293 ofl <<
"</Lines>" << std::endl;
296 ofl <<
"</Piece>" << std::endl;
297 ofl <<
"</PolyData>" << std::endl;
298 ofl <<
"</VTKFile>" << std::endl;
310template <MInt nDim, MInt nDist,
class SysEqn>
314 m_log <<
" + Calculating wall distances..." << std::endl;
315 m_log <<
" - method: " << m_interpolationDistMethod << std::endl;
316 m_log <<
" - grid cut method: " << m_gridCutTest << std::endl;
319 for(
auto& i : m_bndCells) {
323 if(m_interpolationDistMethod ==
"sphere" || m_interpolationDistMethod ==
"circle") {
324 const MInt nDim_ = (m_interpolationDistMethod ==
"sphere") ? 3 : 2;
325 for(
MInt i = 0; i < (
MInt)m_bndCells.size(); i++) {
326 const MInt currentId = m_bndCells[i].m_cellId;
328 const MFloat cellHalfLength = m_solver->c_cellLengthAtLevel(m_solver->a_level(currentId) + 1);
329 const MFloat cellRadiusSq =
330 std::inner_product(&m_solver->a_coordinate(currentId, 0), &m_solver->a_coordinate(currentId, nDim_),
331 &m_solver->a_coordinate(currentId, 0), .0);
335 const MFloat radiusSq = 0.25;
336 m_bndCells[i].m_isFluid = (cellRadiusSq > radiusSq);
340 m_bndCells[i].m_distances.clear();
341 m_bndCells[i].m_distances.resize(IPOW3[nDim] - 1, 0.0);
343 const MFloat dxSq = Ld::distType(
dist) * 4.0 * cellHalfLength * cellHalfLength;
346 m_bndCells[i].m_distances[
dist] = std::numeric_limits<MFloat>::max();
353 for(
MInt j = 0; j < nDim_; j++) {
355 m_solver->a_coordinate(currentId, j) * ((
MFloat)Ld::idFld(
dist, j) - 1.0) * 2.0 * cellHalfLength / dxSq;
358 const MFloat tmpQValue = sqrt(qValue * qValue + (radiusSq - cellRadiusSq) / dxSq);
360 if(qValue + tmpQValue >= 0.0 && fabs(qValue + tmpQValue) <= 0.5) {
362 m_bndCells[i].m_distances[
dist] = qValue;
364 if(qValue - tmpQValue >= 0.0 && fabs(qValue - tmpQValue) <= 0.5) {
366 m_bndCells[i].m_distances[
dist] = qValue;
372 else if(m_interpolationDistMethod ==
"perpOp" || m_interpolationDistMethod ==
"cylinder") {
378 std::vector<MInt> wallIds;
379 for(
MInt i = 0; i < (
MInt)(m_bndCndSegIds.size()); i++) {
380 MBool is_periodic =
false;
381 if(m_noPeriodicSegments != 0)
382 for(
MInt j = 0; j < m_noPeriodicSegments; j++)
383 if(m_bndCndSegIds[i] == m_periodicSegmentsIds[j]) {
388 MBool is_inout =
false;
389 for(
MInt j = 0; j < m_noInOutSegments; j++)
390 if(m_bndCndSegIds[i] == m_inOutSegmentsIds[j]) {
395 if(!is_periodic & !is_inout) wallIds.push_back(i);
398 if(wallIds.size() > 0) {
399 std::unordered_set<MInt> reconsider;
401 for(
auto wallId : wallIds) {
402 m_log <<
" - BC " << m_bndCndIds[wallId] << std::endl;
403 m_log <<
" * number or cells: " << (m_bndCndOffsets[wallId + 1] - m_bndCndOffsets[wallId]) << std::endl;
404 m_log <<
" * segment id: " << m_bndCndSegIds[wallId] << std::endl;
406 for(
MInt i = m_bndCndOffsets[wallId]; i < m_bndCndOffsets[wallId + 1]; i++) {
407 const MInt currentId = m_bndCells[i].m_cellId;
410 const MFloat cellHalfLength = m_solver->c_cellLengthAtLevel(m_solver->a_level(currentId) + 1);
414 for(
MInt j = 0; j < nDim; j++) {
415 target[j] = m_solver->a_coordinate(currentId, j) - cellHalfLength;
416 target[j + nDim] = m_solver->a_coordinate(currentId, j) + cellHalfLength;
419 d[j] = m_solver->a_coordinate(currentId, j);
423 std::vector<MInt> nodeList;
424 m_solver->m_geometry->getIntersectionElements(target, nodeList, cellHalfLength,
425 &m_solver->a_coordinate(currentId, 0));
428 m_bndCells[i].m_distances.clear();
429 m_bndCells[i].m_distances.resize(IPOW3[nDim] - 1, 0.0);
433 const MFloat dx = F2 * SQRT[Ld::distType(
dist)] * cellHalfLength;
436 m_bndCells[i].m_distances[
dist] = std::numeric_limits<MFloat>::max();
439 for(
MInt j = 0; j < nDim; j++)
440 e[j] = d[j] + ((
MFloat)Ld::idFld(
dist, j) - 1.0) * cellHalfLength;
442 MFloat targetsmall[2 * nDim];
443 for(
MInt k = 0; k < nDim; k++) {
444 targetsmall[k] = d[k];
445 targetsmall[k + nDim] = e[k];
449 MBool has_cut = m_solver->m_geometry->getClosestLineIntersectionLength(m_bndCndIds[wallId], nodeList,
450 targetsmall, &min_dist);
452 m_bndCells[i].m_distances[
dist] =
455 m_bndCells[i].m_distances[
dist] = 1.0;
462 m_bndCells[i].m_isFluid =
false;
463 MBool hasBndryCutNghbr =
false;
464 MBool hasNoCutNghbr =
false;
465 MBool hasFluidCutNghbr =
false;
467 if(m_bndCells[i].m_distances[
dist] < 1.0) {
468 if(m_solver->a_hasNeighbor(currentId,
dist)) {
469 const MInt nghId = m_solver->c_neighborId(currentId,
dist);
470 if(m_solver->a_isBndryCell(nghId)) {
471 hasBndryCutNghbr =
true;
475 hasFluidCutNghbr =
true;
482 hasNoCutNghbr =
true;
487 m_bndCells[i].m_isFluid =
false;
488 else if(hasBndryCutNghbr)
489 reconsider.insert(i);
490 else if(hasNoCutNghbr)
491 m_bndCells[i].m_isFluid =
true;
502 MUint reconsiderSize = 0;
503 while(reconsiderSize != reconsider.size()) {
504 reconsiderSize = reconsider.size();
505 m_log <<
" - number of cells to reconsider: " << reconsiderSize << std::endl;
506 auto r = reconsider.begin();
507 while(r != reconsider.end()) {
508 const MInt cellId = m_bndCells[*r].m_cellId;
511 if(m_bndCells[*r].m_distances[
dist] < 1.0 && m_solver->a_hasNeighbor(cellId,
dist)) {
512 const MInt nghId = m_solver->c_neighborId(cellId,
dist);
513 if(m_solver->a_isBndryCell(nghId)) {
514 const MInt bndIdNeigh = m_solver->a_bndId(nghId);
515 if(reconsider.find(bndIdNeigh) == reconsider.end()) {
517 if(
approx(m_bndCells[bndIdNeigh].m_distances[Ld::oppositeDist(
dist)], 1.0, MFloatEps)) {
518 m_bndCells[*r].m_isFluid = !m_bndCells[bndIdNeigh].m_isFluid;
527 reconsider.erase(r++);
535 if(m_interpolationDistMethod ==
"cylinder") {
537 const MInt cylinderBcId = Context::getSolverProperty<MInt>(
"cylinderBcId", m_solverId, AT_);
538 MInt cylinderId = -1;
539 for(
MInt i = 0; i < (
MInt)(m_bndCndIds.size()); i++) {
540 if(m_bndCndIds[i] == cylinderBcId) {
545 if(cylinderId != -1) {
546 const MFloat radius = 0.5;
547 const MFloat radiusSqr = radius * radius;
549 for(
MInt i = m_bndCndOffsets[cylinderId]; i < m_bndCndOffsets[cylinderId + 1]; i++) {
550 const MInt currentId = m_bndCells[i].m_cellId;
552 const MFloat cellHalfLength = m_solver->c_cellLengthAtLevel(m_solver->a_level(currentId) + 1);
554 const MFloat cellRadiusSq = m_solver->a_coordinate(currentId, 0) * m_solver->a_coordinate(currentId, 0)
555 + m_solver->a_coordinate(currentId, 1) * m_solver->a_coordinate(currentId, 1);
558 m_bndCells[i].m_isFluid = cellRadiusSq > radiusSqr;
562 m_bndCells[i].m_distances.clear();
563 m_bndCells[i].m_distances.resize(IPOW3[nDim] - 1, 0.0);
567 dx = F2 * cellHalfLength;
569 dx = SQRT2 * F2 * cellHalfLength;
571 dx = SQRT3 * F2 * cellHalfLength;
572 const MFloat dxSqr = dx * dx;
575 m_bndCells[i].m_distances[
dist] = std::numeric_limits<MFloat>::max();
582 const MInt nDim_cyl = 2;
583 for(
MInt j = 0; j < nDim_cyl; j++) {
584 qValue -= m_solver->a_coordinate(currentId, j) * ((
MFloat)Ld::idFld(
dist, j) - 1.0) * 2.0 * cellHalfLength
588 const MFloat tmpQValue = sqrt(qValue * qValue - (cellRadiusSq - radiusSqr) / dxSqr);
590 if(qValue + tmpQValue >= 0.0 && fabs(qValue + tmpQValue) <= 0.5) {
591 m_bndCells[i].m_distances[
dist] = qValue + tmpQValue;
592 }
else if(qValue - tmpQValue >= 0.0 && fabs(qValue - tmpQValue) <= 0.5) {
593 m_bndCells[i].m_distances[
dist] = qValue - tmpQValue;
602 else if(m_interpolationDistMethod ==
"pipe") {
605 else if(m_interpolationDistMethod ==
"STD") {
607 constexpr MFloat relEps = 1e-16;
608 const MFloat eps = relEps * m_solver->c_cellLengthAtLevel(m_solver->maxLevel());
609 auto getInsideOutsideAndDistances = [&](
const MInt i,
const MInt index) {
610 auto& bndCell = m_bndCells[i];
611 const MInt currentId = bndCell.m_cellId;
613 bndCell.m_isFluid = !(m_solver->m_geometry->pointIsInside2(&m_solver->a_coordinate(currentId, 0)));
616 const MFloat cellLength = m_solver->c_cellLengthAtLevel(m_solver->a_level(currentId));
625 const MFloat bbHalfLenght = cellLength;
628 for(
MInt j = 0; j < nDim; j++) {
629 target[j] = m_solver->a_coordinate(currentId, j) - bbHalfLenght;
630 target[j + nDim] = m_solver->a_coordinate(currentId, j) + bbHalfLenght;
631 d[j] = m_solver->a_coordinate(currentId, j);
633 std::vector<MInt> nodeList;
634 if(m_gridCutTest ==
"SAT")
635 m_solver->m_geometry->getIntersectionElements(target, nodeList, bbHalfLenght,
636 &m_solver->a_coordinate(currentId, 0));
638 m_solver->m_geometry->getIntersectionElements(target, nodeList);
640 bndCell.m_distances.clear();
641 bndCell.m_distances.resize(IPOW3[nDim] - 1, 0.0);
646 for(
MInt j = 0; j < nDim; j++) {
647 e[j] = d[j] + ((
MFloat)Ld::idFld(
dist, j) - 1.0) * bbHalfLenght;
650 (bndCell.m_isFluid) ? std::numeric_limits<MFloat>::max() : std::numeric_limits<MFloat>::lowest();
652 for(
MInt n = 0; n < (signed)nodeList.size(); n++) {
654 MFloat**
const v = m_solver->m_geometry->elements[nodeList[n]].m_vertices;
658 m_solver->m_geometry->getLineTriangleIntersectionSimpleDistance(d, e, v[0], v[1], v[2], &distance);
660 distance = (distance < 0.0) ? 0.0 : distance;
664 if(fabs(distance - trgDistance) < eps) {
665 if(m_solver->m_geometry->elements[nodeList[n]].m_bndCndId == m_bndCndIds[index]) {
666 trgDistance = distance;
669 }
else if((bndCell.m_isFluid && distance < trgDistance) ||
670 (!bndCell.m_isFluid && distance > trgDistance)
672 trgDistance = distance;
677 if(trgNodeId > -1 && m_solver->m_geometry->elements[nodeList[trgNodeId]].m_bndCndId == m_bndCndIds[index]) {
678 const MFloat dx = SQRT[Ld::distType(
dist)] * cellLength;
679 bndCell.m_distances[
dist] = trgDistance / dx;
680 if(m_calcSublayerDist) {
681 m_distIntersectionElementId[currentId][
dist] = nodeList[trgNodeId];
684 bndCell.m_distances[
dist] = std::numeric_limits<MFloat>::max();
717 for(
MInt index = 0; index < (
MInt)m_bndCndSegIds.size(); index++) {
718 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[index + 1]; i++) {
719 getInsideOutsideAndDistances(i, index);
723 const MInt oldNumberOfBndCells = m_bndCells.size();
724 MBool needResorting =
false;
725 for(
MInt i = 0; i < oldNumberOfBndCells; i++) {
726 if(m_bndCells[i].m_isFluid) {
727 const MInt currentId = m_bndCells[i].m_cellId;
728 for(
MInt j = 0; j < nDist - 1; j++) {
729 if(m_bndCells[i].m_distances[j] > 0.5)
continue;
730 if(!m_solver->a_hasNeighbor(currentId, j))
continue;
731 const MInt nghbrId = m_solver->c_neighborId(currentId, j);
733 if(m_solver->a_isBndryCell(nghbrId) || !m_solver->a_isActive(nghbrId) || m_solver->a_isHalo(nghbrId))
736 needResorting =
true;
737 m_bndCells.emplace_back();
738 auto& newBndCell = m_bndCells.back();
739 newBndCell.m_cellId = nghbrId;
740 newBndCell.m_isFluid =
true;
741 newBndCell.m_segmentId.push_back(m_bndCells[i].m_segmentId[0]);
742 newBndCell.m_bndCndId.push_back(m_bndCells[i].m_bndCndId[0]);
743 m_solver->a_isBndryCell(nghbrId) =
true;
746 const MInt index = this->m_mapBndCndSegId2Index[m_bndCells[i].m_segmentId[0]];
747 const MInt newBndCellId = m_bndCells.size() - 1;
748 getInsideOutsideAndDistances(newBndCellId, index);
751 if(newBndCell.m_distances[
dist] < 1.0) {
752 if(m_solver->a_hasNeighbor(nghbrId,
dist)) {
753 const MInt nghbrId2 = m_solver->c_neighborId(nghbrId,
dist);
754 if(m_solver->a_isBndryCell(nghbrId2)) {
755 const MInt nghbrBndId2 = m_solver->a_bndId(nghbrId2);
756 if(m_bndCells[nghbrBndId2].m_isFluid ==
false) {
757 newBndCell.m_distances[
dist] = std::numeric_limits<MFloat>::max();
768 m_log <<
" ## redoing sortBoundaryCells" << std::endl;
769 this->sortBoundaryCells();
770 m_log <<
" redoing sortBoundaryCells ## " << std::endl;
773 const MInt newNumberOfBndCells = m_bndCells.size();
775 auto& bndCell = m_bndCells[i];
776 const MInt currentId = bndCell.m_cellId;
777 if(bndCell.m_isFluid) {
778 for(MInt j = 0; j < nDist - 1; j++) {
779 const MInt opp = Ld::oppositeDist(j);
780 const MBool cutj = bndCell.m_distances[j] < 1.0;
781 const MBool cutopp = bndCell.m_distances[opp] < 1.0;
785 if(bndCell.m_distances[j] <= 0.5) {
786 if(cutopp) bndCell.m_distances[j] = 0.5;
790 if(m_solver->a_hasNeighbor(currentId, j)) {
791 const MInt nghbrId = m_solver->c_neighborId(currentId, j);
792 if(m_solver->a_isBndryCell(nghbrId)) {
793 if(m_bndCells[m_solver->a_bndId(nghbrId)].m_isFluid == false) {
794 bndCell.m_distances[j] = std::numeric_limits<MFloat>::max();
803 if(bndCell.m_distances[opp] <= 0.5) {
804 if(cutj) bndCell.m_distances[opp] = 0.5;
808 if(m_solver->a_hasNeighbor(currentId, opp)) {
809 const MInt nghbrId = m_solver->c_neighborId(currentId, opp);
810 if(m_solver->a_isBndryCell(nghbrId)) {
811 if(m_bndCells[m_solver->a_bndId(nghbrId)].m_isFluid == false) {
812 bndCell.m_distances[opp] = std::numeric_limits<MFloat>::max();
821 for(
MInt j = 0; j < nDist - 1; j++) {
822 if(bndCell.m_distances[j] < 0.5) {
823 if(m_solver->a_hasNeighbor(currentId, j)) {
824 const MInt nghbrId = m_solver->c_neighborId(currentId, j);
825 if(m_solver->a_isBndryCell(nghbrId)) {
826 if(m_bndCells[m_solver->a_bndId(nghbrId)].m_isFluid == false) {
827 bndCell.m_distances[j] = std::numeric_limits<MFloat>::max();
837 if(m_outputWallDistanceField) {
838 std::stringstream fileName;
839 fileName << m_solver->restartDir() <<
"lbDistanceField" << m_solver->getIdentifier() << ParallelIo::fileExt();
842 parallelIo.setAttribute(m_solver->solverId(),
"solverId");
843 parallelIo.setAttribute(m_solver->gridInputFileName(),
"gridFile",
"");
845 const MPI_Offset firstGlobalId = m_solver->domainOffset(m_solver->domainId());
846 const MPI_Offset localNoCells = m_solver->noInternalCells();
847 parallelIo.setOffset(localNoCells, firstGlobalId);
848 addWallDistanceFieldToOutputFile(parallelIo,
true,
false);
849 addWallDistanceFieldToOutputFile(parallelIo,
false,
true);
850 m_outputWallDistanceField =
false;
856template <MInt nDim_, MInt nDist_,
class SysEqn>
860 constexpr MInt nDim = 2;
861 constexpr MInt nDist = 9;
863 for(
MInt i = 0; i < (
MInt)m_bndCells.size(); i++) {
864 m_bndCells[i].m_isFluid =
false;
867 if(m_interpolationDistMethod ==
"perpOp") {
868 MBool triangleIntersection;
869 MFloat target[6] = {0, 0, 0, 2, 2, 4};
870 MFloat cellHalfLength = 0.0;
871 MFloat currentDistance = 0;
882 std::vector<MInt> wallIds;
883 for(
MInt i = 0; i < (
MInt)(m_bndCndSegIds.size()); i++) {
884 MBool is_periodic =
false;
885 if(m_noPeriodicSegments != 0)
886 for(
MInt j = 0; j < m_noPeriodicSegments; j++)
887 if(m_bndCndSegIds[i] == m_periodicSegmentsIds[j]) {
892 MBool is_inout =
false;
893 for(
MInt j = 0; j < m_noInOutSegments; j++)
894 if(m_bndCndSegIds[i] == m_inOutSegmentsIds[j]) {
899 if(!is_periodic & !is_inout) wallIds.push_back(i);
902 for(
auto wallId : wallIds) {
903 for(
MInt i = m_bndCndOffsets[wallId]; i < m_bndCndOffsets[wallId + 1]; i++) {
904 const MInt currentId = m_bndCells[i].m_cellId;
908 if(m_solver->m_geometry->pointIsInside(&m_solver->a_coordinate(currentId, 0))) {
910 m_bndCells[i].m_isFluid =
false;
913 m_bndCells[i].m_isFluid =
true;
918 m_bndCells[i].m_distances.clear();
919 m_bndCells[i].m_distances.resize(IPOW3[nDim] - 1, 0.0);
922 for(
MInt j = 0; j < nDim; j++) {
923 cellHalfLength = m_solver->c_cellLengthAtLevel(m_solver->a_level(currentId) + 1);
924 target[j] = m_solver->a_coordinate(currentId, j) - cellHalfLength;
925 target[j + nDim] = m_solver->a_coordinate(currentId, j) + cellHalfLength;
928 c[j] = m_solver->a_coordinate(currentId, j);
932 std::vector<MInt> nodeList;
933 if(m_gridCutTest ==
"SAT")
934 m_solver->m_geometry->getIntersectionElements(target, nodeList, cellHalfLength,
935 &m_solver->a_coordinate(currentId, 0));
937 m_solver->m_geometry->getIntersectionElements(target, nodeList);
939 triangleIntersection =
false;
942 m_bndCells[i].m_distances[
dist] = m_solver->c_cellLengthAtLevel(0);
949 for(
MInt j = 0; j < nDim; j++) {
950 d[j] = c[j] + ((
MFloat)Ld::idFld(
dist, j) - 1.0) * cellHalfLength;
953 m_bndCells[i].m_distances[
dist] = currentDistance;
955 for(
MInt n = 0; n < (signed)nodeList.size(); n++) {
956 if(m_solver->m_geometry->elements[nodeList[n]].m_bndCndId != m_bndCndIds[wallId])
continue;
957 if(m_solver->m_geometry->edgeTriangleIntersection(m_solver->m_geometry->elements[nodeList[n]].m_vertices[0],
958 m_solver->m_geometry->elements[nodeList[n]].m_vertices[1],
960 triangleIntersection =
true;
962 for(
MInt k = 0; k < nDim; k++) {
963 a[k] = m_solver->m_geometry->elements[nodeList[n]].m_vertices[0][k];
964 b[k] = m_solver->m_geometry->elements[nodeList[n]].m_vertices[1][k];
967 gamma = (
b[0] -
a[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (
b[1] -
a[1]);
972 s2 = ((
b[0] -
a[0]) * (c[1] -
a[1]) - (c[0] -
a[0]) * (
b[1] -
a[1])) / gamma;
982 if(s2 < 0.0) s2 = -s2;
984 if(s2 > 1.0)
continue;
986 currentDistance = s2 * F1B2;
988 m_bndCells[i].m_distances[
dist] = (currentDistance < m_bndCells[i].m_distances[
dist])
990 : m_bndCells[i].m_distances[
dist];
996 if(!triangleIntersection) {
997 m_log <<
" BndCell[" << i <<
"] has no triangle intersection!" << std::endl;
1003 else if(m_interpolationDistMethod ==
"circle") {
1007 std::cout <<
"Prescribe analytic circle with radius: " << radius <<
", x:" << x <<
", y:" <<
y << std::endl;
1009 MFloat cellHalfLength, cellRadiusSq, dxB2, dxSq;
1013 for(
MInt i = 0; i < (
MInt)m_bndCells.size(); i++) {
1014 currentId = m_bndCells[i].m_cellId;
1015 cellHalfLength = m_solver->grid().cellLengthAtLevel(m_solver->a_level(currentId) + 1);
1016 cellRadiusSq = (m_solver->a_coordinate(currentId, 0) - x) * (m_solver->a_coordinate(currentId, 0) - x)
1017 + (m_solver->a_coordinate(currentId, 1) -
y) * (m_solver->a_coordinate(currentId, 1) -
y);
1020 if(cellRadiusSq <= radius * radius) {
1021 m_bndCells[i].m_isFluid =
false;
1023 m_bndCells[i].m_isFluid =
true;
1027 m_bndCells[i].m_distances.clear();
1028 m_bndCells[i].m_distances.resize(IPOW3[nDim] - 1, 0.0);
1031 m_bndCells[i].m_distances[
dist] = m_solver->grid().cellLengthAtLevel(0);
1035 dxSq = 4.0 * cellHalfLength * cellHalfLength;
1036 dxB2 = cellHalfLength;
1038 dxSq = 2.0 * 2.0 * cellHalfLength * cellHalfLength;
1039 dxB2 = SQRT2 * cellHalfLength;
1057 for(
MInt j = 0; j < nDim; j++) {
1058 p1 -= m_solver->a_coordinate(currentId, j) * (Ld::idFld(
dist, j) - 1.0) * 2.0 * cellHalfLength / dxSq;
1060 p2 = sqrt(p1 * p1 + (radius * radius - cellRadiusSq) / dxSq);
1063 if(p1 + p2 >= 0.0 && fabs(p1 + p2) <= 0.5) {
1065 m_bndCells[i].m_distances[
dist] = (p1 + p2) * 2.0 * dxB2;
1067 if(p1 - p2 >= 0.0 && fabs(p1 - p2) <= 0.5) {
1068 m_bndCells[i].m_distances[
dist] = (p1 - p2) * 2.0 * dxB2;
1075 std::stringstream ss;
1076 ss <<
"ERROR: Unknown interpolationDistMethod: " << m_interpolationDistMethod << std::endl;
1084 calculateWallDistances2D();
1089 calculateWallDistances2D();
1092template <MInt nDim, MInt nDist,
class SysEqn>
1094 const MBool writeHeader,
1095 const MBool writeData) {
1097 const MInt totalNoCells = m_solver->domainOffset(m_solver->noDomains());
1098 const MInt internalCells = m_solver->noInternalCells();
1102 const MString varName =
"isFluid";
1104 parallelIo.setAttribute(varName,
"name", varName);
1106 for(
MInt i = 0; i < nDist - 1; i++) {
1107 const MString varName =
"distance_" + std::to_string(i);
1109 parallelIo.setAttribute(varName,
"name", varName);
1115 const MString varName =
"isFluid";
1116 for(
MInt i = 0; i < internalCells; i++) {
1119 for(
auto& bndCell : m_bndCells) {
1120 if(m_solver->a_isHalo(bndCell.m_cellId))
continue;
1121 tmp[bndCell.m_cellId] = (bndCell.m_isFluid) ? 1 : 0;
1123 parallelIo.writeArray(tmp.
getPointer(), varName);
1126 for(
MInt j = 0; j < nDist - 1; j++) {
1127 const MString varName =
"distance_" + std::to_string(j);
1128 for(
MInt i = 0; i < internalCells; i++) {
1131 for(
auto& bndCell : m_bndCells) {
1132 if(m_solver->a_isHalo(bndCell.m_cellId))
continue;
1133 tmp[bndCell.m_cellId] = (bndCell.m_distances[j] < 2.0) ? bndCell.m_distances[j] : -1.0;
1135 parallelIo.writeArray(tmp.
getPointer(), varName);
1147template <MInt nDim, MInt nDist,
class SysEqn>
1151 m_log <<
" + Generating parabolic inflow..." << std::endl;
1153 MInt noInflowSegments = 0;
1154 MInt* inflowSegmentIds =
nullptr;
1164 mAlloc(inflowSegmentIds, noInflowSegments,
"inflowSegmentIds", AT_);
1165 for(
MInt i = 0; i < noInflowSegments; i++) {
1166 inflowSegmentIds[i] = Context::getSolverProperty<MInt>(
"inflowSegmentIds", m_solverId, AT_, i);
1169 m_log <<
" - none found" << std::endl << std::endl;
1173 MInt num, currentId, nearestNode, neighborNode0, neighborNode1;
1177 MFloat dmin, dtemp, maxRadius;
1179 MFloat v1_length, v2_length, v3_length, angle0, angle1, proj0, proj1;
1183 for(
MInt i = 0; i < noInflowSegments; i++) {
1184 MInt own = m_solver->m_geometry->m_ownSegmentId[inflowSegmentIds[i]];
1187 if(m_solver->m_geometry->m_parallelGeometry && nDim == 3)
1189 a = allOwnersGetBoundaryVertices(inflowSegmentIds[i], &num);
1191 a = m_solver->m_geometry->GetBoundaryVertices(inflowSegmentIds[i],
nullptr,
nullptr, 0, &num);
1197 for(
MInt j = 0; j < (
MInt)(m_bndCndSegIds.size()); j++)
1198 if(m_bndCndSegIds[j] == inflowSegmentIds[i])
id = j;
1200 if(
id == -1)
continue;
1201 m_log <<
" - segment " << inflowSegmentIds[i] << std::endl;
1206 maxRadius = m_solver->m_geometry->getBndMaxRadius(
a, num);
1207 m_log <<
" * max. radius: " << maxRadius << std::endl;
1210 for(
MInt j = m_bndCndOffsets[
id]; j < m_bndCndOffsets[
id + 1]; j++) {
1211 currentId = m_bndCells[j].m_cellId;
1215 for(
MInt k = 0; k < nDim; k++) {
1216 dmin += (m_solver->a_coordinate(currentId, k) -
a[0][k]) * (m_solver->a_coordinate(currentId, k) -
a[0][k]);
1220 for(
MInt k = 1; k < num; k++) {
1222 for(
MInt l = 0; l < nDim; l++) {
1224 (m_solver->a_coordinate(currentId, l) -
a[k][l]) * (m_solver->a_coordinate(currentId, l) -
a[k][l]);
1234 for(
MInt k = 0; k < nDim; k++) {
1235 v1[k] = m_solver->a_coordinate(currentId, k) -
a[nearestNode][k];
1236 v1_length += v1[k] * v1[k];
1238 v1_length = sqrt(v1_length);
1244 neighborNode0 = (nearestNode + 1) % num;
1246 if(nearestNode == 0)
1247 neighborNode1 = num - 1;
1249 neighborNode1 = nearestNode - 1;
1253 for(
MInt k = 0; k < nDim; k++) {
1254 v2[k] =
a[neighborNode0][k] -
a[nearestNode][k];
1255 v3[k] =
a[neighborNode1][k] -
a[nearestNode][k];
1256 v2_length += v2[k] * v2[k];
1257 v3_length += v3[k] * v3[k];
1259 v2_length = sqrt(v2_length);
1260 v3_length = sqrt(v3_length);
1265 for(
MInt d = 0; d < nDim; d++) {
1266 proj0 += (v1[d] * v2[d]);
1267 proj1 += (v1[d] * v3[d]);
1270 if(proj0 <= 0 && proj1 <= 0)
1274 angle0 = acos(proj0 / (v1_length * v2_length));
1275 angle1 = acos(proj1 / (v1_length * v3_length));
1277 if(angle0 <= angle1)
1278 dmin = sin(angle0) * v1_length;
1280 dmin = sin(angle1) * v1_length;
1283 m_bndCells[j].m_multiplier = dmin;
1289 m_log <<
" * poiseuille inflow: |v|=Ma*c and v ~ r^2" << std::endl;
1292 for(
MInt j = m_bndCndOffsets[
id]; j < m_bndCndOffsets[
id + 1]; j++) {
1293 m_bndCells[j].m_multiplier = m_bndCells[j].m_multiplier / maxRadius;
1294 m_bndCells[j].m_multiplier = 1.0 - m_bndCells[j].m_multiplier;
1295 m_bndCells[j].m_multiplier = 2.0 * (1.0 - (m_bndCells[j].m_multiplier * m_bndCells[j].m_multiplier));
1301 m_log <<
" * poiseille inflow (broader): |v|=Ma*c and v ~ r^4" << std::endl;
1304 for(
MInt j = m_bndCndOffsets[
id]; j < m_bndCndOffsets[
id + 1]; j++) {
1305 m_bndCells[j].m_multiplier = m_bndCells[j].m_multiplier / maxRadius;
1306 m_bndCells[j].m_multiplier = 1.0 - m_bndCells[j].m_multiplier;
1307 m_bndCells[j].m_multiplier = 1.5
1309 - (m_bndCells[j].m_multiplier * m_bndCells[j].m_multiplier
1310 * m_bndCells[j].m_multiplier * m_bndCells[j].m_multiplier));
1315 m_log <<
"lbbndcnddxqy::parabolicInflow() unknown index for parabolic inflow " << std::endl;
1316 std::stringstream errorMessage;
1317 errorMessage <<
"lbbndcnddxqy::parabolicInflow() unknown index for parabolic inflow";
1318 DEBUG(
"lbbndcnddxqy::parabolicInflow() unknown index for parabolic inflow" << std::endl,
1319 MAIA_DEBUG_ASSERTION);
1320 TERMM(1, errorMessage.str());
1335template <MInt nDim, MInt nDist,
class SysEqn>
1344 m_log <<
" * segment owned by: ";
1345 m_solver->m_geometry->determineSegmentOwnership(segmentId, &own, &sumowners, &firstOwner, owners.
getPointer());
1346 for(
MInt d = 0; d < m_solver->noDomains(); d++)
1347 if(owners[d] > 0)
m_log << d <<
" ";
1350 m_log <<
" * sum of owners: " << sumowners << std::endl;
1351 m_log <<
" * root of communication: " << firstOwner << std::endl;
1356 return m_solver->m_geometry->GetBoundaryVertices(segmentId,
nullptr,
nullptr, 0, num);
1360 m_solver->createMPIComm(owners.
getPointer(), sumowners, &charComm);
1368 if(m_solver->m_geometry->m_parallelGeometry) {
1369 offStart = m_solver->m_geometry->m_segmentOffsets[segmentId];
1370 offEnd = m_solver->m_geometry->m_segmentOffsets[segmentId + 1];
1372 offStart = m_solver->m_geometry->m_segmentOffsetsWithoutMB[segmentId];
1373 offEnd = m_solver->m_geometry->m_segmentOffsetsWithoutMB[segmentId + 1];
1375 MInt numElements = offEnd - offStart;
1377 m_log <<
" * number of local triangles: " << numElements << std::endl;
1378 m_log <<
" * segment offsets: " << offStart <<
" - " << offEnd << std::endl;
1381 MInt noTriInfo = nDim * nDim;
1385 for(
MInt t = offStart, i = 0, j = 0; t < offEnd; t++, i++) {
1386 myOriginalIds[i] = m_solver->m_geometry->elements[t].m_originalId;
1387 for(
MInt v = 0; v < nDim; v++)
1388 for(
MInt d = 0; d < nDim; d++, j++)
1389 segTriangles[j] = m_solver->m_geometry->elements[t].m_vertices[v][d];
1394 "numElemPerCPU.getPointer()");
1397 m_log <<
" * triangles per domain: ";
1398 MInt sumallelem = 0;
1399 for(
MInt i = 0; i < sumowners; i++) {
1400 m_log << numElemPerCPU[i] <<
" ";
1401 sumallelem += numElemPerCPU[i];
1402 numTriInfoPerCPU[i] = numElemPerCPU[i] * noTriInfo;
1405 m_log <<
" * sum of global triangles: " << sumallelem << std::endl;
1411 for(
MInt d = 1; d < sumowners; d++) {
1412 displOrig[d] = displOrig[d - 1] + numElemPerCPU[d - 1];
1413 displTris[d] = displTris[d - 1] + numTriInfoPerCPU[d - 1];
1419 "myOriginalIds.getPointer()",
"allOriginalIds.getPointer()");
1424 "segTriangles.getPointer()",
"allSegTriangles.getPointer()");
1426 std::set<MInt> uniqueTriangles;
1427 for(
MInt i = 0; i < sumallelem; i++)
1428 uniqueTriangles.insert(allOriginalIds[i]);
1430 MInt noUniqueTris = uniqueTriangles.size();
1431 m_log <<
" * sum of unique triangles: " << noUniqueTris << std::endl;
1434 for(
MInt i = 0; i < noUniqueTris; i++)
1439 for(
MInt i = 0, j = 0; i < sumallelem; i++) {
1440 MInt dist = distance(uniqueTriangles.begin(), uniqueTriangles.find(allOriginalIds[i]));
1441 if(
dist != noUniqueTris && dbl[
dist] == 0) {
1442 keepOffsets[j] = i * noTriInfo;
1448 return m_solver->m_geometry->GetBoundaryVertices(segmentId, allSegTriangles.
getPointer(),
1449 keepOffsets.
getPointer(), noUniqueTris, num);
1467template <MInt nDim, MInt nDist,
class SysEqn>
1471 const MInt pCellId = m_solver->m_G0CellList[cellIndex];
1472 MFloat rho = m_solver->a_variable(pCellId, PV->RHO);
1473 std::array<MFloat, nDim> uW{};
1474 getBoundaryVelocityMb(cellIndex, uW.data());
1477 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
1478 for(
MInt j = 0; j < nDist - 1; j++) {
1479#ifdef WAR_NVHPC_PSTL
1480 const MFloat q = m_distances[cellIndex][j];
1481 const MInt opposite = m_solver->m_oppositeDist[j];
1483 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1484 const MInt opposite = Ld::oppositeDist(j);
1487 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
1491 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
1492 const MFloat F2q = F2 * q;
1493 m_solver->a_oldDistribution(pCellId, opposite) = (F2q * m_solver->a_distribution(pCellId, j))
1494 + ((F1 - F2q) * m_solver->a_oldDistribution(pCellId, j))
1495 + firstMomentSourceTerm(uW.data(), rho, opposite);
1496#ifndef WAR_NVHPC_PSTL
1497 incrementForces(pCellId, cellIndex, j, uW.data());
1503 m_solver->a_oldDistribution(pCellId, opposite) =
1504 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1512 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
1513 m_solver->a_oldDistribution(pCellId, opposite) =
1514 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1520 for(
MInt j = 0; j < nDist - 1; j++) {
1521#ifdef WAR_NVHPC_PSTL
1522 const MFloat q = m_distances[cellIndex][j];
1523 const MInt opposite = m_solver->m_oppositeDist[j];
1525 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1526 const MInt opposite = Ld::oppositeDist(j);
1529 if(m_solver->a_hasNeighbor(pCellId, j)) {
1531 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
1532 rho = m_solver->a_variable(neighborId, PV->RHO);
1533 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
1534 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
1538 const MFloat F2q = F2 * (F1 - q);
1541 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
1542 m_solver->a_oldDistribution(neighborId, j) =
1543 (m_solver->a_distribution(neighborId, opposite) / F2q)
1544 + (m_solver->a_distribution(neighborId, j) * (F2q - F1) / F2q)
1545 + (F1 / F2q) * firstMomentSourceTerm(uW.data(), rho, j);
1547#ifndef WAR_NVHPC_PSTL
1548 incrementForces(neighborId, cellIndex, opposite, uW.data());
1557 m_solver->setEqDists(pCellId, F1, uW.data());
1574template <MInt nDim, MInt nDist,
class SysEqn>
1578 const MInt pCellId = m_solver->m_G0CellList[cellIndex];
1579 MFloat rho = m_solver->a_variable(pCellId, PV->RHO);
1580 std::array<MFloat, nDim> uW{};
1581 getBoundaryVelocityMb(cellIndex, uW.data());
1584 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
1585 for(
MInt j = 0; j < nDist - 1; j++) {
1586#ifdef WAR_NVHPC_PSTL
1587 const MFloat q = m_distances[cellIndex][j];
1588 const MInt opposite = m_solver->m_oppositeDist[j];
1590 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1591 const MInt opposite = Ld::oppositeDist(j);
1594 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
1598 if(m_solver->a_hasNeighbor(pCellId, opposite)) {
1599 const MInt neighborId = m_solver->c_neighborId(pCellId, opposite);
1602 const MFloat F2q = F2 * q;
1605 MFloat quadratic = Fq * (F2q + 1) * m_solver->a_distribution(pCellId, j)
1606 + (1 + F2q) * (1 - F2q) * m_solver->a_distribution(neighborId, j)
1607 - Fq * (1 - F2q) * m_solver->a_oldDistribution(neighborId, j)
1608 + firstMomentSourceTerm(uW.data(), rho, opposite);
1610 m_solver->a_oldDistribution(pCellId, opposite) = quadratic;
1611#ifndef WAR_NVHPC_PSTL
1612 incrementForces(pCellId, cellIndex, j, uW.data());
1618 m_solver->a_oldDistribution(pCellId, opposite) =
1619 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1625 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
1626 m_solver->a_oldDistribution(pCellId, opposite) =
1627 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1633 for(
MInt j = 0; j < nDist - 1; j++) {
1634#ifdef WAR_NVHPC_PSTL
1635 const MFloat q = m_distances[cellIndex][j];
1636 const MInt opposite = m_solver->m_oppositeDist[j];
1638 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1639 const MInt opposite = Ld::oppositeDist(j);
1643 if(m_solver->a_hasNeighbor(pCellId, j)) {
1645 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
1646 rho = m_solver->a_variable(neighborId, PV->RHO);
1647 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
1648 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
1652 const MFloat F2q = F2 * (F1 - q);
1653 const MFloat Fq = (1 - q);
1656 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
1657 if(m_solver->a_hasNeighbor(neighborId, j)) {
1658 const MInt nneighborId = m_solver->c_neighborId(neighborId, j);
1662 * (m_solver->a_distribution(neighborId, opposite) + firstMomentSourceTerm(uW.data(), rho, j))
1663 + (F2q - 1) / Fq * m_solver->a_distribution(neighborId, j)
1664 - (F2q - 1) / (F2q + 1) * m_solver->a_distribution(nneighborId, j);
1666 m_solver->a_oldDistribution(neighborId, j) = quadratic;
1669 MFloat linear = (m_solver->a_distribution(neighborId, opposite) / F2q)
1670 + (m_solver->a_distribution(neighborId, j) * (F2q - F1) / F2q)
1671 + (F1 / F2q) * firstMomentSourceTerm(uW.data(), rho, j);
1673 m_solver->a_oldDistribution(neighborId, j) = linear;
1675#ifndef WAR_NVHPC_PSTL
1676 incrementForces(neighborId, cellIndex, opposite, uW.data());
1685 m_solver->setEqDists(pCellId, F1, uW.data());
1702template <MInt nDim, MInt nDist,
class SysEqn>
1706 const MInt pCellId = m_solver->m_G0CellList[cellIndex];
1707 MFloat rho = m_solver->a_variable(pCellId, PV->RHO);
1708 std::array<MFloat, nDim> uW{};
1709 getBoundaryVelocityMb(cellIndex, uW.data());
1712 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
1713 for(
MInt j = 0; j < nDist - 1; j++) {
1714#ifdef WAR_NVHPC_PSTL
1715 const MFloat q = m_distances[cellIndex][j];
1716 const MInt opposite = m_solver->m_oppositeDist[j];
1718 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1719 const MInt opposite = Ld::oppositeDist(j);
1722 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
1726 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
1727 const MInt neighborId = m_solver->c_neighborId(pCellId, opposite);
1728 const MInt nneighborId = m_solver->c_neighborId(neighborId, opposite);
1730 const MFloat F2q = F2 * q;
1734 const MFloat wall = Fq * (Fq + 1) / 2 * m_solver->a_distribution(pCellId, j)
1735 + (1 - Fq) * (1 + Fq) * m_solver->a_distribution(neighborId, j)
1736 - Fq * (1 - Fq) / 2 * m_solver->a_distribution(nneighborId, j);
1739 const MFloat wall_bb = wall + firstMomentSourceTerm(uW.data(), rho, opposite);
1742 const MFloat interp = 2 / (1 + Fq) / (2 + Fq) * wall_bb
1743 + F2q / (1 + Fq) * m_solver->a_distribution(pCellId, opposite)
1744 - Fq / (2 + Fq) * m_solver->a_distribution(neighborId, opposite);
1746 m_solver->a_oldDistribution(pCellId, opposite) = interp;
1747#ifndef WAR_NVHPC_PSTL
1748 incrementForces(pCellId, cellIndex, j, uW.data());
1754 m_solver->a_oldDistribution(pCellId, opposite) =
1755 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1761 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
1762 m_solver->a_oldDistribution(pCellId, opposite) =
1763 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW.data(), rho, opposite);
1769 for(
MInt j = 0; j < nDist - 1; j++) {
1770#ifdef WAR_NVHPC_PSTL
1771 const MFloat q = m_distances[cellIndex][j];
1772 const MInt opposite = m_solver->m_oppositeDist[j];
1774 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
1775 const MInt opposite = Ld::oppositeDist(j);
1779 if(m_solver->a_hasNeighbor(pCellId, j)) {
1781 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
1782 rho = m_solver->a_variable(neighborId, PV->RHO);
1783 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
1784 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
1788 const MFloat F2q = F2 * (F1 - q);
1789 const MFloat Fq = (1 - q);
1792 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
1793 const MInt nneighborId = m_solver->c_neighborId(neighborId, j);
1794 const MInt nnneighborId = m_solver->c_neighborId(nneighborId, j);
1797 const MFloat wall = Fq * (Fq + 1) / 2 * m_solver->a_distribution(neighborId, opposite)
1798 + (1 - Fq) * (1 + Fq) * m_solver->a_distribution(nneighborId, opposite)
1799 - Fq * (1 - Fq) / 2 * m_solver->a_distribution(nnneighborId, opposite);
1802 const MFloat wall_bb = wall + firstMomentSourceTerm(uW.data(), rho, j);
1806 const MFloat interp = 2 / (1 + Fq) / (2 + Fq) * wall_bb
1807 + F2q / (1 + Fq) * m_solver->a_distribution(neighborId, j)
1808 - Fq / (2 + Fq) * m_solver->a_distribution(nneighborId, j);
1811 m_solver->a_oldDistribution(neighborId, j) = interp;
1812#ifndef WAR_NVHPC_PSTL
1813 incrementForces(neighborId, cellIndex, opposite, uW.data());
1822 m_solver->setEqDists(pCellId, F1, uW.data());
1842template <MInt nDim, MInt nDist,
class SysEqn>
1845 const MInt opposite = Ld::oppositeDist(j);
1847 const MFloat& Fin = m_solver->a_distribution(cellId, j);
1848 const MFloat& Fout = m_solver->a_oldDistribution(cellId, opposite);
1851 for(
MInt d = 0; d < nDim; d++) {
1852 const MFloat Vin = Ld::ppdfDir(j, d) - uW[d];
1853 const MFloat Vout = Ld::ppdfDir(opposite, d) - uW[d];
1855 m_boundaryCellsMb.force(mbCellId, j, d) = (Fin * Vin - Fout * Vout);
1868template <MInt nDim, MInt nDist,
class SysEqn>
1870 for(
MInt n = 0; n < nDim; n++) {
1871 uW[n] = m_boundaryCellsMb.velocity(mbCellId, n);
1883template <MInt nDim, MInt nDist,
class SysEqn>
1885 for(
MInt d = 0; d < nDim; d++)
1887 for(
MInt i = 0; i < m_lbNoMovingWalls; i++) {
1888 if(m_segIdMovingWalls[i] == m_bndCndSegIds[index]) {
1889 for(
MInt d = 0; d < nDim; d++) {
1890 uW[d] = m_lbWallVelocity[i * nDim + d];
1905template <MInt nDim, MInt nDist,
class SysEqn>
1907 MFloat wT = m_solver->m_initTemperatureKelvin;
1908 for(
MInt i = 0; i < m_lbNoHeatedWalls; i++) {
1909 if(m_segIdHeatedWalls[i] == m_bndCndSegIds[index]) {
1910 wT = m_lbWallTemperature[i];
1930template <MInt nDim, MInt nDist,
class SysEqn>
1933#ifdef WAR_NVHPC_PSTL
1934 MFloat ppdfDir[nDim] = {F0};
1935 for(
MInt d = 0; d < nDim; d++) {
1936 ppdfDir[d] = m_solver->m_ppdfDir[
dist * nDim + d];
1938 const MFloat scalarProduct = std::inner_product(uW, uW + nDim, &ppdfDir[0], .0);
1939 const MFloat weight = m_solver->m_tp[m_solver->m_distType[
dist]];
1941 const MFloat scalarProduct = std::inner_product(uW, uW + nDim, lbDescriptor::ppdfDir<nDim>[
dist], .0);
1942 const MFloat weight = Ld::tp(Ld::distType(
dist));
1945 return 2.0 * F1BCSsq * weight * rho * scalarProduct;
1961template <MInt nDim, MInt nDist,
class SysEqn>
1965 const MInt noMbCells = m_boundaryCellsMb.size();
1967#ifdef WAR_NVHPC_PSTL
1968 mAlloc(m_distances, noMbCells, nDist - 1,
"distances", F1, AT_);
1969 for(
MInt i = 0; i < noMbCells; i++) {
1970 const MInt pCellId = m_solver->m_G0CellList[i];
1971 for(
MInt d = 0; d < nDist - 1; d++) {
1972 m_distances[i][d] = getDistanceMb(pCellId, i, d);
1977 maia::parallelFor<true>(0, noMbCells, [=](
MInt mbId) {
1979#ifdef WAR_NVHPC_PSTL
1981 if(m_bounceBackFunctionMbCase == 0) {
1982 interpolatedBounceBackMb_Bouzidi_lin(mbId, set);
1983 }
else if(m_bounceBackFunctionMbCase == 1) {
1984 interpolatedBounceBackMb_Bouzidi_qua(mbId, set);
1986 interpolatedBounceBackMb_Yu_qua(mbId, set);
1990 (this->*bounceBackFunctionMb)(mbId, set);
1993 if(m_solver->m_isThermal) {
1994 interpolatedBounceBackMb_Bouzidi_lin_thermal(mbId, set);
1996 if(m_solver->m_isTransport) {
1997 interpolatedBounceBackMb_Bouzidi_lin_transport(mbId, set);
2001#ifdef WAR_NVHPC_PSTL
2004 if(m_calcWallForces && m_solver->m_currentNoG0Cells > 0) {
2005 calculateWallForcesMb(set);
2022template <MInt nDim, MInt nDist,
class SysEqn>
2026 MInt noMbCells = m_boundaryCellsMb.size();
2027 if(m_solver->noDomains() > 1) {
2028 MPI_Allreduce(&noMbCells, &noMbCells, 1, MPI_INT, MPI_SUM, m_solver->mpiComm(), AT_,
"noMbCells",
"noMbCells");
2030 if(!m_solver->domainId()) {
2031 std::cout <<
"Apply free surface bc to " << noMbCells <<
" no mbCells" << std::endl;
2034 for(
MInt mbCellId = 0; mbCellId < m_boundaryCellsMb.size(); mbCellId++) {
2035 const MInt pCellId = m_boundaryCellsMb.cellId(mbCellId);
2037 ASSERT(m_solver->a_isG0CandidateOfSet(pCellId, (set - m_solver->m_levelSetId)),
"Inconsistent collector!");
2039 interpolatedAntiBounceBackMb_Bouzidi_qua(mbCellId, set);
2060template <MInt nDim, MInt nDist,
class SysEqn>
2064 std::array<MFloat, nDim> uW{};
2065 getBoundaryVelocity(index, uW.data());
2067#ifdef WAR_NVHPC_PSTL
2071 MInt offset = end - begin;
2073 maia::parallelFor<true>(0, offset, [=](
MInt id) {
2075 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
2078 if((globalTimeStep) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
2083 interpolatedBounceBackSingleSpecies(i, uW.data());
2086 if(m_calcWallForces) {
2087 calculateWallForces(index);
2105template <MInt nDim, MInt nDist,
class SysEqn>
2109#ifdef WAR_NVHPC_PSTL
2111 const MInt begin = m_bndCndOffsets[
index];
2112 const MInt end = m_bndCndOffsets[
index + 1];
2113 const MInt offset = end - begin;
2115 maia::parallelFor<true>(0, offset, [=](
MInt id) {
2116 const MInt i = begin +
id;
2117 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
2120 if((globalTimeStep) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
2124 if(m_solver->a_isHalo(m_bndCells[i].m_cellId)) return;
2126 for(MInt j = 0; j < nDist - 1; j++) {
2127#ifdef WAR_NVHPC_PSTL
2128 const MInt opposite = m_solver->m_oppositeDist[j];
2130 const MInt opposite = Ld::oppositeDist(j);
2132 if(m_solver->a_hasNeighbor(m_bndCells[i].m_cellId, opposite) == 0) {
2134 if(m_solver->c_parentId(m_bndCells[i].m_cellId) > -1) {
2135 if(m_solver->a_hasNeighbor(m_solver->c_parentId(m_bndCells[i].m_cellId), opposite)) continue;
2137 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) =
2138 m_solver->a_distribution(m_bndCells[i].m_cellId, opposite);
2158template <MInt nDim, MInt nDist,
class SysEqn>
2162 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2164 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(cellId)) != 0)
continue;
2169 if(m_solver->a_isHalo(cellId))
continue;
2171 for(
MInt j = 0; j < nDist - 1; j++) {
2172 if(m_solver->a_hasNeighbor(cellId, Ld::oppositeDist(j)) == 0) {
2173 m_solver->a_oldDistribution(cellId, j) = m_solver->a_oldDistribution(cellId, Ld::oppositeDist(j));
2192template <MInt nDim, MInt nDist,
class SysEqn>
2197 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2199 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
2207 if(m_solver->a_hasNeighbor(cellId, 2) == 0) {
2208 neighborId = m_solver->c_neighborId(cellId, 3);
2210 neighborId = m_solver->c_neighborId(cellId, 2);
2213 MFloat rho = m_solver->a_variable(neighborId, PV->RHO);
2215 const MFloat old_rho = m_solver->a_oldVariable(cellId, PV->RHO);
2219 rho = (old_rho + rho) / 2.0;
2222 const std::array<MFloat, nDim> u{};
2223 const MFloat squaredVelocity{};
2225 m_solver->setEqDists(cellId, rho, squaredVelocity, u.data());
2227 m_solver->a_variable(cellId, PV->RHO) = rho;
2228 for(
MInt n = 0; n < nDim; n++) {
2229 m_solver->a_variable(cellId, PV->VV[n]) = u[n];
2250template <MInt nDim, MInt nDist,
class SysEqn>
2254 MFloat F2q, rhoF, uF[nDim], uBF[nDim], tmpUF, tmpUBF, tmp2UF,
b[2 * nDim];
2256 const MInt dist1 = Ld::distFld(0);
2257 const MInt dist2 = Ld::distFld(1) + Ld::distFld(0);
2261 MInt nghbrId, tmpDistId;
2264 static std::ofstream ofl;
2267 for(
MInt i = 0; i < nDist - 1; i++) {
2268 distributions[i] = 0.0;
2276 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2278 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
2282 id = m_bndCells[i].m_cellId;
2286 if(m_solver->a_level(
id) < m_solver->maxLevel())
continue;
2288 m_omega = 2.0 / (1.0 + 6.0 * m_solver->a_nu(
id) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(
id)));
2299 if(m_bndCells[i].m_isFluid) {
2300 rhoF = m_solver->a_variable(
id, PV->RHO);
2301 for(
MInt n = 0; n < nDim; n++) {
2302 uF[n] = m_solver->a_variable(
id, PV->VV[n]);
2304 b[2 * n + 1] = uF[n];
2307 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
2309 for(
MInt j = 0; j < nDist - 1; j++) {
2319 k = j - Ld::distFld(0);
2320 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
2325 k = j - (Ld::distFld(0) + Ld::distFld(1));
2326 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
2336 if(m_bndCells[i].m_distances[j] < 0.5) {
2337 F2q = F2 * m_bndCells[i].m_distances[j];
2339 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(j)) > 0) {
2340 nghbrId = m_solver->c_neighborId(
id, Ld::oppositeDist(j));
2344 for(
MInt n = 0; n < nDim; n++) {
2345 uBF[n] = m_solver->a_variable(nghbrId, n);
2346 tmpUBF += (Ld::idFld(j, n) - 1) * uBF[n];
2352 fEq = Ld::tp(tpIndex) * rhoF
2353 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
2354 xi = m_omega * (F2q - 1.0) / (1.0 - 2.0 * m_omega);
2357 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) =
2358 (1.0 - xi) * m_solver->a_distribution(
id, j) + xi * fEq;
2361 distributions[Ld::oppositeDist(j)] +=
2362 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) + m_solver->a_distribution(
id, j);
2369 if(m_solver->a_hasNeighbor(
id, j) == 0) {
2371 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) = m_solver->a_distribution(
id, j);
2374 distributions[Ld::oppositeDist(j)] +=
2375 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) + m_solver->a_distribution(
id, j);
2390 for(
MInt j = 0; j < nDist - 1; j++) {
2406 if(m_solver->a_hasNeighbor(
id, j) > 0 && !m_solver->a_isHalo(m_solver->c_neighborId(
id, j))) {
2407 if(m_bndCells[i].m_distances[j] <= 0.5) {
2408 F2q = F2 - F2 * m_bndCells[i].m_distances[j];
2410 nghbrId = m_solver->c_neighborId(
id, j);
2412 rhoF = m_solver->a_variable(nghbrId, PV->RHO);
2413 for(
MInt n = 0; n < nDim; n++) {
2414 uF[n] = m_solver->a_variable(nghbrId, PV->VV[n]);
2416 b[2 * n + 1] = uF[n];
2419 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
2424 tmpUF =
b[Ld::oppositeDist(j)];
2428 k = Ld::oppositeDist(j) - Ld::distFld(0);
2429 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
2433 k = Ld::oppositeDist(j) - (Ld::distFld(0) + Ld::distFld(1));
2434 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
2441 for(
MInt dim = 0; dim < nDim; dim++) {
2442 uBF[dim] = (1.0 - 3.0 / F2q) * uF[dim];
2443 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
2446 fEq = Ld::tp(tpIndex) * rhoF
2447 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
2448 xi = m_omega * (F2q - 1.0) / (1 + 0.5 * m_omega);
2452 m_solver->a_oldDistribution(nghbrId, j) =
2453 (1.0 - xi) * m_solver->a_distribution(nghbrId, Ld::oppositeDist(j)) + xi * fEq;
2457 m_solver->a_oldDistribution(nghbrId, j) + m_solver->a_distribution(nghbrId, Ld::oppositeDist(j));
2466 m_solver->a_variable(
id, PV->RHO) = 1.0;
2467 m_solver->a_oldVariable(
id, PV->RHO) = 1.0;
2469 for(
MInt n = 0; n < nDim; n++) {
2470 m_solver->a_variable(
id, n) = 0.0;
2471 m_solver->a_oldVariable(
id, n) = 0.0;
2477 for(
MInt j = 0; j < Ld::distFld(0); j++) {
2478 m_solver->a_oldDistribution(
id, j) = Ld::tp(1);
2482 tmpDistId = Ld::distFld(0);
2483 for(
MInt j = 0; j < Ld::distFld(1); j++) {
2484 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(2);
2488 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
2489 for(
MInt j = 0; j < Ld::distFld(2); j++) {
2490 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(3);
2494 m_solver->a_oldDistribution(
id, Ld::lastId()) = Ld::tp(0);
2506template <MInt nDim, MInt nDist,
class SysEqn>
2510 MFloat q, rhoF, uF[nDim], tmpUF, tmpUBF, tmp2UF, tmp2UBF = 0.0,
b[2 * nDim];
2512 for(
MInt d = 0; d < nDim; d++) {
2513 uBF[d] = std::numeric_limits<MFloat>::max();
2516 MInt id = 0, k, tpIndex;
2518 MInt nghbrId, tmpDistId;
2521 static std::ofstream ofl;
2524 for(
MInt i = 0; i < nDist - 1; i++) {
2525 distributions[i] = 0.0;
2530 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2532 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
2538 if(m_solver->a_level(
id) < m_solver->maxLevel())
continue;
2540 id = m_bndCells[i].m_cellId;
2542 m_omega = 2.0 / (1.0 + 6.0 * m_solver->a_nu(
id) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(
id)));
2553 if(m_bndCells[i].m_isFluid) {
2554 rhoF = m_solver->a_variable(
id, PV->RHO);
2556 for(
MInt d = 0; d < nDim; d++) {
2557 uF[d] = m_solver->a_variable(
id, d);
2558 tmp2UF += uF[d] * uF[d];
2560 b[2 * d + 1] = uF[d];
2563 for(
MInt j = 0; j < nDist - 1; j++) {
2564 if(j < Ld::distFld(0)) {
2569 if(j < (Ld::distFld(0) + Ld::distFld(1))) {
2571 k = j - Ld::distFld(0);
2572 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
2576 k = j - (Ld::distFld(0) + Ld::distFld(1));
2577 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
2586 if(m_bndCells[i].m_distances[j] < 0.5) {
2587 q = m_bndCells[i].m_distances[j];
2589 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(j)) > 0) {
2590 nghbrId = m_solver->c_neighborId(
id, Ld::oppositeDist(j));
2593 uBF[0] = (q - 1.0) * m_solver->a_variable(
id, PV->U)
2594 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->U) / (q + 1.0);
2595 uBF[1] = (q - 1.0) * m_solver->a_variable(
id, PV->V)
2596 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->V) / (q + 1.0);
2598 IF_CONSTEXPR(nDim == 3)
2599 uBF[2] = (q - 1.0) * m_solver->a_variable(
id, PV->W)
2600 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->W) / (q + 1.0);
2604 for(
MInt d = 0; d < nDim; d++) {
2605 tmpUBF += (Ld::idFld(j, d) - 1) * uBF[d];
2606 tmp2UBF += uBF[d] * uBF[d];
2610 for(
MInt dim = 0; dim < nDim; dim++) {
2611 uBF[dim] = (q - 1.0) * uF[dim] / q;
2612 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
2613 tmp2UBF += uBF[dim] * uBF[dim];
2617 fEqW = Ld::tp(tpIndex) * rhoF
2618 * (1.0 + tmpUBF * F1BCSsq + tmpUBF * tmpUBF * F1BCSsq * F1BCSsq * F1B2 - tmp2UBF * F1BCSsq * F1B2);
2619 fEqF = Ld::tp(tpIndex) * rhoF
2620 * (1.0 + tmpUF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
2623 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) =
2624 (1.0 - m_omega) * (m_solver->a_distribution(
id, Ld::oppositeDist(j)) - fEqF) + fEqW;
2627 distributions[Ld::oppositeDist(j)] +=
2628 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) + m_solver->a_distribution(
id, j);
2636 if(m_solver->a_hasNeighbor(
id, j) == 0) {
2637 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) = m_solver->a_distribution(
id, j);
2640 distributions[Ld::oppositeDist(j)] +=
2641 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) + m_solver->a_distribution(
id, j);
2656 for(
MInt j = 0; j < nDist - 1; j++) {
2671 if(m_solver->a_hasNeighbor(
id, j) > 0 && !m_solver->a_isHalo(m_solver->c_neighborId(
id, j))) {
2672 if(m_bndCells[i].m_distances[j] <= 0.5) {
2673 q = F1 - m_bndCells[i].m_distances[j];
2675 nghbrId = m_solver->c_neighborId(
id, j);
2677 rhoF = m_solver->a_variable(nghbrId, PV->RHO);
2679 for(
MInt d = 0; d < nDim; d++) {
2680 uF[d] = m_solver->a_variable(
id, d);
2681 tmp2UF += uF[d] * uF[d];
2683 b[2 * d + 1] = uF[d];
2686 if(j < Ld::distFld(0)) {
2687 tmpUF =
b[Ld::oppositeDist(j)];
2690 if(j < (Ld::distFld(0) + Ld::distFld(1))) {
2691 k = Ld::oppositeDist(j) - Ld::distFld(0);
2692 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
2695 k = Ld::oppositeDist(j) - (Ld::distFld(0) + Ld::distFld(1));
2696 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
2704 for(
MInt dim = 0; dim < nDim; dim++) {
2705 uBF[dim] = (q - 1.0) * uF[dim] / q;
2706 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
2707 tmp2UBF += uBF[dim] * uBF[dim];
2714 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(j)) > 0) {
2715 nghbrId = m_solver->c_neighborId(
id, Ld::oppositeDist(j));
2718 uBF[0] = (q - 1.0) * m_solver->a_variable(
id, PV->U)
2719 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->U) / (q + 1.0);
2720 uBF[1] = (q - 1.0) * m_solver->a_variable(
id, PV->V)
2721 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->V) / (q + 1.0);
2722 IF_CONSTEXPR(nDim == 3)
2723 uBF[2] = (q - 1.0) * m_solver->a_variable(
id, PV->W)
2724 + (1.0 - q) * (q - 1.0) * m_solver->a_variable(nghbrId, PV->W) / (q + 1.0);
2727 for(
MInt d = 0; d < nDim; d++) {
2728 tmpUBF += (Ld::idFld(j, d) - 1) * uBF[d];
2729 tmp2UBF += uBF[d] * uBF[d];
2733 for(
MInt dim = 0; dim < nDim; dim++) {
2734 uBF[dim] = (q - 1.0) * uF[dim] / q;
2735 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
2736 tmp2UBF += uBF[dim] * uBF[dim];
2741 fEqW = Ld::tp(tpIndex) * rhoF
2742 * (1.0 + tmpUBF * F1BCSsq + tmpUBF * tmpUBF * F1BCSsq * F1BCSsq * F1B2 - tmp2UBF * F1BCSsq * F1B2);
2743 fEqF = Ld::tp(tpIndex) * rhoF
2744 * (1.0 + tmpUF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
2747 m_solver->a_oldDistribution(nghbrId, j) =
2748 (1.0 - m_omega) * (m_solver->a_distribution(nghbrId, j) - fEqF) + fEqW;
2752 m_solver->a_oldDistribution(nghbrId, j) + m_solver->a_distribution(nghbrId, Ld::oppositeDist(j));
2761 m_solver->a_variable(
id, PV->RHO) = 1.0;
2762 for(
MInt d = 0; d < nDim; d++) {
2763 m_solver->a_variable(
id, d) = 0.0;
2766 m_solver->a_oldVariable(
id, PV->RHO) = 1.0;
2767 for(
MInt d = 0; d < nDim; d++) {
2768 m_solver->a_oldVariable(
id, d) = 0.0;
2774 for(
MInt j = 0; j < Ld::distFld(0); j++) {
2775 m_solver->a_oldDistribution(
id, j) = Ld::tp(1);
2779 tmpDistId = Ld::distFld(0);
2780 for(
MInt j = 0; j < Ld::distFld(1); j++) {
2781 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(2);
2785 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
2786 for(
MInt j = 0; j < Ld::distFld(2); j++) {
2787 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(3);
2791 m_solver->a_oldDistribution(
id, Ld::lastId()) = Ld::tp(0);
2814template <MInt nDim, MInt nDist,
class SysEqn>
2818 const MFloat wT = getBoundaryTemperature(index);
2820 std::array<MFloat, nDim> uW{};
2821 getBoundaryVelocity(index, uW.data());
2823 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2825 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
2829 interpolatedBounceBackSingleSpecies(i, uW.data());
2830 const MInt pCellId = m_bndCells[i].m_cellId;
2833 calculateEqDistsWallSingleSpeciesThermal(pCellId, wT);
2853template <MInt nDim, MInt nDist,
class SysEqn>
2857 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
2858 const MInt currentId = m_bndCells[i].m_cellId;
2859 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)) != 0)
continue;
2864 if(m_solver->a_isHalo(currentId))
continue;
2866 for(
MInt j = 0; j < nDist - 1; j++) {
2867 if(m_solver->a_hasNeighbor(currentId, Ld::oppositeDist(j)) == 0) {
2868 m_solver->a_oldDistribution(currentId, j) = m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j));
2869 m_solver->a_oldDistributionThermal(currentId, j) =
2870 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j));
2888template <MInt nDim, MInt nDist,
class SysEqn>
2897 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++,
p++) {
2898 const MInt currentId = m_bndCells[i].m_cellId;
2899 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)) != 0)
continue;
2909 if(m_solver->a_level(currentId) < m_solver->maxLevel())
continue;
2918 if(m_bndCells[i].m_isFluid) {
2919 for(
MInt j = 0; j < nDist - 1; j++) {
2933 if(m_bndCells[i].m_distances[j] <= 0.5) {
2935 F2 * m_bndCells[i].m_distances[j];
2936 if(m_solver->a_hasNeighbor(currentId, Ld::oppositeDist(j)) > 0) {
2937 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j)) =
2938 (F2q * m_solver->a_distribution(currentId, j))
2939 + ((1 - F2q) * m_solver->a_oldDistribution(currentId, j));
2940 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j)) =
2941 (F2q * m_solver->a_distributionThermal(currentId, j))
2942 + ((1 - F2q) * m_solver->a_oldDistributionThermal(currentId, j));
2948 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j)) = m_solver->a_distribution(currentId, j);
2949 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j)) =
2950 m_solver->a_distributionThermal(currentId, j);
2957 if(m_solver->a_hasNeighbor(currentId, j) == 0) {
2958 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j)) = m_solver->a_distribution(currentId, j);
2959 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j)) =
2960 m_solver->a_distributionThermal(currentId, j);
2971 for(
MInt j = 0; j < nDist - 1; j++) {
2988 if(m_solver->a_hasNeighbor(currentId, j) > 0 && !m_solver->a_isHalo(m_solver->c_neighborId(currentId, j))) {
2989 const MInt neighborId = m_solver->c_neighborId(currentId, j);
2991 const MFloat F2q = F2 - F2 * m_bndCells[i].m_distances[j];
2993 if(m_bndCells[i].m_distances[j] < 0.5) {
2994 m_solver->a_oldDistribution(neighborId, j) =
2995 (m_solver->a_distribution(neighborId, Ld::oppositeDist(j)) / F2q)
2996 + (m_solver->a_distribution(neighborId, j) * (F2q - 1.0) / F2q);
2997 m_solver->a_oldDistributionThermal(neighborId, j) =
2998 (m_solver->a_distributionThermal(neighborId, Ld::oppositeDist(j)) / F2q)
2999 + (m_solver->a_distributionThermal(neighborId, j) * (F2q - 1.0) / F2q);
3008 m_solver->a_variable(currentId, PV->RHO) = 1.0;
3009 m_solver->a_oldVariable(currentId, PV->RHO) = 1.0;
3010 for(
MInt dir = 0; dir < nDim; dir++) {
3011 m_solver->a_variable(currentId, PV->U + dir) = 0.0;
3012 m_solver->a_oldVariable(currentId, PV->U + dir) = 0.0;
3014 m_solver->a_variable(currentId, PV->T) = m_solver->m_initTemperatureKelvin;
3015 m_solver->a_oldVariable(currentId, PV->T) = m_solver->m_initTemperatureKelvin;
3017 const MFloat T = m_solver->a_variable(currentId, PV->T);
3022 for(
MInt j = 0; j < Ld::distFld(0); j++) {
3023 m_solver->a_oldDistribution(currentId, j) = Ld::tp(1);
3025 m_solver->a_oldDistributionThermal(currentId, j) = Ld::tp(1) * F1BCSsq * T * CSsq;
3029 MInt tmpDistId = Ld::distFld(0);
3030 for(
MInt j = 0; j < Ld::distFld(1); j++) {
3031 m_solver->a_oldDistribution(currentId, tmpDistId + j) = Ld::tp(2);
3033 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j) = Ld::tp(2) * F1BCSsq * T * CSsq;
3037 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
3038 for(
MInt j = 0; j < Ld::distFld(2); j++) {
3039 m_solver->a_oldDistribution(currentId, tmpDistId + j) = Ld::tp(3);
3041 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j) = Ld::tp(3) * F1BCSsq * T * CSsq;
3045 m_solver->a_oldDistribution(currentId, Ld::lastId()) = Ld::tp(0);
3046 m_solver->a_oldDistributionThermal(currentId, Ld::lastId()) = Ld::tp(0) * T;
3066template <MInt nDim, MInt nDist,
class SysEqn>
3070 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3071 const MInt currentId = m_bndCells[i].m_cellId;
3073 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)) != 0)
continue;
3078 const MInt neighborDir = (m_solver->a_hasNeighbor(currentId, 2) == 0) ? 3 : 2;
3079 const MInt neighborId = m_solver->c_neighborId(currentId, neighborDir);
3082 const MFloat old_rho = m_solver->a_oldVariable(currentId, PV->RHO);
3083 const MFloat old_T = m_solver->m_initTemperatureKelvin;
3087 const MFloat rho = F1B2 * (m_solver->a_variable(neighborId, PV->RHO) + old_rho);
3088 const MFloat T = F1B2 * (m_solver->a_variable(neighborId, PV->T) + old_T);
3095 for(
MInt j = 0; j < Ld::distFld(0); j++) {
3096 m_solver->a_oldDistribution(currentId, j) = Ld::tp(1) * F1BCSsq * rho * CSsq;
3097 m_solver->a_distribution(currentId, j) = m_solver->a_oldDistribution(currentId, j);
3099 m_solver->a_oldDistributionThermal(currentId, j) = Ld::tp(1) * F1BCSsq * T * CSsq;
3100 m_solver->a_distributionThermal(currentId, j) = m_solver->a_oldDistributionThermal(currentId, j);
3104 MInt tmpDistId = Ld::distFld(0);
3105 for(
MInt j = 0; j < Ld::distFld(1); j++) {
3106 m_solver->a_oldDistribution(currentId, tmpDistId + j) = Ld::tp(2) * F1BCSsq * rho * CSsq;
3107 m_solver->a_distribution(currentId, tmpDistId + j) = m_solver->a_oldDistribution(currentId, tmpDistId + j);
3109 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j) = Ld::tp(2) * F1BCSsq * T * CSsq;
3110 m_solver->a_distributionThermal(currentId, tmpDistId + j) =
3111 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j);
3115 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
3116 for(
MInt j = 0; j < Ld::distFld(2); j++) {
3117 m_solver->a_oldDistribution(currentId, tmpDistId + j) = Ld::tp(3) * F1BCSsq * rho * CSsq;
3118 m_solver->a_distribution(currentId, tmpDistId + j) = m_solver->a_oldDistribution(currentId, tmpDistId + j);
3120 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j) = Ld::tp(3) * F1BCSsq * T * CSsq;
3121 m_solver->a_distributionThermal(currentId, tmpDistId + j) =
3122 m_solver->a_oldDistributionThermal(currentId, tmpDistId + j);
3126 m_solver->a_oldDistribution(currentId, Ld::lastId()) = Ld::tp(0) * rho;
3127 m_solver->a_distribution(currentId, Ld::lastId()) = m_solver->a_oldDistribution(currentId, Ld::lastId());
3129 m_solver->a_oldDistributionThermal(currentId, Ld::lastId()) = Ld::tp(0) * T;
3130 m_solver->a_distributionThermal(currentId, Ld::lastId()) =
3131 m_solver->a_oldDistributionThermal(currentId, Ld::lastId());
3133 m_solver->a_variable(currentId, PV->RHO) = rho;
3134 for(
MInt dir = 0; dir < nDim; dir++) {
3135 m_solver->a_variable(currentId, PV->U + dir) = 0.0;
3137 m_solver->a_variable(currentId, PV->T) = T;
3151template <MInt nDim, MInt nDist,
class SysEqn>
3165 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++,
p++) {
3167 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3171 id = m_bndCells[i].m_cellId;
3174 m_solver->a_variable(
id, PV->T) = m_solver->m_initTemperatureKelvin;
3175 m_solver->a_oldVariable(
id, PV->T) = m_solver->m_initTemperatureKelvin;
3177 for(
MInt d = 0; d < nDim; d++) {
3178 m_solver->a_variable(
id, d) = 0.0;
3181 MFloat T = m_solver->a_variable(
id, PV->T);
3182 MFloat rho = m_solver->a_variable(
id, PV->RHO);
3184 for(
MInt j = 0; j < Ld::distFld(0); j++) {
3185 m_solver->a_oldDistribution(
id, j) = Ld::tp(1) * F1BCSsq * rho * CSsq;
3186 m_solver->a_oldDistributionThermal(
id, j) = Ld::tp(1) * F1BCSsq * T * CSsq;
3190 tmpDistId = Ld::distFld(0);
3191 for(
MInt j = 0; j < Ld::distFld(1); j++) {
3192 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(2) * F1BCSsq * rho * CSsq;
3193 m_solver->a_oldDistributionThermal(
id, tmpDistId + j) = Ld::tp(2) * F1BCSsq * T * CSsq;
3197 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
3198 for(
MInt j = 0; j < Ld::distFld(2); j++) {
3199 m_solver->a_oldDistribution(
id, tmpDistId + j) = Ld::tp(3) * F1BCSsq * rho * CSsq;
3200 m_solver->a_oldDistributionThermal(
id, tmpDistId + j) = Ld::tp(3) * F1BCSsq * T * CSsq;
3203 m_solver->a_oldDistribution(
id, Ld::lastId()) = Ld::tp(0) * rho;
3204 m_solver->a_oldDistributionThermal(
id, Ld::lastId()) = Ld::tp(0) * T;
3228template <MInt nDim, MInt nDist,
class SysEqn>
3234 constexpr MInt lb_proj_zplane_neigh[27] = {-1, -1, -1, -1, 26, -1, -1, -1, -1, -1, 0, -1, 1, -1,
3235 2, -1, 3, -1, 6, -1, 7, -1, 8, -1, 9, -1, -1};
3237 MInt nocells = m_bndCndOffsets[
index + 1] - m_bndCndOffsets[
index];
3241 MFloat T_inner = 0.0, T_outer = 0.0, T_wall = m_solver->m_initTemperatureKelvin;
3243 for(
MInt num = 0; num < nocells; num++) {
3244 bndId = num + m_bndCndOffsets[
index];
3245 T_inner = m_solver->a_variable(m_bndCells[bndId].m_cellId, PV->T);
3247 T_outer = 2 * T_wall - T_inner;
3249 for(
MInt j = 0; j < Ld::distFld(0); j++)
3250 ghosts(num, j) = Ld::tp(1) * F1BCSsq * T_outer * CSsq;
3253 tmpDistId = Ld::distFld(0);
3254 for(
MInt j = 0; j < Ld::distFld(1); j++)
3255 ghosts(num, tmpDistId + j) = Ld::tp(2) * F1BCSsq * T_outer * CSsq;
3258 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
3259 for(
MInt j = 0; j < Ld::distFld(2); j++)
3260 ghosts(num, tmpDistId + j) = Ld::tp(3) * F1BCSsq * T_outer * CSsq;
3262 ghosts(num, Ld::lastId()) = Ld::tp(0) * T_outer;
3265 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3267 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3275 if(m_solver->a_isHalo(m_bndCells[i].m_cellId))
continue;
3279 MInt proj_neigh = 0;
3280 for(
MInt j = 0; j < nDist - 1; j++) {
3281 if(m_solver->a_hasNeighbor(m_bndCells[i].m_cellId, Ld::oppositeDist(j)) == 0) {
3282 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) =
3283 m_solver->a_distribution(m_bndCells[i].m_cellId, Ld::oppositeDist(j));
3285 proj_dir = lb_proj_zplane_neigh[Ld::oppositeDist(j)];
3287 if(proj_dir < 0)
continue;
3290 proj_neigh = i - m_bndCndOffsets[
index];
3292 for(
MInt l = m_bndCndOffsets[index]; l < m_bndCndOffsets[
index + 1]; l++)
3293 if(m_bndCells[l].m_cellId == m_solver->c_neighborId(m_bndCells[i].m_cellId, proj_dir)) {
3294 proj_neigh = l - m_bndCndOffsets[
index];
3300 if(proj_neigh >= 0 && proj_neigh < nocells)
3301 m_solver->a_oldDistributionThermal(m_bndCells[i].m_cellId, j) = ghosts(proj_neigh, j);
3338template <MInt nDim, MInt nDist,
class SysEqn>
3345 MFloat T_wall = m_solver->m_initTemperatureKelvin;
3346 MFloat eps = 0.0000000000001;
3348 std::array<MFloat, nDim> uW{};
3349 getBoundaryVelocity(index, uW.data());
3351 for(
MInt i = start; i < end; i++) {
3353 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3359 interpolatedBounceBackSingleSpecies(i, uW.data());
3361 MInt currentId = m_bndCells[i].m_cellId;
3362 const MInt pCellId = currentId;
3369 if(m_bndCells[i].m_isFluid) {
3370 for(
MInt j = 0; j < nDist - 1; j++) {
3372 if(m_solver->a_hasNeighbor(pCellId, j) == 0) {
3373 MFloat T_inner = m_solver->a_variable(currentId, PV->T);
3375 if(m_bndCells[i].m_distances[j] > eps) {
3376 T_outer = (T_wall - T_inner) / (m_bndCells[i].m_distances[j]) + T_inner;
3378 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j)) =
3379 Ld::tp(Ld::distType(j)) * F1BCSsq * T_outer * CSsq;
3383 m_solver->a_oldDistributionThermal(currentId, Ld::oppositeDist(j)) =
3384 Ld::tp(Ld::distType(j)) * F1BCSsq * T_wall * CSsq;
3394 for(
MInt j = 0; j < nDist; j++) {
3396 if(m_solver->a_hasNeighbor(pCellId, j) != 0)
3397 if(!m_solver->a_isBndryCell(m_solver->c_neighborId(pCellId, j))) {
3398 MInt neighborId = m_solver->c_neighborId(pCellId, j);
3400 MFloat T_inner = m_solver->a_variable(neighborId, PV->T);
3401 MFloat T_outer = (T_wall - T_inner) / (1.0 - m_bndCells[i].m_distances[j]) + T_inner;
3404 m_solver->a_oldDistributionThermal(neighborId, j) = Ld::tp(Ld::distType(j)) * F1BCSsq * T_outer * CSsq;
3421template <MInt nDim, MInt nDist,
class SysEqn>
3422template <MInt direction>
3427 if constexpr(direction > nDim - 1) {
3428 std::stringstream ss;
3429 ss <<
"Function not defined for nDim=" << nDim <<
" and direction =" << direction << std::endl;
3435 std::array<MFloat, nDim> uW;
3436 std::array<MFloat, 2 * nDim> c;
3438 uW[direction / 2] = m_Ma * LBCS;
3439 for(
MInt d = 0; d < nDim; d++) {
3441 c[2 * d + 1] = uW[d];
3445 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3446 const MInt id = m_bndCells[i].m_cellId;
3449 if(m_solver->a_isHalo(
id))
continue;
3451 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3460 const MFloat rhoF = m_solver->a_variable(
id, PV->RHO);
3502 for(
MInt currentDist = 0; currentDist < nDist - 1; currentDist++) {
3504 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(currentDist)) == 0) {
3505 m_solver->a_oldDistribution(
id, currentDist) = m_solver->a_distribution(
id, Ld::oppositeDist(currentDist));
3517 if(currentDist < Ld::distFld(0)) {
3518 tmpUW = c[currentDist];
3519 }
else if(currentDist < Ld::distFld(0) + Ld::distFld(1)) {
3520 const MInt k = currentDist - Ld::distFld(0);
3521 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
3523 const MInt k = currentDist - (Ld::distFld(0) + Ld::distFld(1));
3524 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
3526 m_solver->a_oldDistribution(
id, currentDist) += 2.0 * Ld::tp(Ld::distType(currentDist)) * rhoF * F1BCSsq * tmpUW;
3550template <MInt nDim, MInt nDist,
class SysEqn>
3554 const MFloat wT = getBoundaryTemperature(index);
3556 std::array<MFloat, nDim> uW{};
3557 getBoundaryVelocity(index, uW.data());
3559#ifdef WAR_NVHPC_PSTL
3563 MInt offset = end - begin;
3565 maia::parallelFor<true>(0, offset, [=](
MInt id) {
3567 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
3570 if((globalTimeStep) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
3575 interpolatedBounceBackSingleSpecies(i, uW.data());
3577 interpolatedBounceBackSingleSpeciesThermal(i, wT, uW.data());
3593template <MInt nDim, MInt nDist,
class SysEqn>
3597 std::array<MFloat, nDim> uW{};
3598 getBoundaryVelocity(index, uW.data());
3600 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3601 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3605 const MInt plugFlowDir = (bcMode == 0 && nDim == 3) ? 2 : 0;
3606 const MBool restingFluid = (bcMode == 0 && nDim == 2);
3607 const MInt pCellId = m_bndCells[i].m_cellId;
3612 MFloat k = F2 * M_PI / (m_referenceLength * 2.0);
3615 MFloat dz = m_solver->c_cellLengthAtLevel(m_solver->a_level(m_bndCells[i].m_cellId));
3616 MFloat z = m_solver->a_coordinate(m_bndCells[i].m_cellId, 2) / dz;
3617 z = z - m_referenceLength;
3623 MFloat x = m_solver->a_coordinate(m_bndCells[i].m_cellId, 0);
3624 MFloat y = m_solver->a_coordinate(m_bndCells[i].m_cellId, 1);
3631 interpolatedBounceBackSingleSpeciesThermal(i, wT, uW.data());
3632 }
else if(bcMode == 1) {
3634 MFloat k = F2 * M_PI / (m_referenceLength);
3637 MFloat dx = m_solver->c_cellLengthAtLevel(m_solver->a_level(m_bndCells[i].m_cellId));
3638 MFloat x = m_solver->a_coordinate(m_bndCells[i].m_cellId, 0) / dx;
3645 interpolatedBounceBackSingleSpeciesThermal(i, wT, uW.data());
3646 }
else if(bcMode == 2) {
3648 MFloat k = F2 * M_PI / m_referenceLength;
3650 MFloat dx = m_solver->c_cellLengthAtLevel(m_solver->a_level(m_bndCells[i].m_cellId));
3651 MFloat x = m_solver->a_coordinate(m_bndCells[i].m_cellId, 0) / dx;
3655 MFloat wq = (m_solver->m_kappa / m_referenceLength) *
cos(k * x);
3659 ASSERT(nDim == 2,
"Not implemented for 3D channels yet.");
3660 interpolatedBounceBackSingleSpeciesThermalFlux(i, wq, index);
3666 for(
MInt d = 0; d < nDim; d++)
3669 if(!restingFluid) l_uu[plugFlowDir] = m_Ma * LBCS;
3671 MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
3672 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
3674 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
3675 for(
MInt n = 0; n < nDim; n++)
3676 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
3700template <MInt nDim, MInt nDist,
class SysEqn>
3704 std::array<MFloat, nDim> uW{};
3705 getBoundaryVelocity(index, uW.data());
3708 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3709 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
3717 calculateWallInterface(i, Cw, Tw);
3723 if(!m_mucosaModel.plugFlow) {
3725 interpolatedBounceBackSingleSpecies(i, uW.data());
3728 const MInt pCellId = m_bndCells[i].m_cellId;
3730 MFloat l_uu[nDim] = {0.0};
3731 if(nDim == 3) l_uu[2] = m_Ma * LBCS;
3732 MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
3733 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
3735 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
3736 for(
MInt n = 0; n < nDim; n++)
3737 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
3740 interpolatedBounceBackSingleSpeciesTransport(i, Cw, uW.data());
3741 interpolatedBounceBackSingleSpeciesThermal(i, Tw, uW.data());
3757template <MInt nDim, MInt nDist,
class SysEqn>
3767 m_mucosaModel.plugFlow = Context::getSolverProperty<MInt>(
"plugFlow", m_solverId, AT_);
3777 MInt segmentId = Context::getSolverProperty<MInt>(
"charSegId", m_solverId, AT_);
3781 MFloat** bndVs = m_solver->m_geometry->GetBoundaryVertices(segmentId,
nullptr,
nullptr, 0, &num);
3784 MFloat circ = m_solver->m_geometry->calcCircumference(bndVs, num);
3787 MFloat size = m_solver->m_geometry->GetBoundarySize(segmentId);
3790 MFloat tracheaDiameter = 4 * size / circ;
3794 m_mucosaModel.refDx = tracheaDiameter / m_referenceLength;
3803 MFloat conductivity = 0.025;
3804 conductivity = Context::getSolverProperty<MFloat>(
"conductivity", m_solverId, AT_, &conductivity);
3814 density = Context::getSolverProperty<MFloat>(
"density", m_solverId, AT_, &density);
3823 MFloat viscosity = 16.45 * 1e-6;
3824 viscosity = Context::getSolverProperty<MFloat>(
"viscosity", m_solverId, AT_, &viscosity);
3834 mucosaCond = Context::getSolverProperty<MFloat>(
"mucosaCond", m_solverId, AT_, &mucosaCond);
3843 MFloat organSideTemp = 37.0;
3844 organSideTemp = Context::getSolverProperty<MFloat>(
"organSideTemp", m_solverId, AT_, &organSideTemp);
3853 MFloat mucosaThickness = 0.001;
3854 mucosaThickness = Context::getSolverProperty<MFloat>(
"mucosaThickness", m_solverId, AT_, &mucosaThickness);
3863 MFloat mucosaDiff = 2.6 * 1e-5;
3864 mucosaDiff = Context::getSolverProperty<MFloat>(
"mucosaDiffusivity", m_solverId, AT_, &mucosaDiff);
3873 MFloat bndryDiff = 3.0 * 1e-5;
3874 bndryDiff = Context::getSolverProperty<MFloat>(
"bndryDiffusivity", m_solverId, AT_, &bndryDiff);
3877 MFloat refU = (m_solver->m_Re * viscosity) / tracheaDiameter;
3880 m_mucosaModel.refT = organSideTemp;
3884 MFloat T = m_mucosaModel.refT;
3885 MFloat refWaterFrac = (2.027 + 0.6036 * T - 0.010972 * T * T + 0.0006312 * T * T * T) * 1e-3;
3888 m_mucosaModel.refC = refWaterFrac * density;
3891 m_mucosaModel.refDiff = (refU * m_mucosaModel.refDx) / (m_Ma * LBCS);
3894 m_mucosaModel.refCondF = conductivity;
3897 MFloat organSideConc = m_mucosaModel.refC;
3900 m_mucosaModel.mucosaThickness = mucosaThickness / m_mucosaModel.refDx;
3901 m_mucosaModel.T_o = organSideTemp / m_mucosaModel.refT;
3902 m_mucosaModel.C_o = organSideConc / m_mucosaModel.refC;
3903 m_mucosaModel.condRatio = mucosaCond / conductivity;
3904 m_mucosaModel.diffRatio = mucosaDiff / bndryDiff;
3907 mAlloc(m_oldWallTemp, m_solver->a_noCells(), nDist,
"oldWallTemp", m_mucosaModel.T_o, AT_);
3913 mAlloc(m_mucousDist, m_solver->a_noCells(), nDist,
"mucousDist", -1.0, AT_);
3914 mAlloc(m_fluidDist, m_solver->a_noCells(), nDist,
"fluidDist", -1.0, AT_);
3915 calculateSublayerDistances(index);
3927template <MInt nDim, MInt nDist,
class SysEqn>
3931 ibbBndIds.push_back(index);
3936 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
3937 const MInt bndCellId = i;
3938 const MInt pCellId = m_bndCells[bndCellId].m_cellId;
3940 if(m_bndCells[bndCellId].m_isFluid) {
3941 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
3942 noMissDist(pCellId) = -1;
3945 for(
MInt j = 0; j < nDist - 1; j++) {
3946 const MInt opposite = Ld::oppositeDist(j);
3947 if(m_bndCells[bndCellId].m_distances[j] <= 0.5 && m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
3948 MInt neighborId = m_solver->c_neighborId(pCellId, opposite);
3949 MInt nbndid = m_solver->a_bndId(neighborId);
3950 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) noMissDist(pCellId) = noMissDist(pCellId) + 1;
3956 for(
MInt j = 0; j < nDist - 1; j++) {
3957 if(m_solver->a_hasNeighbor(pCellId, j) && m_bndCells[bndCellId].m_distances[j] < 0.5) {
3958 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
3959 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
3960 if(m_bndCells[bndCellId].m_distances[j] < 0.5) {
3961 MInt nbndid = m_solver->a_bndId(neighborId);
3962 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
3963 if(m_solver->a_hasNeighbor(neighborId, j)) {
3964 const MInt neighbor2Id = m_solver->c_neighborId(neighborId, j);
3965 MInt n2bndid = m_solver->a_bndId(neighbor2Id);
3966 if(n2bndid == -1 || m_bndCells[n2bndid].m_isFluid)
3967 noMissDist(neighborId) = noMissDist(neighborId) + 1;
3977 for(
MInt i = 0; i < m_solver->a_noCells(); i++) {
3979 noMissDistBnd.push_back(
no);
3993template <MInt nDim, MInt nDist,
class SysEqn>
3997 MFloat F2q, rhoF, uF[nDim], uBF[nDim], tmpUF, tmpUBF, tmp2UF,
b[2 * nDim], tmpUW, c[2 * nDim];
3999 getBoundaryVelocity(index, uW);
4005 for(
MInt d = 0; d < nDim; d++) {
4007 c[2 * d + 1] = uW[d];
4010 const MFloat wT = getBoundaryTemperature(index);
4013 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
4015 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
4019 id = m_bndCells[i].m_cellId;
4021 m_omega = 2.0 / (1.0 + 6.0 * m_solver->a_nu(
id) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(
id)));
4032 if(m_bndCells[i].m_isFluid) {
4033 if(m_densityFluctuations)
4034 rhoF = 1.0 + m_solver->a_variable(
id, PV->RHO);
4036 rhoF = m_solver->a_variable(
id, PV->RHO);
4038 for(
MInt n = 0; n < nDim; n++) {
4039 uF[n] = m_solver->a_variable(
id, PV->VV[n]);
4041 b[2 * n + 1] = uF[n];
4044 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
4046 for(
MInt j = 0; j < nDist - 1; j++) {
4053 k = j - Ld::distFld(0);
4054 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
4055 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
4058 k = j - (Ld::distFld(0) + Ld::distFld(1));
4059 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
4060 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
4069 if(m_bndCells[i].m_distances[j] < 0.5) {
4070 F2q = F2 * m_bndCells[i].m_distances[j];
4072 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(j)) > 0) {
4073 nghbrId = m_solver->c_neighborId(
id, Ld::oppositeDist(j));
4076 for(
MInt n = 0; n < nDim; n++) {
4077 uBF[n] = m_solver->a_variable(nghbrId, PV->VV[n]);
4078 tmpUBF += (Ld::idFld(j, n) - 1) * uBF[n];
4084 fEq = Ld::tp(tpIndex) * rhoF
4085 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
4086 xi = m_omega * (F2q - 1.0) / (1.0 - 2.0 * m_omega);
4090 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) =
4091 (1.0 - xi) * m_solver->a_distribution(
id, j) + xi * fEq
4092 - 2.0 * Ld::tp(tpIndex) * rhoF * F1BCSsq * tmpUW;
4099 if(m_solver->a_hasNeighbor(
id, j) == 0) {
4100 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) = m_solver->a_distribution(
id, j);
4116 for(
MInt j = 0; j < nDist - 1; j++) {
4120 if(m_solver->a_hasNeighbor(
id, j) > 0 && !m_solver->a_isHalo(m_solver->c_neighborId(
id, j))) {
4121 if(m_bndCells[i].m_distances[j] <= 0.5) {
4122 F2q = F2 - F2 * m_bndCells[i].m_distances[j];
4124 nghbrId = m_solver->c_neighborId(
id, j);
4126 if(m_densityFluctuations)
4127 rhoF = 1.0 + m_solver->a_variable(nghbrId, PV->RHO);
4129 rhoF = m_solver->a_variable(nghbrId, PV->RHO);
4131 for(
MInt n = 0; n < nDim; n++) {
4132 uF[n] = m_solver->a_variable(nghbrId, PV->VV[n]);
4134 b[2 * n + 1] = uF[n];
4137 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
4140 tmpUF =
b[Ld::oppositeDist(j)];
4141 tmpUW = c[Ld::oppositeDist(j)];
4145 k = Ld::oppositeDist(j) - Ld::distFld(0);
4146 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
4147 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
4150 k = Ld::oppositeDist(j) - (Ld::distFld(0) + Ld::distFld(1));
4151 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
4152 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
4158 for(
MInt dim = 0; dim < nDim; dim++) {
4159 uBF[dim] = (1.0 - 3.0 / F2q) * uF[dim] + (3.0 / F2q) * uW[dim];
4160 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
4163 fEq = Ld::tp(tpIndex) * rhoF
4164 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
4165 xi = m_omega * (F2q - 1.0) / (1 + 0.5 * m_omega);
4169 m_solver->a_oldDistribution(nghbrId, j) =
4170 (1.0 - xi) * m_solver->a_distribution(nghbrId, Ld::oppositeDist(j)) + xi * fEq
4171 - 2.0 * Ld::tp(tpIndex) * rhoF * F1BCSsq * tmpUW;
4177 calculateEqDistsWallSingleSpecies(
id);
4180 interpolatedBounceBackSingleSpeciesThermal(i, wT, uW);
4194template <MInt nDim, MInt nDist,
class SysEqn>
4198 MInt currentId, neighborId1, neighborId2;
4202 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
4204 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
4208 currentId = m_bndCells[i].m_cellId;
4211 if(m_exDirs[index][0] >= 0 && m_solver->a_hasNeighbor(currentId, m_exDirs[ind][0]) > 0) {
4212 neighborId1 = m_solver->c_neighborId(currentId, m_exDirs[ind][0]);
4213 if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(currentId, m_exDirs[ind][1]) > 0) {
4214 neighborId2 = m_solver->c_neighborId(currentId, m_exDirs[ind][1]);
4215 for(
MInt j = 0; j < nDist - 1; j++) {
4216 m_solver->a_oldDistribution(currentId, j) =
4217 m_exWeights[ind][0] * m_solver->a_oldDistribution(neighborId1, j)
4218 + m_exWeights[ind][1] * m_solver->a_oldDistribution(neighborId2, j);
4221 for(
MInt j = 0; j < nDist - 1; j++) {
4222 m_solver->a_oldDistribution(currentId, j) = m_solver->a_oldDistribution(neighborId1, j);
4226 if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(currentId, m_exDirs[ind][1]) > 0) {
4227 neighborId2 = m_solver->c_neighborId(currentId, m_exDirs[ind][1]);
4228 for(
MInt j = 0; j < nDist - 1; j++) {
4229 m_solver->a_oldDistribution(currentId, j) = m_solver->a_oldDistribution(neighborId2, j);
4247template <MInt nDim, MInt nDist,
class SysEqn>
4249 const MFloat*
const uW) {
4252 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4253 MFloat l_rho = m_solver->a_variable(pCellId, PV->RHO);
4256 if(m_bndCells[cellId].m_isFluid) {
4257 for(
MInt j = 0; j < nDist - 1; j++) {
4259 if(m_bndCells[cellId].m_distances[j] < 1.0) {
4260#ifdef WAR_NVHPC_PSTL
4261 const MInt opposite = m_solver->m_oppositeDist[j];
4263 const MInt opposite = Ld::oppositeDist(j);
4265 if(m_bndCells[cellId].m_distances[opposite] < 1.0) {
4268 m_solver->a_oldDistribution(pCellId, opposite) =
4269 m_solver->a_distribution(pCellId, j) + firstMomentSourceTerm(uW, l_rho, opposite);
4271 if(m_bndCells[cellId].m_distances[j] <= 0.5) {
4278 const MFloat F2q = F2 * m_bndCells[
cellId].m_distances[j];
4279 m_solver->a_oldDistribution(pCellId, opposite) = F2q * m_solver->a_distribution(pCellId, j)
4280 + (F1 - F2q) * m_solver->a_oldDistribution(pCellId, j)
4281 + firstMomentSourceTerm(uW, l_rho, opposite);
4285 const MFloat F2q = F2 * m_bndCells[
cellId].m_distances[j];
4286 m_solver->a_oldDistribution(pCellId, opposite) =
4287 (m_solver->a_distribution(pCellId, j) / F2q)
4288 + (m_solver->a_distribution(pCellId, opposite) * (F2q - F1) / F2q)
4289 + firstMomentSourceTerm(uW, l_rho, opposite);
4298 for(
MInt j = 0; j < nDist - 1; j++) {
4300 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4302 if(m_solver->a_hasNeighbor(pCellId, j)) {
4303 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
4304 if(!m_solver->a_isHalo(neighborId) && m_solver->a_isActive(neighborId)) {
4305 l_rho = m_solver->a_variable(neighborId, PV->RHO);
4306#ifdef WAR_NVHPC_PSTL
4307 const MInt opposite = m_solver->m_oppositeDist[j];
4309 const MInt opposite = Ld::oppositeDist(j);
4311 const MFloat F2q = F2 * (F1 - m_bndCells[
cellId].m_distances[j]);
4312 m_solver->a_oldDistribution(neighborId, j) = (m_solver->a_distribution(neighborId, opposite) / F2q)
4313 + (m_solver->a_distribution(neighborId, j) * (F2q - F1) / F2q)
4314 + (F1 / F2q) * firstMomentSourceTerm(uW, l_rho, j);
4322 m_solver->setEqDists(pCellId, 1.0, uW);
4323 for(
MInt d = 0; d < nDim; d++) {
4324 m_solver->a_variable(pCellId, d) = uW[d];
4325 m_solver->a_oldVariable(pCellId, d) = uW[d];
4327 m_solver->a_variable(pCellId, nDim) = F1;
4328 m_solver->a_oldVariable(pCellId, nDim) = F1;
4343template <MInt nDim, MInt nDist,
class SysEqn>
4345 const MFloat*
const wTPtr,
4346 const MFloat*
const uW) {
4349 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4351 std::array<
MBool, nDist - 1> ibb{};
4355 if(m_bndCells[cellId].m_isFluid) {
4356 for(
MInt j = 0; j < nDist - 1; j++) {
4357#ifdef WAR_NVHPC_PSTL
4358 const MInt opposite = m_solver->m_oppositeDist[j];
4360 const MInt opposite = Ld::oppositeDist(j);
4363 if(m_solver->m_innerEnergy) {
4364 s = zerothMomentSourceTerm<1>(pCellId, opposite, wTPtr[j], uW);
4365 }
else if(m_solver->m_totalEnergy) {
4366 s = zerothMomentSourceTerm<2>(pCellId, opposite, wTPtr[j], uW);
4368 s = zerothMomentSourceTerm<0>(pCellId, opposite, wTPtr[j], uW);
4370 const MFloat sourceTerm = s;
4372 if(m_bndCells[cellId].m_distances[j] <= 0.5) {
4373 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
4375 m_solver->a_oldDistributionThermal(pCellId, opposite) =
4376 (-F2q * m_solver->a_distributionThermal(pCellId, j))
4377 + ((F2q - F1) * m_solver->a_oldDistributionThermal(pCellId, j)) + sourceTerm;
4383 m_solver->a_oldDistributionThermal(pCellId, opposite) = m_solver->a_distributionThermal(pCellId, j);
4388 else if(m_bndCells[cellId].m_distances[j] > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0)
4389 m_solver->a_oldDistributionThermal(pCellId, opposite) = m_solver->a_distributionThermal(pCellId, j);
4394 for(
MInt j = 0; j < nDist - 1; j++) {
4395#ifdef WAR_NVHPC_PSTL
4396 const MInt opposite = m_solver->m_oppositeDist[j];
4398 const MInt opposite = Ld::oppositeDist(j);
4401 if(m_solver->a_hasNeighbor(pCellId, j)) {
4403 MInt neighborId = m_solver->c_neighborId(pCellId, j);
4406 if(m_solver->m_innerEnergy) {
4407 s = zerothMomentSourceTerm<1>(neighborId, j, wTPtr[j], uW);
4408 }
else if(m_solver->m_totalEnergy) {
4409 s = zerothMomentSourceTerm<2>(neighborId, j, wTPtr[j], uW);
4411 s = zerothMomentSourceTerm<0>(neighborId, j, wTPtr[j], uW);
4413 const MFloat sourceTerm = s;
4415 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4418 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
4419 MInt nbndid = m_solver->a_bndId(neighborId);
4422 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4423 MFloat F2q = F2 * (F1 - m_bndCells[
cellId].m_distances[j]);
4426 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
4427 m_solver->a_oldDistributionThermal(neighborId, j) =
4428 -(m_solver->a_distributionThermal(neighborId, opposite) / F2q)
4429 + (m_solver->a_distributionThermal(neighborId, j) * (F2q - F1) / F2q) + sourceTerm / F2q;
4440 for(
MInt j = 0; j < nDist - 1; j++) {
4451 m_solver->setEqDistsThermal(pCellId, wTMean, F1, uW);
4452 m_solver->a_variable(pCellId, PV->T) = wTMean;
4453 m_solver->a_oldVariable(pCellId, PV->T) = wTMean;
4467template <MInt nDim, MInt nDist,
class SysEqn>
4469 const MFloat*
const wCPtr,
4470 const MFloat*
const uW) {
4473 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4475 std::array<
MBool, nDist - 1> ibb{};
4479 if(m_bndCells[cellId].m_isFluid) {
4480 for(
MInt j = 0; j < nDist - 1; j++) {
4481#ifdef WAR_NVHPC_PSTL
4482 const MInt opposite = m_solver->m_oppositeDist[j];
4484 const MInt opposite = Ld::oppositeDist(j);
4486 const MFloat sourceTerm = zerothMomentSourceTerm<0>(pCellId, opposite, wCPtr[j], uW);
4488 if(m_bndCells[cellId].m_distances[j] <= 0.5) {
4489 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
4491 m_solver->a_oldDistributionTransport(pCellId, opposite) =
4492 (-F2q * m_solver->a_distributionTransport(pCellId, j))
4493 + ((F2q - F1) * m_solver->a_oldDistributionTransport(pCellId, j)) + sourceTerm;
4499 m_solver->a_oldDistributionTransport(pCellId, opposite) = m_solver->a_distributionTransport(pCellId, j);
4504 else if(m_bndCells[cellId].m_distances[j] > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0)
4505 m_solver->a_oldDistributionTransport(pCellId, opposite) = m_solver->a_distributionTransport(pCellId, j);
4510 for(
MInt j = 0; j < nDist - 1; j++) {
4511#ifdef WAR_NVHPC_PSTL
4512 const MInt opposite = m_solver->m_oppositeDist[j];
4514 const MInt opposite = Ld::oppositeDist(j);
4516 const MFloat sourceTerm = zerothMomentSourceTerm<0>(cellId, j, wCPtr[j], uW);
4518 if(m_solver->a_hasNeighbor(pCellId, j)) {
4520 MInt neighborId = m_solver->c_neighborId(pCellId, j);
4521 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4524 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
4525 MInt nbndid = m_solver->a_bndId(neighborId);
4528 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4529 MFloat F2q = F2 * (F1 - m_bndCells[
cellId].m_distances[j]);
4532 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
4533 m_solver->a_oldDistributionTransport(neighborId, j) =
4534 -(m_solver->a_distributionTransport(neighborId, opposite) / F2q)
4535 + (m_solver->a_distributionTransport(neighborId, j) * (F2q - F1) / F2q) + sourceTerm / F2q;
4546 for(
MInt j = 0; j < nDist - 1; j++) {
4557 m_solver->setEqDistsTransport(pCellId, wCMean, uW);
4558 m_solver->a_variable(pCellId, nDim + 2) = wCMean;
4559 m_solver->a_oldVariable(pCellId, nDim + 2) = wCMean;
4579template <MInt nDim, MInt nDist,
class SysEqn>
4586 const MFloat rho = m_solver->a_variable(pCellId, PV->RHO);
4588#ifdef WAR_NVHPC_PSTL
4590 const MFloat weight = m_solver->m_tp[m_solver->m_distType[
dist]];
4593 for(
MInt d = 0; d < nDim; d++) {
4594 sP += m_solver->m_ppdfDir[
dist * nDim + d] * uW[d];
4595 sV += uW[d] * uW[d];
4597 const MFloat tmp = sP * sP * F1B2mulF1BCSsq * F1BCSsq;
4598 IF_CONSTEXPR(mode == 0) { sourceTerm = F2 * weight * var * (F1 + tmp - sV * F1B2mulF1BCSsq); }
4599 IF_CONSTEXPR(mode == 1) { sourceTerm = weight * var * D * rho * (
distType + tmp - sV * F1B2mulF1BCSsq); }
4600 IF_CONSTEXPR(mode == 2) {
4601 const MFloat E = D * var * F1B2;
4602 sourceTerm = F2 * weight * rho
4603 * (tmp - sV + F1B2 * (
distType - D * CSsq) + E * (F1 + tmp * F1B2mulF1BCSsq - sV * F1B2mulF1BCSsq));
4606 const MFloat weight = Ld::tp(Ld::distType(
dist));
4608 const MFloat sP = std::inner_product(uW, uW + nDim, lbDescriptor::ppdfDir<nDim>[
dist], .0);
4609 const MFloat sV = std::inner_product(uW, uW + nDim, uW, .0);
4610 const MFloat tmp = sP * sP * F1B2mulF1BCSsq * F1BCSsq;
4611 IF_CONSTEXPR(mode == 0) { sourceTerm = F2 * weight * var * (F1 + tmp - sV * F1B2mulF1BCSsq); }
4612 IF_CONSTEXPR(mode == 1) { sourceTerm = weight * var * D * rho * (
distType + tmp - sV * F1B2mulF1BCSsq); }
4613 IF_CONSTEXPR(mode == 2) {
4614 const MFloat E = D * var * F1B2;
4615 sourceTerm = F2 * weight * rho
4616 * (tmp - sV + F1B2 * (
distType - D * CSsq) + E * (F1 + tmp * F1B2mulF1BCSsq - sV * F1B2mulF1BCSsq));
4634template <MInt nDim, MInt nDist,
class SysEqn>
4639 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4640 const MFloat l_dt =
FPOW2(m_solver->maxLevel() - m_solver->a_level(pCellId));
4641 const MFloat LB_dx = 1.0;
4642 const MInt noCells = m_solver->a_noCells();
4644 MInt noMissDist = 0;
4648 if(m_bndCells[cellId].m_isFluid) {
4651 for(
MInt n = 0; n < (
MInt)ibbBndIds.size(); n++) {
4652 if(ibbBndIds.at(n) == bcIndex) {
4657 noMissDist = noMissDistBnd.at(bndId * noCells + pCellId);
4658 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
4660 else if(noMissDist == 0) {
4661 std::cout <<
"ERROR this should not happen!" << std::endl;
4663 const MFloat splittingFactor = 1.0 / (1.0 * noMissDist);
4664 MFloat fluxInDistDir = splittingFactor * l_q;
4667 for(
MInt j = 0; j < nDist - 1; j++) {
4668 const MInt opposite = Ld::oppositeDist(j);
4670 if(m_bndCells[cellId].m_distances[j] <= 0.5) {
4672 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
4673 MInt neighborId = m_solver->c_neighborId(pCellId, opposite);
4674 MInt nbndid = m_solver->a_bndId(neighborId);
4677 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
4678 MFloat FFq = F2 * m_bndCells[
cellId].m_distances[j] + F1;
4679 MFloat Fq = F2 * m_bndCells[
cellId].m_distances[j] - F1;
4680 m_solver->a_oldDistributionThermal(pCellId, opposite) =
4681 m_solver->a_distributionThermal(pCellId, j)
4682 - (Fq / FFq) * m_solver->a_distributionThermal(neighborId, j)
4683 + (Fq / FFq) * m_solver->a_distributionThermal(pCellId, opposite)
4684 + (F2 / FFq) * (l_dt / LB_dx) * fluxInDistDir;
4688 m_solver->a_oldDistributionThermal(pCellId, opposite) = m_solver->a_distributionThermal(pCellId, j);
4694 m_solver->a_oldDistributionThermal(pCellId, opposite) = m_solver->a_distributionThermal(pCellId, j);
4698 else if(m_bndCells[cellId].m_distances[j] > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
4699 m_solver->a_oldDistributionThermal(pCellId, opposite) = m_solver->a_distributionThermal(pCellId, j);
4706 for(
MInt j = 0; j < nDist - 1; j++) {
4707 const MInt opposite = Ld::oppositeDist(j);
4710 if(m_solver->a_hasNeighbor(pCellId, j)) {
4712 MInt neighborId = m_solver->c_neighborId(pCellId, j);
4713 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
4714 MInt nbndid = m_solver->a_bndId(neighborId);
4716 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4720 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
4722 if(m_solver->a_hasNeighbor(neighborId, j)) {
4723 MInt neighbor2Id = m_solver->c_neighborId(neighborId, j);
4724 MInt n2bndid = m_solver->a_bndId(neighbor2Id);
4726 if(n2bndid == -1 || m_bndCells[n2bndid].m_isFluid) {
4731 for(
MInt n = 0; n < (
MInt)ibbBndIds.size(); n++) {
4732 if(ibbBndIds.at(n) == bcIndex) {
4737 noMissDist = noMissDistBnd.at(bndId * noCells + neighborId);
4738 if(noMissDist == 0) {
4739 std::cout <<
"ERROR this should not happen!" << std::endl;
4741 MFloat splittingFactor = 1.0 / (1.0 * noMissDist);
4742 MFloat fluxInDistDir = splittingFactor * l_q;
4745 MFloat FFq = F2 * nei_q + F1;
4746 MFloat Fq = F2 * nei_q - F1;
4747 m_solver->a_oldDistributionThermal(neighborId, j) =
4748 m_solver->a_distributionThermal(neighborId, opposite)
4749 - (Fq / FFq) * m_solver->a_distributionThermal(neighbor2Id, opposite)
4750 + (Fq / FFq) * m_solver->a_distributionThermal(neighborId, j)
4751 + (F2 / FFq) * (l_dt / LB_dx) * fluxInDistDir;
4755 m_solver->a_oldDistributionThermal(neighborId, j) =
4756 m_solver->a_distributionThermal(neighborId, opposite);
4761 m_solver->a_oldDistributionThermal(neighborId, j) =
4762 m_solver->a_distributionThermal(neighborId, opposite);
4772 std::vector<MFloat> wallTemp;
4773 for(
MInt j = 0; j < nDist - 1; j++) {
4774 if(m_bndCells[cellId].m_distances[j] < 0.5) {
4775 if(m_solver->a_hasNeighbor(pCellId, j)) {
4776 MFloat temp = m_solver->a_variable(m_solver->c_neighborId(pCellId, j), PV->T);
4777 wallTemp.push_back(temp);
4781 const MInt noCuts = (
MInt)wallTemp.size();
4783 for(
MInt n = 0; n < (signed)wallTemp.size(); n++) {
4784 sumTemp += wallTemp.at(n);
4787 calculateEqDistsWallSingleSpeciesThermal(pCellId, wT);
4799template <MInt nDim, MInt nDist,
class SysEqn>
4804 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4806 for(
MInt j = 0; j < nDist - 1; j++) {
4807 const MInt opposite = Ld::oppositeDist(j);
4809 if(m_bndCells[cellId].m_isFluid) {
4810 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
4811 if(m_bndCells[cellId].m_distances[j] > 0.5) {
4814 if(m_solver->a_hasNeighbor(pCellId, opposite) == 0)
continue;
4817 if(!m_solver->a_hasNeighbor(pCellId, j)) {
4820 if(m_bndCells[cellId].m_distances[j] > 0.5) {
4823 MInt nbndid = m_solver->a_bndId(m_solver->c_neighborId(pCellId, j));
4824 if(!(nbndid == -1 || m_bndCells[nbndid].m_isFluid))
continue;
4832 MFloat wallNormal[nDim] = {F0};
4835 for(
MInt d = 0; d < nDim; d++)
4836 lDir += Ld::ppdfDir(j, d) * Ld::ppdfDir(j, d);
4839 if(m_bndCells[cellId].m_isFluid) {
4840 dist2Wall = m_bndCells[
cellId].m_distances[j] * lDir;
4842 dist2Wall = (1.0 - m_bndCells[
cellId].m_distances[j]) * lDir;
4845 if(m_calcSublayerDist) {
4846 MFloat**
const v = m_solver->m_geometry->elements[m_distIntersectionElementId[pCellId][j]].m_vertices;
4850 for(
MInt dim = 0; dim < nDim; dim++)
4851 edge[dim] = v[0][dim] - v[1][dim];
4852 wallNormal[0] = edge[1];
4853 wallNormal[1] = -edge[0];
4854 }
else if(nDim == 3) {
4855 for(
MInt dim = 0; dim < nDim; dim++) {
4856 edge[dim] = v[0][dim] - v[1][dim];
4857 edge2[dim] = v[0][dim] - v[2][dim];
4859 wallNormal[0] = edge[1] * edge2[2] - edge[2] * edge2[1];
4860 wallNormal[1] = edge[2] * edge2[0] - edge[0] * edge2[2];
4861 wallNormal[2] = edge[0] * edge2[1] - edge[1] * edge2[0];
4866 MFloat bounceBackDir[nDim];
4867 for(
MInt d = 0; d < nDim; d++) {
4868 bounceBackDir[d] = Ld::ppdfDir(j, d);
4875 for(
MInt d = 0; d < nDim; d++) {
4876 dp += bounceBackDir[d] * wallNormal[d];
4877 lv += wallNormal[d] * wallNormal[d];
4878 lb += bounceBackDir[d] * bounceBackDir[d];
4885 for(
MInt d = 0; d < nDim; d++) {
4886 wallNormal[d] = -wallNormal[d];
4892 if(
approx(lv, 0.0, MFloatEps))
continue;
4895 MFloat phi = acos(dp / (lv * lb));
4898 m_mucousDist[pCellId][j] = m_mucosaModel.mucosaThickness /
cos(phi);
4899 m_fluidDist[pCellId][j] = dist2Wall;
4913template <MInt nDim, MInt nDist,
class SysEqn>
4916 const MInt pCellId = m_bndCells[
cellId].m_cellId;
4917 MInt fluidCellId = pCellId;
4919 for(
MInt j = 0; j < nDist - 1; j++) {
4920 const MInt opposite = Ld::oppositeDist(j);
4922 if(m_bndCells[cellId].m_isFluid) {
4923 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
4924 if(m_bndCells[cellId].m_distances[j] > 0.5) {
4927 if(!m_solver->a_hasNeighbor(pCellId, opposite))
continue;
4930 if(!m_solver->a_hasNeighbor(pCellId, j)) {
4933 if(m_bndCells[cellId].m_distances[j] > 0.5) {
4936 MInt nbndid = m_solver->a_bndId(m_solver->c_neighborId(pCellId, j));
4937 if(!(nbndid == -1 || m_bndCells[nbndid].m_isFluid)) {
4940 fluidCellId = m_solver->c_neighborId(pCellId, j);
4951 MFloat d_Cf = m_solver->a_variable(fluidCellId, PV->C) * m_mucosaModel.refC;
4952 MFloat d_C_o = m_mucosaModel.C_o * m_mucosaModel.refC;
4953 MFloat fD_mD = m_fluidDist[pCellId][j] / m_mucousDist[pCellId][j];
4955 MFloat d_Cw = (d_Cf + m_mucosaModel.diffRatio * fD_mD * d_C_o) / (1.0 + m_mucosaModel.diffRatio * fD_mD);
4956 wallConc[j] = d_Cw / m_mucosaModel.refC;
4962 MFloat d_latentSourceTerm = F0;
4965 MFloat Tw_old = m_oldWallTemp[pCellId][j];
4968 MFloat d_Tw_old = Tw_old * m_mucosaModel.refT;
4969 MFloat d_dist2Wall = m_fluidDist[pCellId][j] * m_mucosaModel.refDx;
4970 MFloat d_diff = m_solver->m_diffusivity * m_mucosaModel.refDiff;
4971 MFloat d_cond_f = m_mucosaModel.refCondF;
4975 MFloat d_h_lh = (2500.8 - 2.3641 * d_Tw_old + 1.5893 * 1e-3 * d_Tw_old * d_Tw_old
4976 - 6.1434 * 1e-6 * d_Tw_old * d_Tw_old * d_Tw_old)
4980 MFloat d_j_flux = (d_Cw - d_Cf) / d_dist2Wall * d_diff;
4983 MFloat d_q_latent = -d_j_flux * d_h_lh;
4985 d_latentSourceTerm = (d_q_latent * d_dist2Wall / d_cond_f) / (1.0 + m_mucosaModel.condRatio * fD_mD);
4994 MFloat d_Tf = m_solver->a_variable(fluidCellId, PV->T) * m_mucosaModel.refT;
4995 MFloat d_T_o = m_mucosaModel.T_o * m_mucosaModel.refT;
4999 (d_Tf + m_mucosaModel.condRatio * fD_mD * d_T_o) / (1.0 + m_mucosaModel.condRatio * fD_mD) + d_latentSourceTerm;
5002 wallTemp[j] = d_Tw / m_mucosaModel.refT;
5006 m_oldWallTemp[pCellId][j] = wallTemp[j];
5022template <MInt nDim, MInt nDist,
class SysEqn>
5027 const MInt pCellId = m_boundaryCellsMb.cellId(cellIndex);
5029 const MFloat rho = m_boundaryCellsMb.density(cellIndex);
5031 std::array<MFloat, nDim> uBoundary{};
5032 getBoundaryVelocityMb(cellIndex, uBoundary.data());
5033 const MFloat squaredVelocity = std::inner_product(uBoundary.begin(), uBoundary.end(), uBoundary.begin(), .0);
5035 std::array<MFloat, nDist> eqDist{};
5036 sysEqn().calcEqDists(rho, squaredVelocity, uBoundary.data(), eqDist.data());
5039 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
5040 for(
MInt j = 0; j < nDist - 1; j++) {
5041 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
5042 const MInt opposite = Ld::oppositeDist(j);
5044 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
5050 if(m_solver->a_hasNeighbor(pCellId, opposite)) {
5051 const MInt neighborId = m_solver->c_neighborId(pCellId, opposite);
5053 const MFloat F2q = F2 * q;
5056 const MFloat quadratic = -Fq * (F2q + 1) * m_solver->a_distribution(pCellId, j)
5057 - (1 + F2q) * (1 - F2q) * m_solver->a_oldDistribution(pCellId, j)
5058 + Fq * (1 - F2q) * m_solver->a_oldDistribution(neighborId, j) + eqDist[j]
5061 m_solver->a_oldDistribution(pCellId, opposite) = quadratic;
5066 m_solver->a_oldDistribution(pCellId, opposite) =
5067 -m_solver->a_distribution(pCellId, j) + eqDist[j] + eqDist[opposite];
5074 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
5075 m_solver->a_oldDistribution(pCellId, opposite) =
5076 -m_solver->a_distribution(pCellId, j) + eqDist[j] + eqDist[opposite];
5082 for(
MInt j = 0; j < nDist - 1; j++) {
5083 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
5085 const MInt opposite = Ld::oppositeDist(j);
5088 if(m_solver->a_hasNeighbor(pCellId, j)) {
5090 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
5094 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
5098 const MFloat F2q = F2 * (F1 - q);
5099 const MFloat Fq = (1 - q);
5102 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
5103 const MInt nneighborId = m_solver->c_neighborId(neighborId, j);
5106 1 / Fq / (F2q + 1) * (-m_solver->a_distribution(neighborId, opposite) + eqDist[j] + eqDist[opposite])
5107 + (F2q - 1) / Fq * m_solver->a_distribution(neighborId, j)
5108 - (F2q - 1) / (F2q + 1) * m_solver->a_distribution(nneighborId, j);
5110 m_solver->a_oldDistribution(neighborId, j) = quadratic;
5119 m_solver->setEqDists(pCellId, 1.0, squaredVelocity, uBoundary.data());
5131template <MInt nDim, MInt nDist,
class SysEqn>
5135 const std::array<MFloat, nDim> vel{0.0};
5138 m_solver->a_variable(pCellId, PV->RHO) = rho;
5139 m_solver->a_oldVariable(pCellId, PV->RHO) = rho;
5140 for(
MInt n = 0; n < nDim; n++) {
5141 m_solver->a_variable(pCellId, n) = vel[n];
5142 m_solver->a_oldVariable(pCellId, n) = vel[n];
5145 m_solver->setEqDists(pCellId, rho, vel.data());
5156template <MInt nDim, MInt nDist,
class SysEqn>
5162 m_solver->a_variable(pCellId, PV->T) = wT;
5163 m_solver->a_oldVariable(pCellId, PV->T) = wT;
5165 constexpr std::array<MFloat, nDim> u{};
5166 m_solver->setEqDistsThermal(pCellId, wT, F1, F0, u.data());
5177template <MInt nDim, MInt nDist,
class SysEqn>
5183 m_solver->a_variable(pCellId, PV->C) = wC;
5184 m_solver->a_oldVariable(pCellId, PV->C) = wC;
5186 constexpr std::array<MFloat, nDim> u{};
5187 m_solver->setEqDistsTransport(pCellId, wC, 0.0, u.data());
5201template <MInt nDim, MInt nDist,
class SysEqn>
5206 if(m_exDirs[index][0] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][0]) > 0) {
5207 MInt neighborId1 = m_solver->c_neighborId(pCellId, m_exDirs[index][0]);
5209 if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][1]) > 0) {
5210 MInt neighborId2 = m_solver->c_neighborId(pCellId, m_exDirs[index][1]);
5215 *p_var = ex0 * m_solver->a_variable(neighborId1, var) + ex1 * m_solver->a_variable(neighborId2, var);
5217 *p_var = m_solver->a_variable(neighborId1, var);
5219 if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][1]) > 0) {
5220 MInt neighborId2 = m_solver->c_neighborId(pCellId, m_exDirs[index][1]);
5221 *p_var = m_solver->a_variable(neighborId2, var);
5237template <MInt nDim, MInt nDist,
class SysEqn>
5241 if(m_exDirs[index][0] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][0]) > 0) {
5242 const MInt neighborId1 = m_solver->c_neighborId(pCellId, m_exDirs[index][0]);
5244 if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][1]) > 0) {
5245 const MInt neighborId2 = m_solver->c_neighborId(pCellId, m_exDirs[index][1]);
5250 for(
MInt n = 0; n < nDim; n++) {
5251 l_uu[n] = ex0 * m_solver->a_variable(neighborId1, n) + ex1 * m_solver->a_variable(neighborId2, n);
5255 for(
MInt n = 0; n < nDim; n++) {
5256 l_uu[n] = m_solver->a_variable(neighborId1, n);
5259 }
else if(m_exDirs[index][1] >= 0 && m_solver->a_hasNeighbor(pCellId, m_exDirs[index][1]) > 0) {
5260 const MInt neighborId2 = m_solver->c_neighborId(pCellId, m_exDirs[index][1]);
5262 for(
MInt n = 0; n < nDim; n++) {
5263 l_uu[n] = m_solver->a_variable(neighborId2, n);
5266#ifndef WAR_NVHPC_PSTL
5267 TERMM(1,
"No value is extrapolated !");
5285template <MInt nDim, MInt nDist,
class SysEqn>
5290 MFloat ma_x_F1BCS = m_Ma * LBCS;
5291 const MInt pvrho = PV->RHO;
5293#ifdef WAR_NVHPC_PSTL
5297 MInt offset = end - begin;
5299 maia::parallelFor<true>(0, offset, [=](
MInt id) {
5301 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
5304 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
5307 LbGridBoundaryCell<nDim>* bndCell = &m_bndCells[i];
5308 const MInt currentId = (*bndCell).m_cellId;
5309 const MInt pCellId = currentId;
5312 MFloat l_uu[nDim] = {0.0};
5315 extrapolateVariable(ind, pCellId, pvrho, &l_rho);
5317 for(
MInt n = 0; n < nDim; n++) {
5318 l_uu[n] = m_initialVelocityVecs[ind][n] * ma_x_F1BCS * (*bndCell).m_multiplier * m_zeroInflowVelocity;
5322 m_solver->setEqDists(pCellId, l_rho, l_uu);
5324 m_solver->a_variable(pCellId, pvrho) = l_rho;
5325 for(
MInt n = 0; n < nDim; n++) {
5326#ifdef WAR_NVHPC_PSTL
5327 m_solver->a_variable(pCellId, n) = l_uu[n];
5329 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
5333 writeBCOutput(index);
5351template <MInt nDim, MInt nDist,
class SysEqn>
5356 MFloat ma_x_F1BCS = m_Ma * LBCS;
5358 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5359 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5363 const MInt pCellId = currentId;
5366 MFloat l_uu[nDim] = {0.0};
5369 extrapolateVariable(ind, pCellId, PV->RHO, &l_rho);
5372 l_rho = (m_solver->a_variable(pCellId, PV->RHO) + l_rho) * F1B2;
5375 for(
MInt n = 0; n < nDim; n++) {
5376 l_uu[n] = m_initialVelocityVecs[ind][n] * ma_x_F1BCS * (*bndCell).m_multiplier * m_zeroInflowVelocity;
5380 m_solver->setEqDists(pCellId, l_rho, l_uu);
5385 IF_CONSTEXPR(nDim == 3) {
5386 for(
MInt n = 0; n < nDim; n++) {
5387 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
5389 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
5411template <MInt nDim, MInt nDist,
class SysEqn>
5416 MFloat rho = 1.0, u[nDim];
5420 MFloat* bBoxPtr = &bBox[0];
5421 m_solver->m_geometry->getBoundingBox(bBoxPtr);
5423 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5424 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5426 MInt currentId = m_bndCells[i].m_cellId;
5428 extrapolateVariable(ind, currentId, PV->RHO, &rho);
5431 tmpWidth = 0.5 * fabs(bBox[nDim + 1] - bBox[1]);
5433 const MFloat relPos = m_solver->a_coordinate(currentId, 1) / tmpWidth;
5435 const MFloat parabola = (1.0 - relPos * relPos);
5438 * ((1.0 - m_solver->m_CouettePoiseuilleRatio) * linear + m_solver->m_CouettePoiseuilleRatio * parabola);
5440 IF_CONSTEXPR(nDim == 3) u[2] = 0.0;
5442 const
MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
5443 m_solver->setEqDists(currentId, rho, squaredVelocity, u);
5455template <
MInt nDim,
MInt nDist, class SysEqn>
5460 MFloat l_uu[nDim] = {F0};
5464 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5465 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5467 currentId = m_bndCells[i].m_cellId;
5469 MFloat nu = m_solver->a_nu(currentId);
5470 m_omega = 2.0 / (1.0 + 6.0 * nu *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)));
5476 rho = m_solver->a_variable(currentId, PV->RHO);
5477 MFloat squaredVelocity = F0;
5478 for(
MInt d = 0; d < nDim; d++) {
5479 l_uu[d] = m_solver->a_variable(currentId, d);
5480 squaredVelocity += l_uu[d] * l_uu[d];
5483 std::array<MFloat, nDist> eDistributions{};
5484 sysEqn().calcEqDists(rho, l_uu, eDistributions.data());
5488 std::array<MFloat, nDist> nePart{};
5489 for(
MInt j = 0; j < 8; j++) {
5490 nePart[j] = m_solver->a_distribution(currentId, j) - eDistributions[j];
5493 for(
MInt n = 0; n < nDim; n++) {
5494 l_uu[n] = m_initialVelocityVecs[ind][n] * m_Ma * F1BCS * m_bndCells[i].m_multiplier * m_zeroInflowVelocity;
5500 std::array<MFloat, nDist> newEqDists{};
5501 sysEqn().calcEqDists(rho, l_uu, newEqDists.data());
5503 for(
MInt j = 0; j < nDist - 1; j++) {
5504 m_solver->a_oldDistribution(currentId, j) = newEqDists[j] + (F1 - m_omega) * nePart[j];
5523template <MInt nDim, MInt nDist,
class SysEqn>
5527 const MInt ind = m_mapSegIdsInOutCnd[
index];
5528 std::array<MFloat, 2 * nDim> bBox{};
5529 m_solver->m_geometry->getBoundingBox(bBox.data());
5530 const MFloat channelHalfHeight = fabs(bBox[nDim + 1] - bBox[1]) * F1B2;
5532 const MFloat exp = F1 + F1 / m_solver->m_n;
5534 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5535 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5537 MInt currentId = m_bndCells[i].m_cellId;
5540 extrapolateVariable(ind, currentId, PV->RHO, &rho);
5542 const MFloat relPos = fabs(m_solver->a_coordinate(currentId, 1) / channelHalfHeight - F1);
5543 const MFloat parabola = F1 - pow(relPos, exp);
5545 std::array<MFloat, nDim> u{m_Ma * LBCS * parabola};
5547 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
5548 m_solver->setEqDists(currentId, rho, squaredVelocity, u.data());
5551 for(
MInt n = 0; n < nDim; n++) {
5552 m_solver->a_variable(currentId, PV->VV[n]) = u[n];
5554 m_solver->a_variable(currentId, PV->RHO) = rho;
5573template <MInt nDim, MInt nDist,
class SysEqn>
5580 std::array<MFloat, 2 * nDim> bBox{};
5581 m_solver->m_geometry->getBoundingBox(bBox.data());
5583 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5584 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5586 MInt currentId = m_bndCells[i].m_cellId;
5589 extrapolateVariable(ind, currentId, PV->RHO, &rho);
5593 const MFloat tmpWidth = fabs(bBox[nDim + 1] - bBox[1]);
5595 const MFloat bottom = bBox[1];
5597 const MFloat relPos = (m_solver->a_coordinate(currentId, 1) - bottom) / tmpWidth;
5598 const MFloat parabola = (relPos - relPos * relPos);
5601 std::array<MFloat, nDim> l_uu{};
5602 l_uu[0] = m_Ma * LBCS
5603 * ((1.0 - m_solver->m_CouettePoiseuilleRatio) * linear + m_solver->m_CouettePoiseuilleRatio * parabola)
5606 IF_CONSTEXPR(nDim == 3) { l_uu[2] = 0.0; }
5610 std::array<MFloat, nDim> u{};
5611 for(
MInt d = 0; d < nDim; d++) {
5612 u[d] = l_uu[d] / rho;
5614 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
5618 m_solver->setEqDists(currentId, rho, squaredVelocity, u.data());
5619 m_solver->setEqDistsThermal(currentId, T, rho, squaredVelocity, u.data());
5621 for(
MInt n = 0; n < nDim; n++) {
5622 m_solver->a_variable(currentId, PV->VV[n]) = l_uu[n];
5624 m_solver->a_variable(currentId, PV->RHO) = rho;
5625 m_solver->a_variable(currentId, PV->T) = T;
5627 writeBCOutput(index);
5635template <MInt nDim, MInt nDist,
class SysEqn>
5639 MFloat F2q, rhoF, uF[nDim], uBF[nDim], tmpUF, tmpUBF, tmp2UF,
b[2 * nDim], tmpUW, c[2 * nDim];
5641 getBoundaryVelocity(index, uW);
5647 for(
MInt d = 0; d < nDim; d++) {
5649 c[2 * d + 1] = uW[d];
5653 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5655 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
5659 id = m_bndCells[i].m_cellId;
5661 m_omega = 2.0 / (1.0 + 6.0 * m_solver->a_nu(
id) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(
id)));
5672 if(m_bndCells[i].m_isFluid) {
5673 if(m_densityFluctuations)
5674 rhoF = 1.0 + m_solver->a_variable(
id, PV->RHO);
5676 rhoF = m_solver->a_variable(
id, PV->RHO);
5678 for(
MInt n = 0; n < nDim; n++) {
5679 uF[n] = m_solver->a_variable(
id, PV->VV[n]);
5681 b[2 * n + 1] = uF[n];
5684 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
5686 for(
MInt j = 0; j < nDist - 1; j++) {
5687 if(j < Ld::distFld(0)) {
5692 if(j < (Ld::distFld(0) + Ld::distFld(1))) {
5693 k = j - Ld::distFld(0);
5694 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
5695 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
5698 k = j - (Ld::distFld(0) + Ld::distFld(1));
5699 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
5700 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
5709 if(m_bndCells[i].m_distances[j] < 0.5) {
5710 F2q = F2 * m_bndCells[i].m_distances[j];
5712 if(m_solver->a_hasNeighbor(
id, Ld::oppositeDist(j)) > 0) {
5713 nghbrId = m_solver->c_neighborId(
id, Ld::oppositeDist(j));
5716 for(
MInt d = 0; d < nDim; d++) {
5717 uBF[d] = m_solver->a_variable(nghbrId, d);
5718 tmpUBF += (Ld::idFld(j, d) - 1) * uBF[d];
5724 fEq = Ld::tp(tpIndex) * rhoF
5725 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
5726 xi = m_omega * (F2q - 1.0) / (1.0 - 2.0 * m_omega);
5730 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) =
5731 (1.0 - xi) * m_solver->a_distribution(
id, j) + xi * fEq
5732 - 2.0 * Ld::tp(tpIndex) * rhoF * F1BCSsq * tmpUW;
5739 if(m_solver->a_hasNeighbor(
id, j) == 0) {
5740 m_solver->a_oldDistribution(
id, Ld::oppositeDist(j)) = m_solver->a_distribution(
id, j);
5756 for(
MInt j = 0; j < nDist - 1; j++) {
5760 if(m_solver->a_hasNeighbor(
id, j) > 0 && !m_solver->a_isHalo(m_solver->c_neighborId(
id, j))) {
5761 if(m_bndCells[i].m_distances[j] <= 0.5) {
5762 F2q = F2 - F2 * m_bndCells[i].m_distances[j];
5764 nghbrId = m_solver->c_neighborId(
id, j);
5766 if(m_densityFluctuations)
5767 rhoF = 1.0 + m_solver->a_variable(nghbrId, PV->RHO);
5769 rhoF = m_solver->a_variable(nghbrId, PV->RHO);
5771 for(
MInt n = 0; n < nDim; n++) {
5772 uF[n] = m_solver->a_variable(nghbrId, PV->VV[n]);
5774 b[2 * n + 1] = uF[n];
5777 tmp2UF = std::inner_product(&uF[0], &uF[nDim], &uF[0], .0);
5779 if(j < Ld::distFld(0)) {
5780 tmpUF =
b[Ld::oppositeDist(j)];
5781 tmpUW = c[Ld::oppositeDist(j)];
5784 if(j < (Ld::distFld(0) + Ld::distFld(1))) {
5785 k = Ld::oppositeDist(j) - Ld::distFld(0);
5786 tmpUF = (
b[Ld::mFld1(2 * k)] +
b[Ld::mFld1(2 * k + 1)]);
5787 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
5790 k = Ld::oppositeDist(j) - (Ld::distFld(0) + Ld::distFld(1));
5791 tmpUF = (
b[Ld::mFld2(3 * k)] +
b[Ld::mFld2(3 * k + 1)] +
b[Ld::mFld2(3 * k + 2)]);
5792 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
5798 for(
MInt dim = 0; dim < nDim; dim++) {
5799 uBF[dim] = (1.0 - 3.0 / F2q) * uF[dim] + (3.0 / F2q) * uW[dim];
5800 tmpUBF += (Ld::idFld(Ld::oppositeDist(j), dim) - 1) * uBF[dim];
5803 fEq = Ld::tp(tpIndex) * rhoF
5804 * (1.0 + tmpUBF * F1BCSsq + tmpUF * tmpUF * F1BCSsq * F1BCSsq * F1B2 - tmp2UF * F1BCSsq * F1B2);
5805 xi = m_omega * (F2q - 1.0) / (1.0 + 0.5 * m_omega);
5809 m_solver->a_oldDistribution(nghbrId, j) =
5810 (1.0 - xi) * m_solver->a_distribution(nghbrId, Ld::oppositeDist(j)) + xi * fEq
5811 - 2.0 * Ld::tp(tpIndex) * rhoF * F1BCSsq * tmpUW;
5816 m_solver->setEqDists(
id, F1, uW);
5819 if(m_calcWallForces) calculateWallForces(index);
5831template <MInt nDim, MInt nDist,
class SysEqn>
5837 std::array<MFloat, nDim> forceWall_;
5838 forceWall_.fill(0.0);
5841 getBoundaryVelocity(index, uW);
5843 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
5844 const MInt pCellId = m_bndCells[i].m_cellId;
5846 if(m_solver->a_level(pCellId) != m_solver->maxLevel())
continue;
5849 if(m_bndCells[i].m_isFluid) {
5850 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
5854 for(
MInt j = 0; j < nDist - 1; j++) {
5855 const MInt opposite = Ld::oppositeDist(j);
5857 MFloat Vin[nDim], Vout[nDim];
5858 for(
MInt d = 0; d < nDim; d++) {
5859 Vin[d] = Ld::ppdfDir(j, d) - uW[d];
5860 Vout[d] = Ld::ppdfDir(opposite, d) - uW[d];
5864 if(m_bndCells[i].m_distances[j] < 1.0) {
5865 if(m_solver->a_hasNeighbor(pCellId, opposite)) {
5866 for(
MInt d = 0; d < nDim; d++) {
5867 forceWall_[d] += m_solver->a_distribution(pCellId, j) * Vin[d]
5868 - m_solver->a_oldDistribution(pCellId, opposite) * Vout[d];
5876 for(
MInt j = 0; j < nDist - 1; j++) {
5878 if(m_solver->a_hasNeighbor(pCellId, j)) {
5880 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
5881 if(m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
5884 const MInt opposite = Ld::oppositeDist(j);
5886 MFloat Vin[nDim], Vout[nDim];
5887 for(
MInt d = 0; d < nDim; d++) {
5888 Vin[d] = Ld::ppdfDir(opposite, d) - uW[d];
5889 Vout[d] = Ld::ppdfDir(j, d) - uW[d];
5893 const MFloat q = m_bndCells[i].m_distances[j];
5896 const MInt nbndid = m_solver->a_bndId(neighborId);
5897 if(nbndid == -1 || m_bndCells[nbndid].m_isFluid) {
5899 for(
MInt d = 0; d < nDim; d++) {
5900 forceWall_[d] += m_solver->a_distribution(neighborId, opposite) * Vin[d]
5901 - m_solver->a_oldDistribution(neighborId, j) * Vout[d];
5910 std::array<MFloat, nDim> forceWall;
5911 forceWall.fill(0.0);
5913 const MInt segId = this->m_mapIndex2BndCndSegId[
index];
5914 const auto& cwfc = this->m_mapWallForceContainer[segId];
5916 if(cwfc.noComm > 1) {
5917 MPI_Reduce(forceWall_.data(), forceWall.data(), nDim, MPI_DOUBLE, MPI_SUM, 0, cwfc.comm, AT_,
"forceWall_",
5920 forceWall = forceWall_;
5925 std::FILE* forceFile;
5926 forceFile = fopen(cwfc.fileName.c_str(),
"a+");
5928 for(
MInt d = 0; d < nDim; d++) {
5929 fprintf(forceFile,
"%15e\t", forceWall[d]);
5931 fprintf(forceFile,
"\n");
5945template <MInt nDim, MInt nDist,
class SysEqn>
5948 ASSERT(set < m_solver->m_maxNoSets,
"ERROR: wrong set is choosen");
5952 std::array<MFloat, nDim> forceWall_;
5953 forceWall_.fill(0.0);
5955 for(
MInt cellIndex = 0; cellIndex < m_boundaryCellsMb.size(); cellIndex++) {
5956 const MInt pCellId = m_boundaryCellsMb.cellId(cellIndex);
5958 getBoundaryVelocityMb(cellIndex, uW);
5961 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
5962 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
5965 for(
MInt j = 0; j < nDist - 1; j++) {
5966 const MInt opposite = Ld::oppositeDist(j);
5968 MFloat Vin[nDim], Vout[nDim];
5969 for(
MInt d = 0; d < nDim; d++) {
5970 Vin[d] = Ld::ppdfDir(j, d) - uW[d];
5971 Vout[d] = Ld::ppdfDir(opposite, d) - uW[d];
5974 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
5977 if(m_solver->a_hasNeighbor(pCellId, opposite)) {
5978 for(
MInt d = 0; d < nDim; d++) {
5979 forceWall_[d] += m_solver->a_distribution(pCellId, j) * Vin[d]
5980 - m_solver->a_oldDistribution(pCellId, opposite) * Vout[d];
5986 for(
MInt j = 0; j < nDist - 1; j++) {
5988 if(m_solver->a_hasNeighbor(pCellId, j)) {
5990 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
5991 if(m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
5994 const MInt opposite = Ld::oppositeDist(j);
5996 MFloat Vin[nDim], Vout[nDim];
5997 for(
MInt d = 0; d < nDim; d++) {
5998 Vin[d] = Ld::ppdfDir(opposite, d) - uW[d];
5999 Vout[d] = Ld::ppdfDir(j, d) - uW[d];
6003 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
6006 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
6007 if((!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0)) {
6009 for(
MInt d = 0; d < nDim; d++) {
6010 forceWall_[d] += m_solver->a_distribution(neighborId, opposite) * Vin[d]
6011 - m_solver->a_oldDistribution(neighborId, j) * Vout[d];
6020 std::array<MFloat, nDim> forceWall;
6021 forceWall.fill(0.0);
6024 MBool isRoot =
true;
6025 if(m_solver->noDomains() > 1) {
6026 MPI_Reduce(forceWall_.data(), forceWall.data(), nDim, MPI_DOUBLE, MPI_SUM, 0, m_BCWallMBComm, AT_,
"forceWall_",
6028 isRoot = m_solver->domainId() == m_BCWallMBNeighbors[0];
6030 forceWall = forceWall_;
6035 std::FILE* forceFile;
6036 forceFile = fopen(m_forceFile.c_str(),
"a+");
6038 for(
MInt d = 0; d < nDim; d++) {
6039 fprintf(forceFile,
"%15e\t", forceWall[d]);
6046 fprintf(forceFile,
"\n");
6065template <MInt nDim, MInt nDist,
class SysEqn>
6069 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6070 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6072 const MInt currentId = m_bndCells[i].m_cellId;
6073 const MInt pCellId = currentId;
6075 const MFloat l_rho = 1.0;
6076 MFloat l_uu[nDim] = {0.0};
6077 l_uu[0] = m_Ma * LBCS;
6079 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
6082 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
6084 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
6085 for(
MInt n = 0; n < nDim; n++) {
6086 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6104template <MInt nDim, MInt nDist,
class SysEqn>
6108 const MInt ind = m_mapSegIdsInOutCnd[
index];
6109 const MFloat ma_x_F1BCS = m_Ma * LBCS;
6110 const MInt pvrho = PV->RHO;
6111 const MInt pvt = PV->T;
6113#ifdef WAR_NVHPC_PSTL
6115 const MInt begin = m_bndCndOffsets[
index];
6116 const MInt end = m_bndCndOffsets[
index + 1];
6117 const MInt offset = end - begin;
6119 maia::parallelFor<true>(0, offset, [=](
MInt id) {
6120 const MInt i = begin +
id;
6121 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
6124 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
6127 LbGridBoundaryCell<nDim>* bndCell = &m_bndCells[i];
6128 MInt currentId = (*bndCell).m_cellId;
6129 const MInt pCellId = currentId;
6134 extrapolateVariable(ind, pCellId, pvrho, &l_rho);
6136 std::array<MFloat, nDim> l_uu{};
6137 for(
MInt n = 0; n < nDim; n++) {
6138 l_uu[n] = m_initialVelocityVecs[ind][n] * ma_x_F1BCS * (*bndCell).m_multiplier * m_zeroInflowVelocity * l_rho;
6143 std::array<MFloat, nDim> u{};
6144 for(
MInt n = 0; n < nDim; n++) {
6145 u[n] = l_uu[n] / l_rho;
6147 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
6150 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, u.data());
6152 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, squaredVelocity, u.data());
6154 for(
MInt n = 0; n < nDim; n++) {
6155 m_solver->a_variable(pCellId, n) = l_uu[n];
6157 m_solver->a_variable(pCellId, pvrho) = l_rho;
6158 m_solver->a_variable(pCellId, pvt) = l_t;
6159#ifdef WAR_NVHPC_PSTL
6164 writeBCOutput(index);
6180template <MInt nDim, MInt nDist,
class SysEqn>
6184 const MInt ind = m_mapSegIdsInOutCnd[
index];
6185 const MInt x_pos = m_solver->m_referenceLength * m_solver->m_blasiusPos;
6186 const MInt pvrho = PV->RHO;
6188 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6189 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6193 const MInt pCellId = currentId;
6196 const MFloat eta = (*bndCell).m_eta;
6197 const MInt pos = (eta / m_blasius_delta);
6202 extrapolateVariable(ind, pCellId, pvrho, &l_rho);
6204 std::array<MFloat, nDim> l_u{};
6205 std::array<MFloat, nDim> u{};
6206 const MFloat l_t = m_solver->m_initTemperatureKelvin - m_blasius[pos][2];
6207 l_u[0] = (m_Ma * LBCS) * m_blasius[pos][2] * l_rho;
6208 IF_CONSTEXPR(nDim == 3) l_u[1] = 0.0 * l_rho;
6210 0.5 * sqrt((m_Ma * LBCS) * m_solver->m_nu / x_pos) * (eta * m_blasius[pos][2] - m_blasius[pos][1]) * l_rho;
6214 for(
MInt n = 0; n < nDim; n++) {
6215 u[n] = l_u[n] / l_rho;
6217 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
6220 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, u.data());
6221 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, squaredVelocity, u.data());
6223 m_solver->a_variable(pCellId, PV->U) = l_u[0];
6224 m_solver->a_variable(pCellId, PV->V) = l_u[1];
6225 IF_CONSTEXPR(nDim == 3) m_solver->a_variable(pCellId, PV->W) = l_u[2];
6226 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
6227 m_solver->a_variable(pCellId, PV->T) = l_t;
6239template <
MInt nDim,
MInt nDist, class SysEqn>
6243 const MInt ind = m_mapSegIdsInOutCnd[
index];
6244 const MFloat ma_x_F1BCS = m_Ma * LBCS;
6246 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6247 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6251 const MInt pCellId = currentId;
6257 extrapolateVariable(ind, pCellId, PV->RHO, &l_rho);
6260 std::array<MFloat, nDim> l_uu{};
6261 std::array<MFloat, nDim> u{};
6262 for(
MInt n = 0; n < nDim; n++) {
6263 l_uu[n] = m_initialVelocityVecs[ind][n] * ma_x_F1BCS * (*bndCell).m_multiplier * m_zeroInflowVelocity * l_rho;
6268 for(
MInt n = 0; n < nDim; n++) {
6269 u[n] = l_uu[n] / l_rho;
6271 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
6274 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, u.data());
6275 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, squaredVelocity, u.data());
6276 m_solver->setEqDistsTransport(pCellId, l_c, squaredVelocity, u.data());
6278 for(
MInt n = 0; n < nDim; n++) {
6279 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6281 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
6282 if(m_solver->m_isThermal) m_solver->a_variable(pCellId, PV->T) = l_t;
6283 m_solver->a_variable(pCellId, PV->C) = l_c;
6285 writeBCOutput(index);
6297template <MInt nDim, MInt nDist,
class SysEqn>
6301 const MInt ind = m_mapSegIdsInOutCnd[
index];
6302 constexpr MFloat rho0 = 1.0;
6303 const MFloat trgRhoU = rho0 * m_Ma * LBCS;
6305 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6306 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6308 auto& bndCell = m_bndCells[i];
6311 extrapolateVariable(ind, cellId, PV->RHO, &rho);
6312 const MFloat trgU = trgRhoU / rho;
6314 for(
MInt n = 0; n < nDim; n++) {
6315 u[n] = trgU * m_initialVelocityVecs[ind][n];
6317 m_solver->setEqDists(cellId, rho, u);
6318 for(
MInt n = 0; n < nDim; n++) {
6319 m_solver->a_variable(cellId, PV->U + n) = u[n];
6321 m_solver->a_variable(cellId, PV->RHO) = rho;
6340template <MInt nDim, MInt nDist,
class SysEqn>
6346 MFloat ma_x_pulsatile_F1BCS = m_Ma * pulsatile * LBCS;
6347 const MInt pvrho = PV->RHO;
6349#ifdef WAR_NVHPC_PSTL
6353 MInt offset = end - begin;
6355 maia::parallelFor<true>(0, offset, [=](
MInt id) {
6357 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
6360 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
6363 LbGridBoundaryCell<nDim>* bndCell = &m_bndCells[i];
6364 const MInt currentId = (*bndCell).m_cellId;
6365 const MInt pCellId = currentId;
6368 MFloat l_uu[nDim] = {0.0};
6371 extrapolateVariable(ind, pCellId, pvrho, &l_rho);
6373 for(
MInt n = 0; n < nDim; n++) {
6374 l_uu[n] = m_initialVelocityVecs[ind][n] * (*bndCell).m_multiplier * ma_x_pulsatile_F1BCS;
6379 for(
MInt n = 0; n < nDim; n++) {
6382 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
6385 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
6387#ifdef WAR_NVHPC_PSTL
6388 for(
MInt n = 0; n < nDim; n++) {
6389 m_solver->a_variable(pCellId, n) = l_uu[n];
6392 for(
MInt n = 0; n < nDim; n++) {
6393 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6396 m_solver->a_variable(pCellId, pvrho) = l_rho;
6397#ifdef WAR_NVHPC_PSTL
6402 writeBCOutput(index);
6415template <MInt nDim, MInt nDist,
class SysEqn>
6423 const MFloat velMag = sqrt(std::inner_product(&m_initialVelocityVecs[ind][0], &m_initialVelocityVecs[ind][nDim],
6424 &m_initialVelocityVecs[ind][0], 0.0));
6427 std::array<MFloat, nDim> u{};
6428 for(
MInt n = 0; n < nDim; n++) {
6429 u[n] = m_Ma * F1BCS * m_initialVelocityVecs[ind][n] / velMag;
6432 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6433 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6437 m_solver->setEqDists(cellId, rho, u.data());
6439 m_solver->a_oldVariable(cellId, PV->RHO) = rho;
6440 m_solver->a_variable(cellId, PV->RHO) = rho;
6441 for(
MInt n = 0; n < nDim; n++) {
6442 m_solver->a_oldVariable(cellId, PV->VV[n]) = u[n];
6443 m_solver->a_variable(cellId, PV->VV[n]) = u[n];
6476template <MInt nDim, MInt nDist,
class SysEqn>
6480 const MInt ind = m_mapSegIdsInOutCnd[
index];
6481 const MInt pvrho = PV->RHO;
6483#ifdef WAR_NVHPC_PSTL
6485 const MInt begin = m_bndCndOffsets[
index];
6486 const MInt end = m_bndCndOffsets[
index + 1];
6487 const MInt offset = end - begin;
6489 maia::parallelFor<true>(0, offset, [=](
MInt id) {
6491 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
6494 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
6497 const MInt currentId = m_bndCells[i].m_cellId;
6498 const MInt pCellId = currentId;
6500 MFloat l_uu[nDim] = {0.0};
6502 extrapolateVelocities(ind, pCellId, &l_uu[0]);
6507 if constexpr(nDim == 3) {
6508 MFloat old_squared_velocity = F0;
6509 MFloat squaredVelocity = F0;
6510 for(
MInt n = 0; n < nDim; n++) {
6511 squaredVelocity += (l_uu[n] * l_uu[n]);
6512 const MFloat l_old_u = m_solver->a_oldVariable(pCellId, n);
6513 old_squared_velocity += (l_old_u * l_old_u);
6515 const MFloat old_rho = m_solver->a_oldVariable(pCellId, pvrho);
6516 if(m_densityFluctuations)
6517 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + (m_rho1 - 1.0)) / 2.0;
6519 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + m_rho1) / 2.0;
6521 l_rho = (1.0 + m_solver->a_variable(pCellId, pvrho)) * F1B2;
6524 m_solver->setEqDists(pCellId, l_rho, l_uu);
6526 m_solver->a_variable(pCellId, pvrho) = l_rho;
6527#ifdef WAR_NVHPC_PSTL
6528 for(
MInt n = 0; n < nDim; n++) {
6529 m_solver->a_variable(pCellId, n) = l_uu[n];
6532 for(
MInt n = 0; n < nDim; n++) {
6533 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6537 writeBCOutput(index);
6551template <MInt nDim, MInt nDist,
class SysEqn>
6555 MInt cellsWeigthed = 0;
6559 MInt maxLevel = m_solver->a_level(m_bndCells[m_bndCndOffsets[index]].m_cellId);
6560 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6562 (maxLevel > m_solver->a_level(m_bndCells[i].m_cellId)) ? maxLevel : m_solver->a_level(m_bndCells[i].m_cellId);
6565 MFloat meanDensity = 0.0;
6566 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6567 weight = pow(
IPOW2(maxLevel - m_solver->a_level(m_bndCells[i].m_cellId)), nDim);
6568 if(m_solver->c_noChildren(m_bndCells[i].m_cellId) == 0) {
6569 for(
MInt j = 0; j < nDist; j++) {
6570 meanDensity += weight * m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j);
6572 cellsWeigthed += weight;
6575 meanDensity = 1.0 - meanDensity / cellsWeigthed;
6577 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6578 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6579 for(
MInt j = 0; j < nDist; j++) {
6580 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) += Ld::tp(Ld::distType(j)) * meanDensity;
6592template <MInt nDim, MInt nDist,
class SysEqn>
6596 if(direction > 2 * nDim) {
6597 TERMM(1,
"invalid direction for dnt!");
6600 MFloat rho, u[nDim], uInner[nDim];
6601 MInt currentId, currentDist;
6608 const MInt d = std::floor(direction / 2.0);
6610 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6611 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6615 currentId = m_bndCells[i].m_cellId;
6618 if(m_solver->a_isHalo(currentId))
continue;
6620 neighborId = m_solver->c_neighborId(currentId, Ld::oppositeDist(direction));
6623 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentId) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)));
6626 for(
MInt dim = 0; dim < nDim; dim++) {
6627 uInner[dim] = m_solver->a_variable(neighborId, PV->VV[dim]);
6630 MFloat zeroVel[nDim] = {0.0};
6632 sysEqn().calcEqDists(1.0, 0.0, zeroVel, &eDistributions1[0]);
6635 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
6636 currentDist = Ld::componentFld(Ld::oppositeDist(direction), j);
6638 m_solver->a_oldDistribution(currentId, currentDist) =
6639 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(currentDist));
6641 for(
MInt k = 0; k < nDim; k++) {
6642 m_solver->a_oldDistribution(currentId, currentDist) +=
6643 6 * eDistributions1[currentDist] * (Ld::idFld(currentDist, k) - 1.0) * uInner[k];
6649 rho = m_solver->a_variable(m_bndCells[i].m_cellId, PV->RHO);
6650 for(
MInt dim = 0; dim < nDim; dim++) {
6651 u[dim] = m_solver->a_variable(m_bndCells[i].m_cellId, PV->VV[dim]);
6654 sysEqn().calcEqDists(rho, u, &eDistributions[0]);
6661 M = (Ld::idFld(direction, d) - 1.0) * (-m_solver->a_nu(m_bndCells[i].m_cellId) * m_omega)
6662 * (m_solver->a_oldDistribution(m_bndCells[i].m_cellId, direction) - eDistributions[direction]);
6665 sysEqn().calcEqDists(1.0, u, &eDistributions1[0]);
6670 if(m_solver->a_hasNeighbor(currentId, direction) == 0) {
6671 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, Ld::oppositeDist(direction)) =
6672 eDistributions1[Ld::oppositeDist(direction)] + M
6673 + (m_solver->a_oldDistribution(m_bndCells[i].m_cellId, direction) - eDistributions[direction]);
6685template <MInt nDim, MInt nDist,
class SysEqn>
6689 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6690 const MInt currentId = m_bndCells[i].m_cellId;
6691 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)) != 0)
continue;
6694 if(m_solver->a_isHalo(currentId))
continue;
6697 const MFloat rho = m_solver->a_variable(currentId, PV->RHO);
6698 std::array<MFloat, nDim> u;
6699 std::array<MFloat, nDim> oldU;
6700 for(
MInt d = 0; d < nDim; d++) {
6701 u[d] = m_solver->a_variable(currentId, PV->VV[d]);
6702 oldU[d] = m_solver->a_oldVariable(currentId, PV->VV[d]);
6704 const MFloat squaredVelocity = std::inner_product(u.begin(), u.end(), u.begin(), 0.0);
6710 if constexpr(nDim == 3) {
6712 const MFloat oldSquaredVelocity = std::inner_product(oldU.begin(), oldU.end(), oldU.begin(), 0.0);
6713 const MFloat rho_out = (m_densityFluctuations) ? 0.0 : 1.0;
6714 rhoNonRefl = (rho + F1BCS * (sqrt(squaredVelocity) - sqrt(oldSquaredVelocity)) + rho_out) / 2.0;
6716 rhoNonRefl = (rho + 1.0) / 2.0;
6720 std::array<MFloat, nDist> eqDist, eqNew;
6721 if(m_solver->isCompressible()) {
6722 sysEqn().calcEqDists(rho, squaredVelocity, u.data(), eqDist.data());
6723 sysEqn().calcEqDists(rhoNonRefl, squaredVelocity, u.data(), eqNew.data());
6725 sysEqn().calcEqDists(rho, squaredVelocity, u.data(), eqDist.data());
6726 sysEqn().calcEqDists(rhoNonRefl, squaredVelocity, u.data(), eqNew.data());
6730 const MInt lvlDiff = m_solver->maxLevel() - m_solver->a_level(currentId);
6731 const MFloat omega = 1.0 / (0.5 + F1BCSsq * m_solver->a_nu(currentId) *
FFPOW2(lvlDiff));
6732 for(
MInt j = 0; j < nDist - 1; j++) {
6733 const MFloat neqDist = m_solver->a_distribution(currentId, j) - eqDist[j];
6734 m_solver->a_oldDistribution(currentId, j) = eqNew[j] + (1 - omega) * neqDist;
6737 writeBCOutput(index);
6767template <MInt nDim, MInt nDist,
class SysEqn>
6772 const MInt pvrho = PV->RHO;
6775#ifdef WAR_NVHPC_PSTL
6779 MInt offset = end - begin;
6781 maia::parallelFor<true>(0, offset, [=](
MInt id) {
6783 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
6786 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
6789 MFloat l_uu[nDim] = {0.0};
6791 const MInt currentId = m_bndCells[i].m_cellId;
6792 const MInt pCellId = currentId;
6795 extrapolateVelocities(ind, pCellId, &l_uu[0]);
6798 const MFloat l_old_rho = m_solver->a_oldVariable(pCellId, pvrho);
6800 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
6804 pow((1.0 - (gamma - 1.0) * (1.0 / (2.0 * gamma)) * (1.0 / (l_old_rho * l_old_rho)) * 3.0 * squaredVelocity),
6805 (gamma / (gamma - 1.0)));
6808 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
6810#ifdef WAR_NVHPC_PSTL
6811 for(
MInt n = 0; n < nDim; n++) {
6812 m_solver->a_variable(pCellId, n) = l_uu[n];
6815 for(
MInt n = 0; n < nDim; n++) {
6816 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6819 m_solver->a_variable(pCellId, pvrho) = l_rho;
6820#ifdef WAR_NVHPC_PSTL
6825 writeBCOutput(index);
6840template <MInt nDim, MInt nDist,
class SysEqn>
6846 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6847 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6849 MFloat l_uu[nDim] = {0.0};
6851 const MInt currentId = m_bndCells[i].m_cellId;
6853 const MInt pCellId = currentId;
6856 extrapolateVelocities(ind, pCellId, &l_uu[0]);
6859 const MFloat l_rho = m_rho1;
6864 m_solver->a_variable(pCellId, PV->U) = l_uu[0];
6865 m_solver->a_variable(pCellId, PV->V) = l_uu[1];
6866 if(nDim == 3) m_solver->a_variable(pCellId, PV->W) = l_uu[2];
6867 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
6869 writeBCOutput(index);
6885template <MInt nDim, MInt nDist,
class SysEqn>
6890 MFloat mean_velocity = 0.0;
6891 MInt numberOfCellsPerDomain = 0;
6894 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6895 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6897 MFloat l_uu[nDim] = {0.0};
6898 const MInt currentId = m_bndCells[i].m_cellId;
6899 const MInt pCellId = currentId;
6901 if(m_solver->c_noChildren(pCellId) == 0 && !m_solver->a_hasProperty(currentId, Cell::IsHalo)) {
6903 extrapolateVelocities(ind, pCellId, &l_uu[0]);
6905 for(
MInt n = 0; n < nDim; n++) {
6906 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
6907 l_uu[n] /= m_rhoLast;
6909 for(
MInt n = 0; n < nDim; n++) {
6910 mean_velocity += (m_bndNormals[ind][n] * l_uu[n]);
6913 numberOfCellsPerDomain++;
6917 MFloat mean_velocity_all = 0.0;
6919 MInt totalNumberOfCells = 0;
6920 if(m_noBCNeighbors[m_mapBndCndIdSegId[index]] > 1) {
6921 MPI_Allreduce(&numberOfCellsPerDomain, &totalNumberOfCells, 1, MPI_INT, MPI_SUM,
6922 m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"numberOfCellsPerDomain",
6923 "totalNumberOfCells");
6926 MPI_Allreduce(&mean_velocity, &mean_velocity_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
6927 "mean_velocity",
"mean_velocity_all");
6928 mean_velocity_all /= totalNumberOfCells;
6930 totalNumberOfCells = numberOfCellsPerDomain;
6931 mean_velocity_all = mean_velocity / totalNumberOfCells;
6935 MFloat l_Re = mean_velocity_all * m_referenceLength / m_solver->m_nu;
6936 MFloat Re_diff = m_solver->m_Re - l_Re;
6944 m_deltaRho = 1.0 - l_rho;
6945 m_maxDeltaRho = m_deltaRho;
6951 if(!(fabs(Re_diff) < eps)) {
6956 MFloat scaleRe = (m_solver->m_Re - l_Re) / (m_solver->m_Re - m_ReLast);
6958 m_deltaRho = fabs(scaleRe * m_deltaRho);
6959 if(m_deltaRho > m_maxDeltaRho) m_deltaRho = m_maxDeltaRho;
6963 l_rho -= m_deltaRho;
6968 else if(Re_diff < 0) {
6970 MFloat scaleRe = (l_Re - m_solver->m_Re) / (l_Re - m_ReLast);
6972 m_deltaRho = fabs(scaleRe * m_deltaRho);
6973 if(m_deltaRho > m_maxDeltaRho) m_deltaRho = m_maxDeltaRho;
6975 l_rho += m_deltaRho;
6979 if(this->m_calcBcResidual && m_solver->domainId() == m_BCneighbors[m_mapBndCndIdSegId[index]][0]) {
6980 m_BCResidualStream[m_mapBndCndIdSegId[
index]]
6981 <<
globalTimeStep <<
" final Re: " << m_solver->m_Re <<
" local Re: " << l_Re
6982 <<
" delta Re: " << (m_solver->m_Re - l_Re) <<
" local rho: " << l_rho <<
" delta rho: " << m_deltaRho
6983 <<
" max delta rho: " << m_maxDeltaRho <<
" nu " << m_solver->m_nu <<
" #Cells " << totalNumberOfCells
6989 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
6990 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
6992 const MInt currentId = m_bndCells[i].m_cellId;
6994 const MInt pCellId = currentId;
6996 MFloat l_uu[nDim] = {0.0};
6997 for(
MInt n = 0; n < nDim; n++) {
6998 l_uu[n] = m_solver->a_variable(pCellId, PV->VV[n]);
7000 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7003 m_solver->setEqDists(pCellId, l_rho, l_uu);
7005 writeBCOutput(index);
7019template <MInt nDim, MInt nDist,
class SysEqn>
7029 MFloat mean_velocity = 0.0;
7030 if(m_hasLocalReCut) {
7031 for(
MInt i = 0; i < (
MInt)m_localReCutCells.size(); i++) {
7032 MInt pCellId = m_localReCutCells[i];
7033 MFloat density = m_solver->a_variable(pCellId, PV->RHO);
7035 MFloat l_uu[nDim] = {0.0};
7037 for(
MInt n = 0; n < nDim; n++) {
7038 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7041 for(
MInt n = 0; n < nDim; n++) {
7042 mean_velocity += (m_bndNormals[ind][n] * l_uu[n]);
7048 MFloat mean_velocity_all;
7049 MPI_Allreduce(&mean_velocity, &mean_velocity_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
7050 "mean_velocity",
"mean_velocity_all");
7052 mean_velocity_all /= m_totalNoBcCells[m_mapBndCndIdSegId[
index]];
7055 l_Re = mean_velocity_all * m_localReCutDiameter / m_solver->m_nu;
7056 MFloat Re_diff = m_localReCutRe - l_Re;
7063 if(!(fabs(Re_diff) < eps)) {
7064 MFloat s = Re_diff / m_localReCutRe;
7070 MFloat scaleRe = Re_diff / (m_localReCutRe - m_ReLast);
7072 if(fabs(s) < m_localReCutAdpPerc) {
7073 m_deltaRho = fabs(scaleRe * m_deltaRho);
7074 if(m_deltaRho > m_maxDeltaRho) m_deltaRho = m_maxDeltaRho;
7076 m_lRho -= m_deltaRho;
7082 else if(Re_diff < 0) {
7084 MFloat scaleRe = Re_diff / (l_Re - m_ReLast);
7086 if(fabs(s) < m_localReCutAdpPerc) {
7087 m_deltaRho = fabs(scaleRe * m_deltaRho);
7088 if(m_deltaRho > m_maxDeltaRho) m_deltaRho = m_maxDeltaRho;
7090 m_lRho += m_deltaRho;
7097 if(this->m_calcBcResidual && m_solver->domainId() == m_firstBCinComm
7099 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
globalTimeStep <<
"\t" << m_localReCutRe <<
"\t" << l_Re <<
"\t"
7100 << m_ReLast <<
"\t" << Re_diff <<
"\t" << m_lRho <<
"\t"
7101 << m_rhoLast <<
"\t" << m_deltaRho << std::endl;
7119template <MInt nDim, MInt nDist,
class SysEqn>
7125 m_deltaRho = 1.0 - m_lRho;
7134 m_deltaRho = Context::getSolverProperty<MFloat>(
"deltaRho", m_solverId, AT_, &m_deltaRho);
7136 m_maxDeltaRho = m_deltaRho;
7148 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7149 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7151 const MInt currentId = m_bndCells[i].m_cellId;
7152 const MInt pCellId = currentId;
7154 MFloat l_uu[nDim] = {0.0};
7156 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7158 m_solver->setEqDists(pCellId, m_lRho, l_uu);
7160 m_solver->a_variable(pCellId, PV->RHO) = m_lRho;
7161 for(
MInt n = 0; n < nDim; n++) {
7162 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7165 writeBCOutput(index);
7181template <MInt nDim, MInt nDist,
class SysEqn>
7185 const MInt ind = m_mapSegIdsInOutCnd[
index];
7187 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7188 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7190 std::array<MFloat, nDim> l_uu{};
7191 std::array<MFloat, nDim> u{};
7195 const MInt currentId = m_bndCells[i].m_cellId;
7197 const MInt pCellId = currentId;
7200 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7203 const MFloat l_old_rho = m_solver->a_oldVariable(pCellId, PV->RHO);
7205 const MFloat squaredVelocityRho = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
7210 - (
lb_gamma2 - 1.0) * (1.0 / (2.0 *
lb_gamma2)) * (1.0 / (l_old_rho * l_old_rho)) * 3.0 * squaredVelocityRho),
7215 for(
MInt n = 0; n < nDim; n++) {
7216 u[n] = l_uu[n] / l_rho;
7219 m_solver->setEqDists(pCellId, l_rho, u.data());
7220 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, u.data());
7222 if(m_solver->m_isTransport) {
7224 m_solver->setEqDistsTransport(pCellId, l_c, u.data());
7225 m_solver->a_variable(pCellId, PV->C) = l_c;
7228 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7229 m_solver->a_variable(pCellId, PV->T) = l_t;
7230 for(
MInt n = 0; n < nDim; n++) {
7231 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7234 writeBCOutput(index);
7249template <MInt nDim, MInt nDist,
class SysEqn>
7255 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7256 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7259 std::array<MFloat, nDim> l_uu{};
7260 std::array<MFloat, nDim> u{};
7262 const MInt currentId = m_bndCells[i].m_cellId;
7263 const MInt pCellId = currentId;
7266 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7267 extrapolateVariable(ind, pCellId, PV->T, &l_t);
7274 for(
MInt n = 0; n < nDim; n++) {
7275 u[n] = l_uu[n] / l_rho;
7277 const MFloat squaredVelocity = std::inner_product(&u[0], &u[nDim], &u[0], .0);
7280 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, u.data());
7281 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, squaredVelocity, u.data());
7283 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7284 m_solver->a_variable(pCellId, PV->T) = l_t;
7285 for(
MInt n = 0; n < nDim; n++) {
7286 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7289 writeBCOutput(index);
7305template <MInt nDim, MInt nDist,
class SysEqn>
7310 MFloat mean_velocity = 0.0;
7311 MInt numberOfCellsPerDomain = 0;
7314 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7315 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7317 const MInt currentId = m_bndCells[i].m_cellId;
7318 const MInt pCellId = currentId;
7320 if(m_solver->c_noChildren(pCellId) == 0 && !m_solver->a_hasProperty(currentId, Cell::IsHalo)) {
7321 MFloat l_uu[nDim] = {0.0};
7324 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7326 for(
MInt n = 0; n < nDim; n++) {
7327 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7328 l_uu[n] /= m_rhoLast;
7331 for(
MInt n = 0; n < nDim; n++) {
7332 mean_velocity += (m_bndNormals[ind][n] * l_uu[n]);
7334 numberOfCellsPerDomain++;
7338 MFloat mean_velocity_all = 0.0;
7341 MInt totalNumberOfCells = 0;
7342 if(m_noBCNeighbors[m_mapBndCndIdSegId[index]] > 1) {
7343 MPI_Allreduce(&numberOfCellsPerDomain, &totalNumberOfCells, 1, MPI_INT, MPI_SUM,
7344 m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"numberOfCellsPerDomain",
7345 "totalNumberOfCells");
7348 MPI_Allreduce(&mean_velocity, &mean_velocity_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
7349 "mean_velocity",
"mean_velocity_all");
7350 mean_velocity_all /= totalNumberOfCells;
7352 totalNumberOfCells = numberOfCellsPerDomain;
7353 mean_velocity_all = mean_velocity / totalNumberOfCells;
7357 MFloat l_Re = mean_velocity_all * m_referenceLength / m_solver->m_nu;
7358 MFloat Re_diff = m_solver->m_Re - l_Re;
7366 m_deltaRho = 1.0 - l_rho;
7367 m_maxDeltaRho = m_deltaRho;
7373 if(!(fabs(Re_diff) < eps)) {
7378 MFloat scaleRe = (m_solver->m_Re - l_Re) / (m_solver->m_Re - m_ReLast);
7380 m_deltaRho = fabs(scaleRe * m_deltaRho);
7381 if(m_deltaRho > m_maxDeltaRho)
7382 m_deltaRho = m_maxDeltaRho;
7383 else if(m_deltaRho < 0.00000001)
7384 m_deltaRho = 0.00000001;
7386 l_rho -= m_deltaRho;
7391 else if(Re_diff < 0) {
7393 MFloat scaleRe = (l_Re - m_solver->m_Re) / (l_Re - m_ReLast);
7395 m_deltaRho = fabs(scaleRe * m_deltaRho);
7396 if(m_deltaRho > m_maxDeltaRho)
7397 m_deltaRho = m_maxDeltaRho;
7398 else if(m_deltaRho < 0.00000001)
7399 m_deltaRho = 0.00000001;
7401 l_rho += m_deltaRho;
7405 if(this->m_calcBcResidual && m_solver->domainId() == m_BCneighbors[m_mapBndCndIdSegId[index]][0]) {
7406 m_BCResidualStream[m_mapBndCndIdSegId[
index]]
7407 <<
globalTimeStep <<
" final Re: " << m_solver->m_Re <<
" local Re: " << l_Re
7408 <<
" delta Re: " << (m_solver->m_Re - l_Re) <<
" local rho: " << l_rho <<
" delta rho: " << m_deltaRho
7409 <<
" max delta rho: " << m_maxDeltaRho <<
" nu " << m_solver->m_nu <<
" kappa " << m_solver->m_kappa
7410 <<
" #Cells " << totalNumberOfCells << std::endl;
7415 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7416 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7418 MInt currentId = m_bndCells[i].m_cellId;
7420 const MInt pCellId = currentId;
7424 extrapolateVariable(ind, currentId, PV->T, &l_t);
7426 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7427 m_solver->a_variable(pCellId, PV->T) = l_t;
7428 MFloat l_uu[nDim] = {0.0};
7429 for(
MInt n = 0; n < nDim; n++) {
7430 l_uu[n] = m_solver->a_variable(pCellId, PV->VV[n]) / l_rho;
7433 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
7436 m_solver->setEqDists(pCellId, l_rho, squaredVelocity, l_uu);
7437 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, squaredVelocity, l_uu);
7439 if(m_solver->m_isTransport) {
7441 extrapolateVariable(ind, currentId, PV->C, &l_c);
7442 m_solver->setEqDistsTransport(pCellId, l_c, squaredVelocity, l_uu);
7445 writeBCOutput(index);
7457template <MInt nDim, MInt nDist,
class SysEqn>
7462 MFloat mean_velocity = 0.0;
7464 MFloat mean_oldRho = 0.0;
7465 MInt numberOfCellsPerDomain = 0;
7468 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7469 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7471 const MInt pCellId = m_bndCells[i].m_cellId;
7473 if(m_solver->c_noChildren(pCellId) == 0 && !m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
7474 MFloat l_uu[nDim] = {0.0};
7478 for(
MInt n = 0; n < nDim; n++) {
7479 l_uu[n] = m_solver->a_variable(pCellId, PV->VV[n]);
7482 l_rho = m_solver->a_variable(pCellId, PV->RHO);
7483 l_oldRho = m_solver->a_oldVariable(pCellId, PV->RHO);
7486 mean_oldRho += l_oldRho;
7488 for(
MInt n = 0; n < nDim; n++) {
7489 mean_velocity += (m_bndNormals[ind][n] * l_uu[n]);
7492 numberOfCellsPerDomain++;
7496 MFloat mean_rho_all = 0.0;
7497 MFloat mean_oldRho_all = 0.0;
7498 MFloat mean_velocity_all = 0.0;
7501 MInt totalNumberOfCells = 0;
7502 if(m_noBCNeighbors[m_mapBndCndIdSegId[index]] > 1) {
7503 MPI_Allreduce(&numberOfCellsPerDomain, &totalNumberOfCells, 1, MPI_INT, MPI_SUM,
7504 m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"numberOfCellsPerDomain",
7505 "totalNumberOfCells");
7508 MPI_Allreduce(&mean_rho, &mean_rho_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
7509 "mean_rho",
"mean_rho_all");
7510 mean_rho_all /= totalNumberOfCells;
7513 MPI_Allreduce(&mean_oldRho, &mean_oldRho_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
7514 "mean_oldRho",
"mean_oldRho_all");
7515 mean_oldRho_all /= totalNumberOfCells;
7518 MPI_Allreduce(&mean_velocity, &mean_velocity_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
7519 "mean_velocity",
"mean_velocity_all");
7520 mean_velocity_all /= totalNumberOfCells;
7522 totalNumberOfCells = numberOfCellsPerDomain;
7523 mean_rho_all = mean_rho / totalNumberOfCells;
7524 mean_oldRho_all = mean_oldRho / totalNumberOfCells;
7525 mean_velocity_all = mean_velocity / totalNumberOfCells;
7529 m_rhoLast = mean_rho_all;
7530 m_deltaRho = fabs(mean_rho_all - mean_oldRho_all);
7533 MFloat l_Re = mean_velocity_all / m_rhoLast * m_referenceLength / m_solver->m_nu;
7549template <MInt nDim, MInt nDist,
class SysEqn>
7555 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7556 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7558 const MInt currentId = m_bndCells[i].m_cellId;
7559 const MInt pCellId = currentId;
7561 std::array<MFloat, nDim> l_uu{};
7562 std::array<MFloat, nDim> l_old_uu{};
7563 std::array<MFloat, nDim> u{};
7565 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7567 MFloat old_rho = m_solver->a_oldVariable(pCellId, PV->RHO);
7568 for(
MInt n = 0; n < nDim; n++) {
7569 l_old_uu[n] = m_solver->a_oldVariable(pCellId, PV->VV[n]);
7572 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
7574 const MFloat old_squared_velocity = std::inner_product(&l_old_uu[0], &l_old_uu[nDim], &l_old_uu[0], .0);
7578 if(m_densityFluctuations)
7579 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + (m_rho1 - 1.0)) / 2.0;
7581 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + m_rho1) / 2.0;
7585 for(
MInt n = 0; n < nDim; n++) {
7586 u[n] = l_uu[n] / l_rho;
7589 m_solver->setEqDists(pCellId, l_rho, u.data());
7590 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, u.data());
7592 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7593 m_solver->a_variable(pCellId, PV->T) = l_t;
7594 for(
MInt n = 0; n < nDim; n++) {
7595 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7612template <MInt nDim, MInt nDist,
class SysEqn>
7617 const MInt pvrho = PV->RHO;
7618 const MInt pvt = PV->T;
7620#ifdef WAR_NVHPC_PSTL
7624 MInt offset = end - begin;
7626 maia::parallelFor<true>(0, offset, [=](
MInt id) {
7628 if((globalTimeStep_) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
return;
7631 if((globalTimeStep - 1) % IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0) return;
7634 const MInt currentId = m_bndCells[i].m_cellId;
7635 const MInt pCellId = currentId;
7637 std::array<MFloat, nDim> l_uu{};
7638 std::array<MFloat, nDim> l_old_uu{};
7639 std::array<MFloat, nDim> u{};
7642 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7643 extrapolateVariable(ind, pCellId, PV->T, &l_t);
7645 MFloat old_rho = m_solver->a_oldVariable(pCellId, pvrho);
7646 for(
MInt n = 0; n < nDim; n++) {
7647 l_old_uu[n] = m_solver->a_oldVariable(pCellId, n);
7650 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
7652 const MFloat old_squared_velocity = std::inner_product(&l_old_uu[0], &l_old_uu[nDim], &l_old_uu[0], .0);
7656 if(m_densityFluctuations)
7657 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + (m_rho1 - 1.0)) / 2.0;
7659 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + m_rho1) / 2.0;
7663 for(
MInt n = 0; n < nDim; n++) {
7664 u[n] = l_uu[n] / l_rho;
7666 m_solver->setEqDists(pCellId, l_rho, u.data());
7667 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, u.data());
7669 m_solver->a_variable(pCellId, pvrho) = l_rho;
7670 m_solver->a_variable(pCellId, pvt) = l_t;
7671#ifdef WAR_NVHPC_PSTL
7672 for(
MInt n = 0; n < nDim; n++) {
7673 m_solver->a_variable(pCellId, n) = l_uu[n];
7677 for(
MInt n = 0; n < nDim; n++) {
7678 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7682 writeBCOutput(index);
7694template <MInt nDim, MInt nDist,
class SysEqn>
7700 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7701 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7703 const MInt currentId = m_bndCells[i].m_cellId;
7704 const MInt pCellId = currentId;
7706 std::array<MFloat, nDim> l_uu{};
7707 std::array<MFloat, nDim> l_old_uu{};
7708 std::array<MFloat, nDim> u{};
7712 extrapolateVelocities(ind, pCellId, &l_uu[0]);
7713 if(m_solver->m_isThermal) {
7714 extrapolateVariable(ind, pCellId, PV->T, &l_t);
7716 extrapolateVariable(ind, pCellId, PV->C, &l_c);
7718 MFloat old_rho = m_solver->a_oldVariable(pCellId, PV->RHO);
7719 for(
MInt n = 0; n < nDim; n++) {
7720 l_old_uu[n] = m_solver->a_oldVariable(pCellId, PV->VV[n]);
7723 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
7725 const MFloat old_squared_velocity = std::inner_product(&l_old_uu[0], &l_old_uu[nDim], &l_old_uu[0], .0);
7729 if(m_densityFluctuations)
7730 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + (m_rho1 - 1.0)) / 2.0;
7732 l_rho = (old_rho + F1BCS * (sqrt(squaredVelocity) - sqrt(old_squared_velocity)) + m_rho1) / 2.0;
7736 for(
MInt n = 0; n < nDim; n++) {
7737 u[n] = l_uu[n] / l_rho;
7740 m_solver->setEqDists(pCellId, l_rho, u.data());
7741 m_solver->setEqDistsThermal(pCellId, l_t, l_rho, u.data());
7742 m_solver->setEqDistsTransport(pCellId, l_c, u.data());
7744 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
7745 if(m_solver->m_isThermal) m_solver->a_variable(pCellId, PV->T) = l_t;
7746 m_solver->a_variable(pCellId, PV->C) = l_c;
7747 for(
MInt n = 0; n < nDim; n++) {
7748 m_solver->a_variable(pCellId, PV->VV[n]) = l_uu[n];
7760template <MInt nDim, MInt nDist,
class SysEqn>
7765 std::array<MFloat, nDim> u{};
7766 for(
MInt d = 0; d < nDim; d++) {
7767 u[d] = std::numeric_limits<MFloat>::max();
7772 MInt tmpDistId, currentId;
7776 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7777 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7779 currentId = m_bndCells[i].m_cellId;
7782 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentId) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)));
7786 rho = m_solver->a_variable(currentId, PV->RHO);
7788 for(
MInt d = 0; d < nDim; d++) {
7789 u[d] = m_initialVelocityVecs[ind][d] * m_Ma * LBCS * m_bndCells[i].m_multiplier;
7791 b[2 * d + 1] = u[d];
7794 const MFloat tmp2 = std::inner_product(&u[0], &u[nDim], &u[0], .0);
7797 for(
MInt j = 0; j < Ld::distFld(0); j++) {
7798 m_solver->a_distribution(currentId, j) =
7799 m_solver->a_oldDistribution(currentId, j)
7801 * (Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2)
7802 - m_solver->a_oldDistribution(currentId, j));
7806 tmpDistId = Ld::distFld(0);
7807 for(
MInt j = 0; j < Ld::distFld(1); j++) {
7808 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
7809 m_solver->a_distribution(currentId, tmpDistId + j) =
7810 m_solver->a_oldDistribution(currentId, tmpDistId + j)
7812 * (Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
7813 - m_solver->a_oldDistribution(currentId, tmpDistId + j));
7817 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
7818 for(
MInt j = 0; j < Ld::distFld(2); j++) {
7819 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
7820 m_solver->a_distribution(currentId, tmpDistId + j) =
7821 m_solver->a_oldDistribution(currentId, tmpDistId + j)
7823 * (Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
7824 - m_solver->a_oldDistribution(currentId, tmpDistId + j));
7827 m_solver->a_distribution(currentId, Ld::lastId()) =
7828 m_solver->a_oldDistribution(currentId, Ld::lastId())
7829 + m_omega * (Ld::tp(0) * (rho - F1B2 * F1BCSsq * tmp2) - m_solver->a_oldDistribution(currentId, Ld::lastId()));
7835 for(
MInt j = 0; j < nDist - 1; j++) {
7836 if(m_solver->a_hasNeighbor(currentId, Ld::oppositeDist(j)) == 0) {
7837 m_solver->a_oldDistribution(currentId, j) = m_solver->a_distribution(currentId, j);
7841 m_solver->a_variable(currentId, PV->RHO) = rho;
7842 for(
MInt d = 0; d < nDim; d++) {
7843 m_solver->a_variable(currentId, d) = u[d];
7853template <MInt nDim, MInt nDist,
class SysEqn>
7859 std::array<MFloat, nDim> u{};
7861 std::array<MFloat, 2 * nDim>
b{};
7862 MInt tmpDistId, currentId;
7869 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
7870 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
7872 currentId = m_bndCells[i].m_cellId;
7875 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentId) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)));
7904 rho = m_solver->a_variable(currentId, PV->RHO);
7905 for(
MInt n = 0; n < nDim; n++) {
7906 u[n] = m_solver->a_variable(currentId, PV->VV[n]);
7908 b[2 * n + 1] = u[n];
7911 tmp2 = std::inner_product(&u[0], &u[nDim], &u[0], .0);
7914 for(
MInt j = 0; j < Ld::distFld(0); j++) {
7915 eDistributions[j] = Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2);
7918 tmpDistId = Ld::distFld(0);
7919 for(
MInt j = 0; j < Ld::distFld(1); j++) {
7920 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
7921 eDistributions[tmpDistId + j] =
7922 Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
7925 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
7926 for(
MInt j = 0; j < Ld::distFld(2); j++) {
7927 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
7928 eDistributions[tmpDistId + j] =
7929 Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
7934 for(
MInt j = 0; j < nDist; j++) {
7935 nePart[j] = m_solver->a_oldDistribution(currentId, j) - eDistributions[j];
7953 for(
MInt d = 0; d < nDim; d++) {
7954 u[d] = m_initialVelocityVecs[ind][d] * m_Ma * LBCS * m_bndCells[i].m_multiplier;
7956 b[2 * d + 1] = u[d];
7959 tmp2 = std::inner_product(&u[0], &u[nDim], &u[0], .0);
7962 for(
MInt j = 0; j < Ld::distFld(0); j++) {
7963 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) =
7964 Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2)
7965 + ((1 - m_omega) * nePart[j]);
7971 tmpDistId = Ld::distFld(0);
7972 for(
MInt j = 0; j < Ld::distFld(1); j++) {
7973 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
7974 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, tmpDistId + j) =
7975 Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
7976 + ((1 - m_omega) * nePart[tmpDistId + j]);
7982 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
7983 for(
MInt j = 0; j < Ld::distFld(2); j++) {
7984 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
7985 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, tmpDistId + j) =
7986 Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
7987 + ((1 - m_omega) * nePart[tmpDistId + j]);
8002template <MInt nDim, MInt nDist,
class SysEqn>
8007 MFloat rho, u[nDim], old_u[nDim];
8012 MInt tmpDistId, currentId;
8018 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8019 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
8021 currentId = m_bndCells[i].m_cellId;
8026 if(m_solver->a_isHalo(currentId))
continue;
8030 extrapolateVariable(ind, currentId, PV->T, &l_t);
8033 m_Ma * LBCS / m_solver->m_Re * m_referenceLength *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId));
8034 m_omega = 2.0 / (1.0 + 6.0 * nu);
8039 rho = m_solver->a_variable(currentId, PV->RHO);
8040 u[0] = m_solver->a_variable(currentId, PV->U);
8041 u[1] = m_solver->a_variable(currentId, PV->V);
8042 IF_CONSTEXPR(nDim == 3) u[2] = m_solver->a_variable(currentId, PV->W);
8044 old_u[0] = m_solver->a_oldVariable(currentId, PV->U);
8045 old_u[1] = m_solver->a_oldVariable(currentId, PV->V);
8046 IF_CONSTEXPR(nDim == 3) old_u[2] = m_solver->a_oldVariable(currentId, PV->W);
8050 for(
MInt d = 0; d < nDim; d++) {
8051 tmp2 += (u[d] * u[d]);
8052 old_tmp2 += (old_u[d] * old_u[d]);
8054 b[2 * d + 1] = u[d];
8058 for(
MInt j = 0; j < Ld::distFld(0); j++) {
8059 eDistributions[j] = Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2);
8062 tmpDistId = Ld::distFld(0);
8063 for(
MInt j = 0; j < Ld::distFld(1); j++) {
8064 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
8065 eDistributions[tmpDistId + j] =
8066 Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
8069 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
8070 for(
MInt j = 0; j < Ld::distFld(2); j++) {
8071 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
8072 eDistributions[tmpDistId + j] =
8073 Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
8078 for(
MInt j = 0; j < nDist - 1; j++) {
8079 nePart[j] = m_solver->a_distribution(currentId, j);
8081 for(
MInt j = 0; j < nDist - 1; j++) {
8082 nePart[j] -= eDistributions[j];
8088 IF_CONSTEXPR(nDim == 3) {
8089 if(m_densityFluctuations) {
8090 rho = (rho + F1BCS * (sqrt(tmp2) - sqrt(old_tmp2))) / 2.0;
8096 rho = (rho + F1BCS * (sqrt(tmp2) - sqrt(old_tmp2)) + 1.0) / 2.0;
8100 rho = (rho + 1.0) / 2.0;
8107 for(
MInt j = 0; j < Ld::distFld(0); j++) {
8109 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) =
8110 Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2)
8111 + ((1 - m_omega) * nePart[j]);
8116 tmpDistId = Ld::distFld(0);
8117 for(
MInt j = 0; j < Ld::distFld(1); j++) {
8119 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
8120 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, tmpDistId + j) =
8121 Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
8122 + ((1 - m_omega) * nePart[tmpDistId + j]);
8127 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
8128 for(
MInt j = 0; j < Ld::distFld(2); j++) {
8130 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
8131 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, tmpDistId + j) =
8132 Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
8133 + ((1 - m_omega) * nePart[tmpDistId + j]);
8137 m_solver->setEqDistsThermal(currentId, l_t, rho, u);
8139 writeBCOutput(index);
8154template <MInt nDim, MInt nDist,
class SysEqn>
8155template <MInt direction>
8159 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8160 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
8161 for(
MInt j = 0; j < nDist - 1; j++) {
8162 if(m_solver->a_hasNeighbor(m_bndCells[i].m_cellId, Ld::oppositeDist(j)) == 0) {
8163 const MInt neighbor1 = m_solver->c_neighborId(m_bndCells[i].m_cellId, Ld::oppositeDist(direction));
8164 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) = m_solver->a_oldDistribution(neighbor1, j);
8189template <MInt nDim, MInt nDist,
class SysEqn>
8190template <MBool thermal>
8193 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8195 const MInt maxLvlDiff = m_solver->maxLevel() - m_solver->a_level(cellId);
8197 if(
globalTimeStep %
IPOW2(maxLvlDiff) != 0 || m_solver->a_isHalo(cellId) || !m_solver->a_isActive(cellId)) {
8200 for(
MInt trgDist = 0; trgDist < nDist - 1; trgDist++) {
8202 const MInt srcDir1 = Ld::oppositeDist(trgDist);
8203 if(!(m_bndCells[i].m_distances[srcDir1] <= 0.5)) {
8207 std::array<MInt, nDim> srcDirVec, srcDistVec;
8208 for(
MInt d = 0; d < nDim; d++) {
8209 srcDirVec[d] = Ld::idFld(srcDir1, d);
8210 srcDistVec[d] = Ld::idFld(trgDist, d);
8214 MBool normalPropagation =
true;
8215 for(
MInt d = 0; d < nDim; d++) {
8216 if(srcDirVec[d] == 1)
continue;
8218 const MInt tmpDir = (srcDirVec[d] / 2) + (d * 2);
8220 if(m_bndCells[i].m_distances[tmpDir] <= 0.5) {
8221 srcDistVec[d] = 2 - srcDistVec[d];
8222 normalPropagation =
false;
8225 if(normalPropagation)
continue;
8229 for(
MInt d = 0; d < nDim; d++) {
8230 srcDirVec[d] = 2 - (Ld::idFld(trgDist, d) + srcDistVec[d]) / 2;
8233 const MInt srcDist = Ld::dirFld(srcDistVec[0], srcDistVec[1], srcDistVec[2]);
8234 const MInt srcDir2 = Ld::dirFld(srcDirVec[0], srcDirVec[1], srcDirVec[2]);
8237 enum CellState { NORMAL, AT_INTERFACE, WALL, UNDEFINED };
8240 if(srcDir2 == Ld::lastId()) {
8243 }
else if(m_solver->a_hasNeighbor(cellId, srcDir2)) {
8244 srcCell = m_solver->c_neighborId(cellId, srcDir2);
8245 if(m_solver->a_isActive(srcCell)) {
8248 if(m_solver->m_isRefined && m_solver->a_isInterfaceParent(cellId)) {
8249 state = AT_INTERFACE;
8254 }
else if(m_solver->m_isRefined && m_solver->a_isInterfaceChild(cellId)) {
8255 const MInt parentId = m_solver->c_parentId(cellId);
8256 if(m_solver->a_hasNeighbor(parentId, srcDir2)) {
8257 state = AT_INTERFACE;
8274 m_solver->a_oldDistribution(cellId, trgDist) = m_solver->a_distribution(srcCell, srcDist);
8275 if constexpr(thermal) {
8276 m_solver->a_oldDistributionThermal(cellId, trgDist) = m_solver->a_distributionThermal(srcCell, srcDist);
8280 case AT_INTERFACE: {
8281 m_solver->a_oldDistribution(cellId, trgDist) = m_solver->a_oldDistribution(cellId, srcDist);
8282 if constexpr(thermal) {
8283 m_solver->a_oldDistributionThermal(cellId, trgDist) = m_solver->a_oldDistributionThermal(cellId, srcDist);
8292 const MInt solidNghbrBndId = m_solver->a_bndId(srcCell);
8293 if(m_bndCells[solidNghbrBndId].m_isFluid ==
false && m_bndCells[solidNghbrBndId].m_distances[srcDist] < 0.5) {
8294 const MFloat F2q = F2 * (F1 - m_bndCells[solidNghbrBndId].m_distances[srcDist]);
8295 const MInt oppositeDir = Ld::oppositeDist(trgDist);
8296 m_solver->a_oldDistribution(cellId, trgDist) =
8297 (m_solver->a_distribution(cellId, oppositeDir) / F2q)
8298 + (m_solver->a_distribution(cellId, trgDist) * (F2q - F1) / F2q);
8299 if constexpr(thermal) {
8300 m_solver->a_oldDistributionThermal(cellId, trgDist) =
8301 (m_solver->a_distributionThermal(cellId, oppositeDir) / F2q)
8302 + (m_solver->a_distributionThermal(cellId, trgDist) * (F2q - F1) / F2q);
8325template <MInt nDim, MInt nDist,
class SysEqn>
8326template <MInt direction>
8330 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8331 if((
globalTimeStep) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
8332 for(
MInt j = 0; j < nDist - 1; j++) {
8333 if(m_solver->a_hasNeighbor(m_bndCells[i].m_cellId, Ld::oppositeDist(j)) == 0) {
8334 const MInt neighbor1 = m_solver->c_neighborId(m_bndCells[i].m_cellId, Ld::oppositeDist(direction));
8335 const MInt neighbor2 = m_solver->c_neighborId(neighbor1, Ld::oppositeDist(direction));
8336 m_solver->a_oldDistribution(m_bndCells[i].m_cellId, j) =
8337 2.0 * m_solver->a_oldDistribution(neighbor1, j) - m_solver->a_oldDistribution(neighbor2, j);
8356template <MInt nDim, MInt nDist,
class SysEqn>
8360 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8361 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
8363 const MInt currentId = m_bndCells[i].m_cellId;
8365 const MFloat rho = m_solver->a_variable(currentId, PV->RHO);
8366#ifdef WAR_NVHPC_PSTL
8368 for(
MInt d = 0; d < nDim; d++) {
8369 vel[d] = m_solver->a_variable(currentId, d);
8371 const MFloat*
const u = vel;
8373 const MFloat*
const u = &m_solver->a_variable(currentId, PV->U);
8378 const MFloat tmp2 = std::inner_product(&u[0], &u[nDim], &u[0], 0.0);
8380 for(
MInt n = 0; n < nDim; n++) {
8382 b[2 * n + 1] = u[n];
8387 for(
MInt j = 0; j < Ld::distFld(0); j++) {
8388 eqSym[j] = Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2);
8392 MInt tmpDistId = Ld::distFld(0);
8393 for(
MInt j = 0; j < Ld::distFld(1); j++) {
8394 const MInt tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
8395 eqSym[tmpDistId + j] = Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
8399 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
8400 for(
MInt j = 0; j < Ld::distFld(2); j++) {
8401 const MInt tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
8402 eqSym[tmpDistId + j] = Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
8405 for(
MInt j = 0; j < nDist - 1; j++) {
8406 if(!m_solver->a_hasNeighbor(currentId, j))
8407 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j)) =
8408 -m_solver->a_distribution(currentId, j) + 2.0 * eqSym[j];
8422template <MInt nDim, MInt nDist,
class SysEqn>
8426 if(!this->m_calcBcResidual)
return;
8429 MFloat mean_velocity = 0.0;
8431 MFloat mean_u[nDim] = {0.0};
8432 MInt numberOfCellsPerDomain = 0;
8434 MFloat mean_p_stat = 0.0;
8437 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
8438 if((
globalTimeStep - 1) %
IPOW2(m_solver->maxLevel() - m_solver->a_level(m_bndCells[i].m_cellId)) != 0)
continue;
8440 MInt pCellId = m_bndCells[i].m_cellId;
8442 if(m_solver->c_noChildren(pCellId) == 0 && !m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
8443 MFloat l_rho = m_solver->a_variable(pCellId, PV->RHO);
8444 MFloat l_uu[nDim] = {0.0};
8445 for(
MInt n = 0; n < nDim; n++) {
8446 l_uu[n] = m_solver->a_variable(pCellId, PV->VV[n]) / l_rho;
8450 if(m_solver->m_isThermal) {
8451 l_t = m_solver->a_variable(pCellId, PV->T);
8454 for(
MInt n = 0; n < nDim; n++) {
8455 mean_velocity += (m_bndNormals[ind][n] * l_uu[n]);
8457 const MFloat squaredVelocity = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
8459 numberOfCellsPerDomain++;
8461 for(
MInt n = 0; n < nDim; n++) {
8462 mean_u[n] += l_uu[n];
8465 mean_p_d += F1B2 * l_rho * squaredVelocity;
8466 mean_p_stat += F1B3 * l_rho;
8471 MFloat mean_velocity_all = 0.0;
8472 MFloat mean_rho_all = 0.0;
8473 MFloat mean_u_all[nDim] = {0.0};
8474 MFloat mean_p_d_all = 0.0;
8475 MFloat mean_p_stat_all = 0.0;
8478 MInt totalNumberOfCells = 0;
8479 switch(m_noBCNeighbors[m_mapBndCndIdSegId[index]]) {
8485 totalNumberOfCells = numberOfCellsPerDomain;
8486 mean_velocity_all = mean_velocity / totalNumberOfCells;
8487 mean_rho_all = mean_rho / totalNumberOfCells;
8489 for(
MInt n = 0; n < nDim; n++) {
8490 mean_u_all[n] = mean_u[n] / totalNumberOfCells;
8493 mean_p_d_all = mean_p_d / totalNumberOfCells;
8494 mean_p_stat_all = mean_p_stat / totalNumberOfCells;
8495 if(m_solver->m_isThermal) {
8496 mean_t_all = mean_t / totalNumberOfCells;
8500 MFloat ReynoldsNr = m_referenceLength * mean_velocity_all / m_solver->m_nu;
8502 if(m_solver->domainId() == m_BCneighbors[m_mapBndCndIdSegId[index]][0]) {
8503 m_BCResidualStream[m_mapBndCndIdSegId[
index]].open(m_BCOutputFileName[m_mapBndCndIdSegId[index]],
8504 std::ios_base::app);
8505 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
globalTimeStep <<
" p_dyn " << mean_p_d_all <<
" p_stat "
8506 << mean_p_stat_all <<
" Mag " << mean_velocity_all <<
" v_x "
8507 << mean_u_all[0] <<
" v_y " << mean_u_all[1];
8508 IF_CONSTEXPR(nDim == 3) m_BCResidualStream[m_mapBndCndIdSegId[index]] << " v_z " << mean_u_all[2];
8510 m_BCResidualStream[m_mapBndCndIdSegId[index]] << " rho " << mean_rho_all << " nu " << m_solver->m_nu << " Re "
8513 if(m_solver->m_isThermal) {
8514 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
" t " << mean_t_all <<
" kappa " << m_solver->m_kappa;
8516 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
" #Cells " << totalNumberOfCells << std::endl;
8517 m_BCResidualStream[m_mapBndCndIdSegId[
index]].close();
8523 MPI_Allreduce(&numberOfCellsPerDomain, &totalNumberOfCells, 1, MPI_INT, MPI_SUM,
8524 m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"numberOfCellsPerDomain",
8525 "totalNumberOfCells");
8527 MPI_Allreduce(&mean_velocity, &mean_velocity_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]],
8528 AT_,
"mean_velocity",
"mean_velocity_all");
8529 MPI_Allreduce(&mean_rho, &mean_rho_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
8530 "mean_rho",
"mean_rho_all");
8531 MPI_Allreduce(mean_u, mean_u_all, nDim, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"mean_u",
8533 MPI_Allreduce(&mean_p_d, &mean_p_d_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
8534 "mean_p_d",
"mean_p_d_all");
8535 MPI_Allreduce(&mean_p_stat, &mean_p_stat_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
8536 "mean_p_stat",
"mean_p_stat_all");
8538 if(m_solver->m_isThermal) {
8539 MPI_Allreduce(&mean_t, &mean_t_all, 1, MPI_DOUBLE, MPI_SUM, m_BCComm[m_mapBndCndIdSegId[index]], AT_,
"mean_t",
8541 mean_t_all /= totalNumberOfCells;
8546 mean_velocity_all /= totalNumberOfCells;
8547 mean_rho_all /= totalNumberOfCells;
8549 for(
MInt n = 0; n < nDim; n++) {
8550 mean_u_all[n] /= totalNumberOfCells;
8553 mean_p_d_all /= totalNumberOfCells;
8554 mean_p_stat_all /= totalNumberOfCells;
8556 MFloat ReynoldsNr = m_referenceLength * mean_velocity_all / m_solver->m_nu;
8558 if(m_solver->domainId() == m_BCneighbors[m_mapBndCndIdSegId[index]][0]) {
8559 m_BCResidualStream[m_mapBndCndIdSegId[
index]].open(m_BCOutputFileName[m_mapBndCndIdSegId[index]],
8560 std::ios_base::app);
8561 m_BCResidualStream[m_mapBndCndIdSegId[
index]]
8566 << mean_p_stat_all <<
" Mag " << mean_velocity_all <<
" v_x " << mean_u_all[0] <<
" v_y " << mean_u_all[1];
8567 IF_CONSTEXPR(nDim == 3) m_BCResidualStream[m_mapBndCndIdSegId[index]] << " v_z " << mean_u_all[2];
8569 m_BCResidualStream[m_mapBndCndIdSegId[index]] << " rho " << mean_rho_all << " nu " << m_solver->m_nu << " Re "
8571 if(m_solver->m_isThermal) {
8572 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
" t " << mean_t_all <<
" kappa " << m_solver->m_kappa;
8574 m_BCResidualStream[m_mapBndCndIdSegId[
index]] <<
" #Cells " << totalNumberOfCells << std::endl;
8575 m_BCResidualStream[m_mapBndCndIdSegId[
index]].close();
8588template <MInt nDim, MInt nDist,
class SysEqn>
8591 if(m_refillMethodOrder == 1) {
8605template <MInt nDim, MInt nDist,
class SysEqn>
8609 ASSERT(m_solver->noHaloLayers() > 1,
8610 "linear extrapolation for refillEmergedCell, at least 2 halo layers are required!");
8612 const MInt mbCell = m_boundaryCellMappingMb[pCellId];
8613 ASSERT(mbCell > -1,
"Cell " << pCellId <<
" is no G0 Cell, thus cant be refilled!");
8616 MInt minDistDir = -1;
8617 MFloat minWallDistance = F2;
8619 if(minWallDistance > m_boundaryCellsMb.distance(mbCell,
dist)) {
8620 minWallDistance = m_boundaryCellsMb.distance(mbCell,
dist);
8621 minDistDir = Ld::oppositeDist(
dist);
8626 std::array<MFloat, nDim> l_vv{};
8628 if(m_solver->a_hasNeighbor(pCellId, minDistDir)
8629 && m_solver->a_isActive(m_solver->c_neighborId(pCellId, minDistDir))) {
8630 const MInt nghbor = m_solver->c_neighborId(pCellId, minDistDir);
8631 if(m_solver->a_hasNeighbor(nghbor, minDistDir)
8632 && m_solver->a_isActive(m_solver->c_neighborId(nghbor, minDistDir))) {
8633 const MInt nnghbor = m_solver->c_neighborId(nghbor, minDistDir);
8636 for(
MInt j = 0; j < nDist; j++) {
8637 m_solver->a_oldDistribution(pCellId, j) =
8638 F2 * m_solver->a_oldDistribution(nghbor, j) - F1 * m_solver->a_oldDistribution(nnghbor, j);
8640 m_solver->a_distribution(pCellId, j) =
8641 F2 * m_solver->a_distribution(nghbor, j) - F1 * m_solver->a_distribution(nnghbor, j);
8645 for(
MInt j = 0; j < nDist; j++) {
8646 m_solver->a_oldDistribution(pCellId, j) = m_solver->a_oldDistribution(nghbor, j);
8647 m_solver->a_distribution(pCellId, j) = m_solver->a_distribution(nghbor, j);
8652 m_solver->calculateMacroscopicVariables(pCellId, l_rho, l_vv.data());
8654 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
8655 for(
MInt n = 0; n < nDim; n++) {
8656 m_solver->a_variable(pCellId, PV->VV[n]) = l_vv[n];
8667template <MInt nDim, MInt nDist,
class SysEqn>
8671 ASSERT(m_solver->noHaloLayers() > 2,
8672 "quadratic extrapolation for refillEmergedCell, at least 3 halo layers are required!");
8674 const MInt mbCell = m_boundaryCellMappingMb[pCellId];
8675 ASSERT(mbCell > -1,
"Cell " << pCellId <<
" is no G0 Cell, thus cant be refilled!");
8678 MInt minDistDir = -1;
8679 MFloat minWallDistance = F2;
8681 if(minWallDistance > m_boundaryCellsMb.distance(mbCell,
dist)) {
8682 minWallDistance = m_boundaryCellsMb.distance(mbCell,
dist);
8683 minDistDir = Ld::oppositeDist(
dist);
8688 std::array<MFloat, nDim> l_vv{};
8690 if(m_solver->a_hasNeighbor(pCellId, minDistDir)
8691 && m_solver->a_isActive(m_solver->c_neighborId(pCellId, minDistDir))) {
8692 const MInt nghbor = m_solver->c_neighborId(pCellId, minDistDir);
8693 if(m_solver->a_hasNeighbor(nghbor, minDistDir)
8694 && m_solver->a_isActive(m_solver->c_neighborId(nghbor, minDistDir))) {
8695 const MInt nnghbor = m_solver->c_neighborId(nghbor, minDistDir);
8696 if(m_solver->a_hasNeighbor(nnghbor, minDistDir)
8697 && m_solver->a_isActive(m_solver->c_neighborId(nnghbor, minDistDir))) {
8698 const MInt nnnghbor = m_solver->c_neighborId(nnghbor, minDistDir);
8701 for(
MInt j = 0; j < nDist; j++) {
8702 m_solver->a_oldDistribution(pCellId, j) = F3 * m_solver->a_oldDistribution(nghbor, j)
8703 - F3 * m_solver->a_oldDistribution(nnghbor, j)
8704 + F1 * m_solver->a_oldDistribution(nnnghbor, j);
8706 m_solver->a_distribution(pCellId, j) = F3 * m_solver->a_distribution(nghbor, j)
8707 - F3 * m_solver->a_distribution(nnghbor, j)
8708 + F1 * m_solver->a_distribution(nnnghbor, j);
8713 for(
MInt j = 0; j < nDist; j++) {
8714 m_solver->a_oldDistribution(pCellId, j) =
8715 F2 * m_solver->a_oldDistribution(nghbor, j) - F1 * m_solver->a_oldDistribution(nnghbor, j);
8717 m_solver->a_distribution(pCellId, j) =
8718 F2 * m_solver->a_distribution(nghbor, j) - F1 * m_solver->a_distribution(nnghbor, j);
8724 for(
MInt j = 0; j < nDist; j++) {
8725 m_solver->a_oldDistribution(pCellId, j) = m_solver->a_oldDistribution(nghbor, j);
8726 m_solver->a_distribution(pCellId, j) = m_solver->a_distribution(nghbor, j);
8731 m_solver->calculateMacroscopicVariables(pCellId, l_rho, l_vv.data());
8733 m_solver->a_variable(pCellId, PV->RHO) = l_rho;
8734 for(
MInt n = 0; n < nDim; n++) {
8735 m_solver->a_variable(pCellId, PV->VV[n]) = l_vv[n];
8739template <MInt nDim, MInt nDist,
class SysEqn>
8744 const MInt pCellId = m_solver->m_G0CellList[cellIndex];
8745 MFloat l_t = m_solver->m_initTemperatureKelvin;
8746 std::array<MFloat, nDim> uW{};
8747 getBoundaryVelocityMb(cellIndex, uW.data());
8750 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
8751 for(
MInt j = 0; j < nDist - 1; j++) {
8752#ifdef WAR_NVHPC_PSTL
8753 const MFloat q = m_distances[cellIndex][j];
8754 const MInt opposite = m_solver->m_oppositeDist[j];
8756 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
8757 const MInt opposite = Ld::oppositeDist(j);
8760 if(m_solver->m_innerEnergy) {
8761 s = zerothMomentSourceTerm<1>(pCellId, opposite, l_t, uW.data());
8762 }
else if(m_solver->m_totalEnergy) {
8763 s = zerothMomentSourceTerm<2>(pCellId, opposite, l_t, uW.data());
8765 s = zerothMomentSourceTerm<0>(pCellId, opposite, l_t, uW.data());
8767 const MFloat sourceTerm = s;
8769 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
8773 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
8774 const MFloat F2q = F2 * q;
8775 m_solver->a_oldDistributionThermal(pCellId, opposite) =
8776 (-F2q * m_solver->a_distributionThermal(pCellId, j))
8777 + ((F2q - F1) * m_solver->a_oldDistributionThermal(pCellId, j)) + sourceTerm;
8782 m_solver->a_oldDistributionThermal(pCellId, opposite) =
8783 -m_solver->a_distributionThermal(pCellId, j) + sourceTerm;
8790 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
8791 m_solver->a_oldDistributionThermal(pCellId, opposite) =
8792 m_solver->a_distributionThermal(pCellId, j) + sourceTerm;
8799 for(
MInt j = 0; j < nDist - 1; j++) {
8800#ifdef WAR_NVHPC_PSTL
8801 const MFloat q = m_distances[cellIndex][j];
8802 const MInt opposite = m_solver->m_oppositeDist[j];
8804 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
8805 const MInt opposite = Ld::oppositeDist(j);
8809 if(m_solver->a_hasNeighbor(pCellId, j)) {
8811 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
8812 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
8813 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
8816 if(m_solver->m_innerEnergy) {
8817 s = zerothMomentSourceTerm<1>(neighborId, j, l_t, uW.data());
8818 }
else if(m_solver->m_totalEnergy) {
8819 s = zerothMomentSourceTerm<2>(neighborId, j, l_t, uW.data());
8821 s = zerothMomentSourceTerm<0>(neighborId, j, l_t, uW.data());
8823 const MFloat sourceTerm = s;
8826 const MFloat F2q = F2 * (F1 - q);
8829 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
8830 m_solver->a_oldDistributionThermal(neighborId, j) =
8831 -(m_solver->a_distributionThermal(neighborId, opposite) / F2q)
8832 + (m_solver->a_distributionThermal(neighborId, j) * (F2q - F1) / F2q) + (F1 / F2q) * sourceTerm;
8841 m_solver->setEqDistsThermal(pCellId, l_t, F1, uW.data());
8843 m_solver->a_variable(pCellId, PV->T) = l_t;
8844 m_solver->a_oldVariable(pCellId, PV->T) = l_t;
8848template <MInt nDim, MInt nDist,
class SysEqn>
8853 const MInt pCellId = m_solver->m_G0CellList[cellIndex];
8854 MFloat l_c = m_solver->m_initCon;
8855 std::array<MFloat, nDim> uW{};
8856 getBoundaryVelocityMb(cellIndex, uW.data());
8859 if(m_solver->a_levelSetFunctionMB(pCellId, set) > 0) {
8860 for(
MInt j = 0; j < nDist - 1; j++) {
8861#ifdef WAR_NVHPC_PSTL
8862 const MFloat q = m_distances[cellIndex][j];
8863 const MInt opposite = m_solver->m_oppositeDist[j];
8865 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
8866 const MInt opposite = Ld::oppositeDist(j);
8868 const MFloat sourceTerm = zerothMomentSourceTerm<0>(pCellId, opposite, l_c, uW.data());
8870 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo))
continue;
8874 if(m_solver->a_hasNeighbor(pCellId, opposite) != 0) {
8875 const MFloat F2q = F2 * q;
8876 m_solver->a_oldDistributionTransport(pCellId, opposite) =
8877 (-F2q * m_solver->a_distributionTransport(pCellId, j))
8878 + ((F2q - F1) * m_solver->a_oldDistributionTransport(pCellId, j)) + sourceTerm;
8883 m_solver->a_oldDistributionTransport(pCellId, opposite) =
8884 -m_solver->a_distributionTransport(pCellId, j) + sourceTerm;
8891 else if(q > 0.5 && m_solver->a_hasNeighbor(pCellId, j) == 0) {
8892 m_solver->a_oldDistributionTransport(pCellId, opposite) =
8893 m_solver->a_distributionTransport(pCellId, j) + sourceTerm;
8900 for(
MInt j = 0; j < nDist - 1; j++) {
8901#ifdef WAR_NVHPC_PSTL
8902 const MFloat q = m_distances[cellIndex][j];
8903 const MInt opposite = m_solver->m_oppositeDist[j];
8905 const MFloat q = getDistanceMb(pCellId, cellIndex, j);
8906 const MInt opposite = Ld::oppositeDist(j);
8910 if(m_solver->a_hasNeighbor(pCellId, j)) {
8912 const MInt neighborId = m_solver->c_neighborId(pCellId, j);
8913 if(!m_solver->a_hasProperty(neighborId, Cell::IsHalo)) {
8914 const MBool nbndid = m_solver->a_isG0CandidateOfSet(neighborId, (set - m_solver->m_levelSetId));
8916 const MFloat sourceTerm = zerothMomentSourceTerm<0>(neighborId, j, l_c, uW.data());
8919 const MFloat F2q = F2 * (F1 - q);
8922 if(!nbndid || m_solver->a_levelSetFunctionMB(neighborId, set) > 0) {
8923 m_solver->a_oldDistributionTransport(neighborId, j) =
8924 -(m_solver->a_distributionTransport(neighborId, opposite) / F2q)
8925 + (m_solver->a_distributionTransport(neighborId, j) * (F2q - F1) / F2q) + (F1 / F2q) * sourceTerm;
8934 m_solver->setEqDistsTransport(pCellId, l_c, uW.data());
8935 m_solver->a_variable(pCellId, PV->C) = l_c;
8936 m_solver->a_oldVariable(pCellId, PV->C) = l_c;
8945template <MInt nDim, MInt nDist,
class SysEqn>
8949 const MInt setId = 0;
8951 for(
MInt cellIndex = 0; cellIndex < m_boundaryCellsMb.size(); cellIndex++) {
8953 ASSERT(m_boundaryCellsMb.distance(cellIndex,
dist) >= 0.0,
"boundary cell collector: no valid dist");
8957 for(
MInt cellIndex = 0; cellIndex < m_boundaryCellsMb.size(); cellIndex++) {
8958 const MInt pCellId = m_boundaryCellsMb.cellId(cellIndex);
8961 MInt minDistDir = -1;
8962 MFloat minWallDistance = F2;
8964 if(minWallDistance > m_boundaryCellsMb.distance(cellIndex,
dist)) {
8965 minWallDistance = m_boundaryCellsMb.distance(cellIndex,
dist);
8970 ASSERT(minDistDir > -1,
"minDistDir not found!");
8972 minWallDistance = getDistanceMb(pCellId, cellIndex, minDistDir);
8974 ASSERT(minDistDir > -1,
"No min dist found.");
8976 if(m_solver->a_levelSetFunctionMB(pCellId, setId) > 0) {
8979 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
8983 const MInt opposite = Ld::oppositeDist(minDistDir);
8984 const MFloat q = minWallDistance;
8985 const MInt neighbor = m_solver->c_neighborId(pCellId, opposite);
8989 for(
MInt n = 0; n < nDim; n++) {
8990 m_boundaryCellsMb.velocity(cellIndex, n) =
8991 m_solver->a_variable(pCellId, n) * (1 + q) - m_solver->a_variable(neighbor, n) * q;
8996 std::cerr <<
"Velocity extrapolation to surface: zero order fallback. (inside)"
8997 <<
"(gid " << m_solver->c_globalId(pCellId) <<
" )" << std::endl;
8998 for(
MInt n = 0; n < nDim; n++) {
8999 m_boundaryCellsMb.velocity(cellIndex, n) = m_solver->a_variable(pCellId, n);
9005 const MFloat q = 1 - minWallDistance;
9006 const MInt neighbor = m_solver->c_neighborId(pCellId, minDistDir);
9008 const MInt nneighbor = m_solver->c_neighborId(neighbor, minDistDir);
9010 if(nneighbor > -1) {
9012 for(
MInt n = 0; n < nDim; n++) {
9013 m_boundaryCellsMb.velocity(cellIndex, n) =
9014 m_solver->a_variable(neighbor, n) * (2 - q) - m_solver->a_variable(nneighbor, n) * (1 - q);
9018 for(
MInt n = 0; n < nDim; n++) {
9019 m_boundaryCellsMb.velocity(cellIndex, n) = m_solver->a_variable(neighbor, n);
9026 for(
MInt mbCell = 0; mbCell < m_boundaryCellsMb.size(); mbCell++) {
9027 const MInt pCellId = m_boundaryCellsMb.cellId(mbCell);
9028 if(m_solver->a_hasProperty(pCellId, Cell::IsHalo)) {
9032 if(std::isnan(m_boundaryCellsMb.velocity(mbCell, 0)) || std::isnan(m_boundaryCellsMb.velocity(mbCell, 1))) {
9033 std::cout <<
"vel nan for "
9034 <<
"(gid " << m_solver->c_globalId(pCellId) <<
" )" << std::endl;
9035 TERMM(1,
"Velocity extrapolation nan");
9052template <MInt nDim, MInt nDist,
class SysEqn>
9053template <MU
int type>
9057#ifdef WAR_NVHPC_PSTL
9058 MFloat var[nDim + 1] = {F0};
9059 for(
MInt d = 0; d < nDim + 1; d++) {
9060 var[d] = m_solver->a_variable(cellId, d);
9062 MFloat*
const ptr0 = var;
9064 MFloat*
const ptr0 = &m_solver->a_variable(cellId, 0);
9066 const MFloat F1Brho0 = 1.0 / ptr0[PV->RHO];
9075 constexpr MFloat factorThomson = 1.0;
9077 constexpr MFloat sigma = 0.59;
9078 constexpr MFloat rho_trg = 1.0;
9080 sigma * (1 - m_Ma * m_Ma) * LBCS / (m_domainLength *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(cellId)));
9084 const MInt ind = m_mapSegIdsInOutCnd[
index];
9085 for(
MInt i = 0; i < nDim; i++) {
9086 const MFloat u_trg = m_initialVelocityVecs[ind][i] * m_Ma * LBCS;
9087 L_approx[i] = k_relax * (ptr0[PV->VV[i]] - u_trg);
9092 const MFloat L_approx_ = k_relax * CSsq * (ptr0[PV->RHO] - rho_trg);
9093 for(
MInt i = 0; i < nDim; i++) {
9094 L_approx[i] = L_approx_;
9102 const MInt pvVv[3] = {PV->VV[0], PV->VV[1], PV->VV[2]};
9103 for(
MInt c = 0; c < nDim; c++) {
9104 const MInt dir1 = 2 * c;
9105 const MInt dir2 = 2 * c + 1;
9106 const MBool isTangentialDir = (m_solver->a_hasNeighbor(cellId, dir1) && m_solver->a_hasNeighbor(cellId, dir2));
9107 if(isTangentialDir) {
9109 const MInt nghbrId1 = m_solver->c_neighborId(cellId, dir1);
9110 const MInt nghbrId2 = m_solver->c_neighborId(cellId, dir2);
9111#ifdef WAR_NVHPC_PSTL
9112 MFloat var_n1[nDim + 1] = {F0};
9113 for(
MInt d = 0; d < nDim + 1; d++) {
9114 var_n1[d] = m_solver->a_variable(nghbrId1, d);
9116 MFloat*
const ptr1 = var_n1;
9117 MFloat var_n2[nDim + 1] = {F0};
9118 for(
MInt d = 0; d < nDim + 1; d++) {
9119 var_n2[d] = m_solver->a_variable(nghbrId2, d);
9121 MFloat*
const ptr2 = var_n2;
9123 MFloat*
const ptr1 = &m_solver->a_variable(nghbrId1, 0);
9124 MFloat*
const ptr2 = &m_solver->a_variable(nghbrId2, 0);
9126 const MFloat F1Brho1 = 1.0 / ptr1[PV->RHO];
9127 const MFloat F1Brho2 = 1.0 / ptr2[PV->RHO];
9130 const MFloat rho_x = 0.5 * (ptr2[PV->RHO] - ptr1[PV->RHO]);
9132 for(
MInt j = 0; j < nDim; j++) {
9133 u_x[j] = 0.5 * (ptr2[PV->VV[j]] * F1Brho2 - ptr1[PV->VV[j]] * F1Brho1);
9136 rho_t -= factorThomson * (ptr0[pvVv[c]] * F1Brho0 * rho_x + u_x[c] * ptr0[PV->RHO]);
9137 u_t[c] -= factorThomson * (F1Brho0 * CSsq * rho_x);
9138 for(
MInt j = 0; j < nDim; j++) {
9139 u_t[j] -= factorThomson * (F1Brho0 * ptr0[pvVv[c]] * u_x[j]);
9167 if(m_solver->a_hasNeighbor(cellId, dir1)) {
9169 }
else if(m_solver->a_hasNeighbor(cellId, dir2)) {
9172 TERMM(1,
"Boundary cell with no neighbor in normal direction?");
9174 const MInt nghbrId1 = m_solver->c_neighborId(cellId, dir);
9175 const MInt nghbrId2 = m_solver->c_neighborId(nghbrId1, dir);
9176 const MInt sign = (dir % 2 == 0) ? 1 : -1;
9177#ifdef WAR_NVHPC_PSTL
9179 for(
MInt d = 0; d < nDim + 1; d++) {
9180 var_n1[d] = m_solver->a_variable(nghbrId1, d);
9182 MFloat*
const ptr1 = var_n1;
9184 for(
MInt d = 0; d < nDim + 1; d++) {
9185 var_n2[d] = m_solver->a_variable(nghbrId2, d);
9187 MFloat*
const ptr2 = var_n2;
9189 MFloat*
const ptr1 = &m_solver->a_variable(nghbrId1, 0);
9190 MFloat*
const ptr2 = &m_solver->a_variable(nghbrId2, 0);
9192 const MFloat F1Brho1 = 1.0 / ptr1[PV->RHO];
9193 const MFloat F1Brho2 = 1.0 / ptr2[PV->RHO];
9196 const MFloat rho_x = sign * (F3B2 * ptr0[PV->RHO] - F2 * ptr1[PV->RHO] + F1B2 * ptr2[PV->RHO]);
9198 for(
MInt j = 0; j < nDim; j++) {
9202 * (F3B2 * ptr0[PV->VV[j]] * F1Brho0 - F2 * ptr1[PV->VV[j]] * F1Brho1 + F1B2 * ptr2[PV->VV[j]] * F1Brho2);
9206 const MBool flowPointsInwards = (ptr0[pvVv[c]] * sign < 0);
9207 if(flowPointsInwards) {
9209 for(
MInt j = 0; j < nDim; j++) {
9211 L[
id] = L_approx[j];
9217 for(
MInt j = 0; j < nDim; j++) {
9219 L[
id] = ptr0[pvVv[c]] * F1Brho0 * u_x[j];
9227 L[nDim] = (ptr0[pvVv[c]] * F1Brho0 + LBCS) * (CSsq * rho_x + LBCS * ptr0[PV->RHO] * u_x[c]);
9230 L[0] = (ptr0[pvVv[c]] * F1Brho0 - LBCS) * (CSsq * rho_x - LBCS * ptr0[PV->RHO] * u_x[c]);
9231 L[nDim] = L_approx[c];
9234 rho_t -= F1B2 * F1BCSsq * (L[nDim] + L[0]);
9236 for(
MInt j = 0; j < nDim; j++) {
9241 u_t[c] -= F1B2 * F1BCS * F1Brho0 * (L[nDim] - L[0]);
9247 rho_b = m_solver->a_variable(cellId, PV->RHO) + rho_t;
9248 for(
MInt j = 0; j < nDim; j++) {
9249 u_b[j] = m_solver->a_variable(cellId, PV->VV[j]) * F1Brho0 + u_t[j];
9266template <MInt nDim, MInt nDist,
class SysEqn>
9269 constexpr MFloat deltaT = 1;
9270 constexpr MFloat sigma = 0.59;
9271 constexpr MFloat kappa = 1.0;
9272 constexpr MFloat sqrtKappa = 1.0;
9276 MFloat*
const formerVariables = this->m_bndCndData[
index].data;
9277 const MInt noBcVars = this->m_bndCndData[
index].noVars;
9278 const MInt offset = m_bndCndOffsets[
index];
9280 const MInt currentId = m_bndCells[bndCellId].m_cellId;
9281 const MInt iMo = (bndCellId - offset) * noBcVars;
9284 sigma * (1 - m_Ma * m_Ma) * sqrtKappa * LBCS
9286 *
FFPOW2(m_solver->maxLevel()
9287 - m_solver->a_level(currentId)));
9290 const MFloat rho_trg = (m_densityFluctuations) ? 0.0 : 1.0;
9291 const MFloat rho_offset = (m_densityFluctuations) ? 1.0 : 0.0;
9294 auto subTimeDerivatives = [&](
MInt direction2,
MFloat& rho_t,
MFloat* u_t) {
9295 const MInt nghbrId = m_solver->c_neighborId(currentId, Ld::oppositeDist(direction2));
9303 * (8 * formerVariables[iMo + PV->RHO]
9304 - 9 * F1B2 * (m_solver->a_variable(currentId, PV->RHO) + m_solver->a_oldVariable(currentId, PV->RHO))
9305 + F1B2 * (m_solver->a_variable(nghbrId, PV->RHO) + m_solver->a_oldVariable(nghbrId, PV->RHO)));
9306 const MFloat der_p = kappa * CSsq * der_rho;
9309 * (8 * formerVariables[iMo + PV->U]
9310 - 9 * F1B2 * (m_solver->a_variable(currentId, PV->U) + m_solver->a_oldVariable(currentId, PV->U))
9311 + F1B2 * (m_solver->a_variable(nghbrId, PV->U) + m_solver->a_oldVariable(nghbrId, PV->U)));
9314 * (8 * formerVariables[iMo + PV->V]
9315 - 9 * F1B2 * (m_solver->a_variable(currentId, PV->V) + m_solver->a_oldVariable(currentId, PV->V))
9316 + F1B2 * (m_solver->a_variable(nghbrId, PV->V) + m_solver->a_oldVariable(nghbrId, PV->V)));
9319 * (8 * formerVariables[iMo + PV->W]
9320 - 9 * F1B2 * (m_solver->a_variable(currentId, PV->W) + m_solver->a_oldVariable(currentId, PV->W))
9321 + F1B2 * (m_solver->a_variable(nghbrId, PV->W) + m_solver->a_oldVariable(nghbrId, PV->W)));
9332 switch(direction2) {
9335 L1 = (formerVariables[iMo + PV->U] - sqrtKappa * LBCS)
9336 * (-der_p - (formerVariables[iMo + PV->RHO] + rho_offset) * (-der_u) * sqrtKappa * LBCS);
9338 L3 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9343 u_t[0] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9348 L1 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9351 L3 = formerVariables[iMo + PV->U] * der_v;
9352 L4 = formerVariables[iMo + PV->U] * der_w;
9353 L5 = (formerVariables[iMo + PV->U] + sqrtKappa * LBCS)
9354 * (der_p + (formerVariables[iMo + PV->RHO] + rho_offset) * der_u * sqrtKappa * LBCS);
9357 u_t[0] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9363 L1 = (formerVariables[iMo + PV->V] - sqrtKappa * LBCS)
9364 * (-der_p - (formerVariables[iMo + PV->RHO] + rho_offset) * (-der_v) * sqrtKappa * LBCS);
9366 L3 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9372 u_t[1] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9376 L1 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9378 L3 = formerVariables[iMo + PV->V] * der_u;
9379 L4 = formerVariables[iMo + PV->V] * der_w;
9380 L5 = (formerVariables[iMo + PV->V] + sqrtKappa * LBCS)
9381 * (der_p + (formerVariables[iMo + PV->RHO] + rho_offset) * der_v * sqrtKappa * LBCS);
9385 u_t[1] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9390 L1 = (formerVariables[iMo + PV->W] - sqrtKappa * LBCS)
9391 * (-der_p - (formerVariables[iMo + PV->RHO] + rho_offset) * (-der_w) * sqrtKappa * LBCS);
9393 L3 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9400 u_t[2] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9403 L1 = k_relax * kappa * CSsq * (formerVariables[iMo + PV->RHO] - rho_trg);
9405 L3 = formerVariables[iMo + PV->W] * der_u;
9406 L4 = formerVariables[iMo + PV->W] * der_v;
9407 L5 = (formerVariables[iMo + PV->W] + sqrtKappa * LBCS)
9408 * (der_p + (formerVariables[iMo + PV->RHO] + rho_offset) * der_w * sqrtKappa * LBCS);
9413 u_t[2] += (L5 - L1) * F1B2 * (F1BCS / sqrtKappa) / (formerVariables[iMo + PV->RHO] + rho_offset);
9416 TERMM(1,
"Unrealistic case, please check your Boundary Conditions!!!");
9420 rho_t = (F1BCSsq / kappa) * (F1B2 * (L5 + L1) + L2);
9424 for(
MInt d = 0; d < nDim * 2; d++) {
9425 if(m_solver->a_hasNeighbor(currentId, d) == 0) {
9426 subTimeDerivatives(d, rho_t, u_t);
9430 rho_b = formerVariables[iMo + PV->RHO] - deltaT * rho_t;
9431 u_b[0] = formerVariables[iMo + PV->U] - deltaT * u_t[0];
9432 u_b[1] = formerVariables[iMo + PV->V] - deltaT * u_t[1];
9433 u_b[2] = formerVariables[iMo + PV->W] - deltaT * u_t[2];
9435 formerVariables[iMo + PV->RHO] = rho_b;
9436 formerVariables[iMo + PV->U] = u_b[0];
9437 formerVariables[iMo + PV->V] = u_b[1];
9438 formerVariables[iMo + PV->W] = u_b[2];
9449template <MInt nDim, MInt nDist,
class SysEqn>
9453 constexpr MFloat kappa = 1.0;
9455 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9456 const MInt currentId = m_bndCells[i].m_cellId;
9458 || m_solver->a_isHalo(currentId) || !m_solver->a_hasNeighbor(currentId, Ld::oppositeDist(direction))) {
9464 calcCharValuesOnFace(index, direction, i, rho_b, &u_b[0]);
9467 const MFloat rho_offset = (m_densityFluctuations) ? 1.0 : 0.0;
9469 for(
MInt n = 0; n < nDim; n++) {
9471 c[2 * n + 1] = u_b[n];
9474 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
9475 const MInt dir = Ld::componentFld(direction, j);
9476 if(m_solver->a_hasNeighbor(currentId, dir) == 0) {
9479 if(dir < Ld::distFld(0)) {
9483 if(dir < (Ld::distFld(0) + Ld::distFld(1))) {
9484 const MInt k = dir - Ld::distFld(0);
9485 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
9488 const MInt k = dir - (Ld::distFld(0) + Ld::distFld(1));
9489 tmpUW = (c[Ld::mFld2(3 * k)] + c[Ld::mFld2(3 * k + 1)] + c[Ld::mFld2(3 * k + 2)]);
9494 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(dir)) =
9495 m_solver->a_distribution(currentId, dir)
9496 - 2.0 * Ld::tp(tpIndex) * (rho_b + rho_offset) * (F1BCSsq / kappa) * tmpUW;
9506 constexpr MInt nDim = 2;
9509 L1 = L2 = L3 = L4 = F0;
9515 MFloat sqrtKappa = sqrt(1.2);
9516 MInt currentID, nghbrID, tpIndex, k;
9518 MFloat k_relax = sigma * (1 - m_Ma * m_Ma) * sqrtKappa * LBCS / m_solver->c_cellLengthAtLevel(0);
9519 MFloat der_u, der_v, der_p;
9522 MFloat*
const formerVariables = this->m_bndCndData[
index].data;
9523 const MInt offset = m_bndCndOffsets[
index];
9525 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9526 currentID = m_bndCells[i].m_cellId;
9527 nghbrID = m_solver->c_neighborId(currentID, Ld::oppositeDist(direction));
9528 constexpr MInt noBcVars = nDim + 1;
9529 const MInt iMo = (i - offset) * noBcVars;
9541 if(direction == 0) {
9543 * (-8 * formerVariables[iMo + PV->RHO]
9544 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->RHO) + m_solver->a_oldVariable(currentID, PV->RHO))
9545 - F1B2 * (m_solver->a_oldVariable(nghbrID, PV->RHO) + m_solver->a_variable(nghbrID, PV->RHO)));
9549 * (-8 * formerVariables[iMo + PV->U]
9550 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->U) + m_solver->a_oldVariable(currentID, PV->U))
9551 - F1B2 * (m_solver->a_variable(nghbrID, PV->U) + m_solver->a_oldVariable(nghbrID, PV->U)));
9555 * (-8 * formerVariables[iMo + PV->V]
9556 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->V) + m_solver->a_oldVariable(currentID, PV->V))
9557 - F1B2 * (m_solver->a_variable(nghbrID, PV->V) + m_solver->a_oldVariable(nghbrID, PV->V)));
9560 L1 = (formerVariables[iMo + PV->U] - sqrtKappa * LBCS)
9561 * (der_p - formerVariables[iMo + PV->RHO] * der_u * sqrtKappa * LBCS);
9562 L2 = k_relax * F1B3 * (formerVariables[iMo + PV->U] - 0);
9565 }
else if(direction == 1) {
9567 * (8 * formerVariables[iMo + PV->RHO]
9568 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->RHO) + m_solver->a_oldVariable(currentID, PV->RHO))
9569 + F1B2 * (m_solver->a_oldVariable(nghbrID, PV->RHO) + m_solver->a_variable(nghbrID, PV->RHO)));
9573 * (8 * formerVariables[iMo + PV->U]
9574 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->U) + m_solver->a_oldVariable(currentID, PV->U))
9575 + F1B2 * (m_solver->a_variable(nghbrID, PV->U) + m_solver->a_oldVariable(nghbrID, PV->U)));
9579 * (8 * formerVariables[iMo + PV->V]
9580 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->V) + m_solver->a_oldVariable(currentID, PV->V))
9581 + F1B2 * (m_solver->a_variable(nghbrID, PV->V) + m_solver->a_oldVariable(nghbrID, PV->V)));
9583 L1 = k_relax * F1B3 * (formerVariables[iMo + PV->U] - ub);
9584 L2 = formerVariables[iMo + PV->U] * der_v;
9586 L4 = (formerVariables[iMo + PV->U] + sqrtKappa * LBCS)
9587 * (der_p + formerVariables[iMo + PV->RHO] * der_u * sqrtKappa * LBCS);
9589 TERMM(1,
"Direction can only be 0 or 1 in D2Q9!");
9593 u1 = formerVariables[iMo + PV->U] - deltaT * F1B2 / formerVariables[iMo + PV->RHO] * F1BCS / sqrtKappa * (L4 - L1);
9594 u2 = formerVariables[iMo + PV->V] - deltaT * L2;
9595 rho = formerVariables[iMo + PV->RHO] - deltaT * F1B2 / kappa * F1BCSsq * (L4 + L1)
9596 - F1BCSsq * L3 / kappa;
9603 for(
MInt j = 0; j < 8; j++) {
9604 if(m_solver->a_hasNeighbor(currentID, j) == 0) {
9610 k = j - Ld::distFld(0);
9611 tmpUW = (c[Ld::mFld1(2 * k)] + c[Ld::mFld1(2 * k + 1)]);
9616 m_solver->a_oldDistribution(currentID, Ld::oppositeDist(j)) =
9617 m_solver->a_distribution(currentID, j)
9618 - 2.0 * Ld::tp(tpIndex) * rho * F1BCSsq * tmpUW;
9636 formerVariables[iMo + 0] = u1;
9637 formerVariables[iMo + 1] = u2;
9638 formerVariables[iMo + 2] = rho;
9650template <MInt nDim, MInt nDist,
class SysEqn>
9654 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9655 const MInt currentId = m_bndCells[i].m_cellId;
9657 || m_solver->a_isHalo(currentId)) {
9662 calcCharValues<1>(index, currentId, rho_b, &u_b[0]);
9664#ifdef WAR_NVHPC_PSTL
9665 MFloat oldDist[nDist] = {F0};
9666 for(
MInt d = 0; d < nDist; d++) {
9667 oldDist[d] = m_solver->a_oldDistribution(currentId, d);
9669 sysEqn().calcEqDists(rho_b, &u_b[0], oldDist);
9670 for(
MInt d = 0; d < nDist; d++) {
9671 m_solver->a_oldDistribution(currentId, d) = oldDist[d];
9674 sysEqn().calcEqDists(rho_b, &u_b[0], &m_solver->a_oldDistribution(currentId, 0));
9688template <MInt nDim, MInt nDist,
class SysEqn>
9697 constexpr MFloat kappa = 1.0;
9699 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9700 const MInt currentId = m_bndCells[i].m_cellId;
9702 || m_solver->a_isHalo(currentId) || !m_solver->a_hasNeighbor(currentId, Ld::oppositeDist(direction))) {
9708 calcCharValuesOnFace(index, direction, i, rho_b, &u_b[0]);
9712 const MFloat squaredU_b = std::inner_product(&u_b[0], &u_b[nDim], &u_b[0], .0);
9714 const MInt tmpDistId0 = Ld::distFld(0);
9715 const MInt tmpDistId1 = Ld::distFld(1);
9716 const MInt tmpDistId2 = Ld::distFld(2);
9719 for(
MInt n = 0; n < nDim; n++) {
9721 b[2 * n + 1] = u_b[n];
9726 for(
MInt j = 0; j < tmpDistId0; j++) {
9727 eqSym[j] = Ld::tp(1) * (F1BCSsq / kappa)
9728 * (rho_b * (CSsq * kappa) +
b[j] *
b[j] * (F1BCSsq / kappa) * F1B2 - squaredU_b * F1B2);
9731 for(
MInt j = 0; j < tmpDistId1; j++) {
9732 const MFloat tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
9733 eqSym[tmpDistId0 + j] = Ld::tp(2) * (F1BCSsq / kappa)
9734 * (rho_b * (CSsq * kappa) + tmp * tmp * (F1BCSsq / kappa) * F1B2 - squaredU_b * F1B2);
9738 const MInt tmpDistId = tmpDistId0 + tmpDistId1;
9739 for(
MInt j = 0; j < tmpDistId2; j++) {
9740 const MFloat tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
9741 eqSym[tmpDistId + j] = Ld::tp(3) * (F1BCSsq / kappa)
9742 * (rho_b * (CSsq * kappa) + tmp * tmp * (F1BCSsq / kappa) * F1B2 - squaredU_b * F1B2);
9748#ifdef WAR_NVHPC_PSTL
9750 for(
MInt d = 0; d < nDim; d++) {
9751 u[d] = m_solver->a_variable(currentId, d);
9753 const MFloat*
const l_uu = u;
9755 const MFloat*
const l_uu = &m_solver->a_variable(currentId, PV->VV[0]);
9757 const MFloat l_rho = m_solver->a_variable(currentId, PV->RHO);
9758 for(
MInt n = 0; n < nDim; n++) {
9759 b[2 * n] = -l_uu[n];
9760 b[2 * n + 1] = l_uu[n];
9762 const MFloat squaredU = std::inner_product(&l_uu[0], &l_uu[nDim], &l_uu[0], .0);
9764 MFloat eqSymC[nDist - 1];
9766 for(
MInt j = 0; j < tmpDistId0; j++) {
9768 Ld::tp(1) * (F1BCSsq / kappa) * (l_rho * (CSsq * kappa) +
b[j] *
b[j] * F1BCSsq * F1B2 - squaredU * F1B2);
9773 const MInt tmpDistId = tmpDistId0;
9774 for(
MInt j = 0; j < tmpDistId1; j++) {
9775 const MFloat tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
9776 eqSymC[tmpDistId + j] = Ld::tp(2) * (F1BCSsq / kappa)
9777 * (l_rho * (CSsq * kappa) + tmp * tmp * (F1BCSsq / kappa) * F1B2 - squaredU * F1B2);
9783 const MInt tmpDistId = tmpDistId0 + tmpDistId1;
9784 for(
MInt j = 0; j < tmpDistId2; j++) {
9785 const MFloat tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
9786 eqSymC[tmpDistId + j] = Ld::tp(3) * (F1BCSsq / kappa)
9787 * (l_rho * (CSsq * kappa) + tmp * tmp * (F1BCSsq / kappa) * F1B2 - squaredU * F1B2);
9793 MFloat meanDist[nDist - 1];
9795 for(
MInt j = 0; j < nDist - 1; j++) {
9798 * (m_solver->a_oldDistribution(currentId, j) + m_solver->a_oldDistribution(currentId, Ld::oppositeDist(j)));
9804 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentId) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentId)));
9806 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
9807 const MInt dir = Ld::componentFld(direction, j);
9808 m_solver->a_oldDistribution(currentId, Ld::oppositeDist(dir)) =
9809 -m_solver->a_distribution(currentId, dir) + 2 * eqSym[dir] + (2 - omega) * (meanDist[dir] - eqSymC[dir]);
9818 constexpr MInt nDim = 2;
9821 L1 = L2 = L3 = L4 = F0;
9822 MFloat rho, u1, u2, rho_b, u1c, u2c, rhoc;
9829 MFloat sqrtKappa = sqrt(kappa);
9830 MInt currentID, nghbrID;
9832 MFloat der_u, der_p, der_v;
9837 MFloat*
const formerVariables = this->m_bndCndData[
index].data;
9838 const MInt offset = m_bndCndOffsets[
index];
9840 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9841 currentID = m_bndCells[i].m_cellId;
9842 constexpr MInt noBcVars = nDim + 1;
9843 const MInt iMo = (i - offset) * noBcVars;
9845 k_relax = sigma * (1 - m_Ma * m_Ma) * sqrtKappa * LBCS
9847 *
FFPOW2(m_solver->maxLevel()
9848 - m_solver->a_level(currentID)));
9852 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentID) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentID)));
9856 formerVariables[iMo + 0] = m_solver->a_variable(currentID, PV->U);
9857 formerVariables[iMo + 1] = m_solver->a_variable(currentID, PV->V);
9858 formerVariables[iMo + 2] = m_solver->a_variable(currentID, PV->RHO);
9860 nghbrID = m_solver->c_neighborId(currentID, Ld::oppositeDist(direction));
9862 if(m_solver->a_hasNeighbor(currentID, direction) == 0) {
9865 if(direction == 1) {
9868 * (8 * formerVariables[iMo + PV->RHO]
9869 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->RHO) + m_solver->a_oldVariable(currentID, PV->RHO))
9870 + F1B2 * (m_solver->a_oldVariable(nghbrID, PV->RHO) + m_solver->a_variable(nghbrID, PV->RHO)));
9874 * (8 * formerVariables[iMo + PV->U]
9875 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->U) + m_solver->a_oldVariable(currentID, PV->U))
9876 + F1B2 * (m_solver->a_variable(nghbrID, PV->U) + m_solver->a_oldVariable(nghbrID, PV->U)));
9880 * (8 * formerVariables[iMo + PV->V]
9881 - 9 * F1B2 * (m_solver->a_variable(currentID, PV->V) + m_solver->a_oldVariable(currentID, PV->V))
9882 + F1B2 * (m_solver->a_variable(nghbrID, PV->V) + m_solver->a_oldVariable(nghbrID, PV->V)));
9884 L1 = k_relax * F1B3 * (formerVariables[iMo + PV->RHO] - rho_b);
9885 L2 = formerVariables[iMo + PV->U] * der_v;
9887 L4 = (formerVariables[iMo + PV->U] + sqrtKappa * LBCS)
9888 * (der_p + formerVariables[iMo + PV->RHO] * der_u * sqrtKappa * LBCS);
9889 }
else if(direction == 0) {
9892 * (-8 * formerVariables[iMo + PV->RHO]
9893 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->RHO) + m_solver->a_oldVariable(currentID, PV->RHO))
9894 - F1B2 * (m_solver->a_oldVariable(nghbrID, PV->RHO) + m_solver->a_variable(nghbrID, PV->RHO)));
9898 * (-8 * formerVariables[iMo + PV->U]
9899 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->U) + m_solver->a_oldVariable(currentID, PV->U))
9900 - F1B2 * (m_solver->a_variable(nghbrID, PV->U) + m_solver->a_oldVariable(nghbrID, PV->U)));
9904 * (-8 * formerVariables[iMo + PV->V]
9905 + 9 * F1B2 * (m_solver->a_variable(currentID, PV->V) + m_solver->a_oldVariable(currentID, PV->V))
9906 - F1B2 * (m_solver->a_variable(nghbrID, PV->V) + m_solver->a_oldVariable(nghbrID, PV->V)));
9909 L1 = (formerVariables[iMo + PV->U] - sqrtKappa * LBCS)
9910 * (der_p - formerVariables[iMo + PV->RHO] * der_u * sqrtKappa * LBCS);
9911 L2 = k_relax * F1B3 * (formerVariables[iMo + PV->RHO] - rho_b);
9915 TERMM(1,
"Direction can only be 0 or 1 in D2Q9!");
9919 u1 = formerVariables[iMo + PV->U]
9920 - deltaT * F1B2 / formerVariables[iMo + PV->RHO] * F1BCS / sqrtKappa * (L4 - L1);
9921 u2 = formerVariables[iMo + PV->V] - deltaT * L2;
9922 rho = formerVariables[iMo + PV->RHO] - deltaT * F1B2 / kappa * F1BCSsq * (L4 + L1)
9923 - F1BCSsq * L3 / kappa;
9926 eqD[0] = F1B9 * (rho + F9B2 * ((-u1) * (-u1) - F1B3 * (u1 * u1 + u2 * u2)));
9927 eqD[1] = F1B9 * (rho + F9B2 * ((u1) * (u1)-F1B3 * (u1 * u1 + u2 * u2)));
9928 eqD[2] = F1B9 * (rho + F9B2 * ((-u2) * (-u2) - F1B3 * (u1 * u1 + u2 * u2)));
9929 eqD[3] = F1B9 * (rho + F9B2 * ((u2) * (u2)-F1B3 * (u1 * u1 + u2 * u2)));
9930 eqD[4] = F1B36 * (rho + F9B2 * ((u1 + u2) * (u1 + u2) - F1B3 * (u1 * u1 + u2 * u2)));
9931 eqD[5] = F1B36 * (rho + F9B2 * ((u1 - u2) * (u1 - u2) - F1B3 * (u1 * u1 + u2 * u2)));
9932 eqD[6] = F1B36 * (rho + F9B2 * ((-u1 - u2) * (-u1 - u2) - F1B3 * (u1 * u1 + u2 * u2)));
9933 eqD[7] = F1B36 * (rho + F9B2 * ((-u1 + u2) * (-u1 + u2) - F1B3 * (u1 * u1 + u2 * u2)));
9936 u1c = m_solver->a_variable(currentID, PV->U);
9937 u2c = m_solver->a_variable(currentID, PV->V);
9938 rhoc = m_solver->a_variable(currentID, PV->RHO);
9941 eqDc[0] = F1B9 * (rhoc + F9B2 * ((-u1c) * (-u1c) - F1B3 * (u1c * u1c + u2c * u2c)));
9942 eqDc[1] = F1B9 * (rhoc + F9B2 * ((u1c) * (u1c)-F1B3 * (u1c * u1c + u2c * u2c)));
9943 eqDc[2] = F1B9 * (rhoc + F9B2 * ((-u2c) * (-u2c) - F1B3 * (u1c * u1c + u2c * u2c)));
9944 eqDc[3] = F1B9 * (rhoc + F9B2 * ((u2c) * (u2c)-F1B3 * (u1c * u1c + u2c * u2c)));
9945 eqDc[4] = F1B36 * (rhoc + F9B2 * ((u1c + u2c) * (u1c + u2c) - F1B3 * (u1c * u1c + u2c * u2c)));
9946 eqDc[5] = F1B36 * (rhoc + F9B2 * ((u1c - u2c) * (u1c - u2c) - F1B3 * (u1c * u1c + u2c * u2c)));
9947 eqDc[6] = F1B36 * (rhoc + F9B2 * ((-u1c - u2c) * (-u1c - u2c) - F1B3 * (u1c * u1c + u2c * u2c)));
9948 eqDc[7] = F1B36 * (rhoc + F9B2 * ((-u1c + u2c) * (-u1c + u2c) - F1B3 * (u1c * u1c + u2c * u2c)));
9952 for(
MInt j = 0; j < 8; j++) {
9954 * (m_solver->a_oldDistribution(currentID, j)
9955 + m_solver->a_oldDistribution(currentID, Ld::oppositeDist(j)));
9958 for(
MInt j = 0; j < 8; j++) {
9959 if(m_solver->a_hasNeighbor(currentID, j) == 0)
9960 m_solver->a_oldDistribution(currentID, Ld::oppositeDist(j)) =
9961 -m_solver->a_distribution(currentID, j) + 2 * eqD[j] + (2 - m_omega) * (meanDist[j] - eqDc[j]);
9965 if(m_solver->a_hasNeighbor(currentID, 3) == 0) {
9966 m_solver->a_oldDistribution(currentID, 6) = m_solver->a_distribution(currentID, 4);
9967 m_solver->a_oldDistribution(currentID, 2) = m_solver->a_distribution(currentID, 3);
9968 m_solver->a_oldDistribution(currentID, 5) = m_solver->a_distribution(currentID, 7);
9971 if(m_solver->a_hasNeighbor(currentID, 2) == 0) {
9972 m_solver->a_oldDistribution(currentID, 4) = m_solver->a_distribution(currentID, 6);
9973 m_solver->a_oldDistribution(currentID, 3) = m_solver->a_distribution(currentID, 2);
9974 m_solver->a_oldDistribution(currentID, 7) = m_solver->a_distribution(currentID, 5);
9978 formerVariables[iMo + 0] = u1;
9979 formerVariables[iMo + 1] = u2;
9980 formerVariables[iMo + 2] = rho;
9992template <MInt nDim, MInt nDist,
class SysEqn>
9996 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
9997 const MInt currentId = m_bndCells[i].m_cellId;
9999 || m_solver->a_isHalo(currentId)) {
10003 MFloat rho_b, u_b[nDim];
10004 calcCharValues<2>(index, currentId, rho_b, &u_b[0]);
10006#ifdef WAR_NVHPC_PSTL
10007 MFloat oldDist[nDist] = {F0};
10008 for(
MInt d = 0; d < nDist; d++) {
10009 oldDist[d] = m_solver->a_oldDistribution(currentId, d);
10011 sysEqn().calcEqDists(rho_b, &u_b[0], oldDist);
10012 for(
MInt d = 0; d < nDist; d++) {
10013 m_solver->a_oldDistribution(currentId, d) = oldDist[d];
10016 sysEqn().calcEqDists(rho_b, &u_b[0], &m_solver->a_oldDistribution(currentId, 0));
10028template <MInt nDim, MInt nDist,
class SysEqn>
10032 MFloat L1, L2, L3, L4, L5;
10033 MFloat rho, u[3] = {0.0, 0.0, 0.0}, rho_b;
10034 MFloat nghbr_rho, nghbr_u[3] = {0.0, 0.0, 0.0};
10043 MFloat sqrtKappa = sqrt(1.2);
10045 MInt currentID, nghbrID;
10049 MFloat der_u, der_p, der_v, der_w;
10064 for(
MInt i = m_bndCndOffsets[index]; i < m_bndCndOffsets[
index + 1]; i++) {
10065 currentID = m_bndCells[i].m_cellId;
10066 nghbrID = m_solver->c_neighborId(currentID, Ld::oppositeDist(direction));
10068 k_relax = sigma * (1 - m_Ma * m_Ma) * sqrtKappa * LBCS
10070 *
FFPOW2(m_solver->maxLevel()
10071 - m_solver->a_level(currentID)));
10075 2.0 / (1.0 + 6.0 * m_solver->a_nu(currentID) *
FFPOW2(m_solver->maxLevel() - m_solver->a_level(currentID)));
10077 if(m_densityFluctuations) {
10085 nghbr_rho = m_solver->a_variable(nghbrID, PV->RHO);
10086 nghbr_u[0] = m_solver->a_variable(nghbrID, PV->U);
10087 nghbr_u[1] = m_solver->a_variable(nghbrID, PV->V);
10088 nghbr_u[2] = m_solver->a_variable(nghbrID, PV->W);
10092 tmp2 = nghbr_u[0] * nghbr_u[0] + nghbr_u[1] * nghbr_u[1] + nghbr_u[2] * nghbr_u[2];
10102 for(
MInt j = 0; j < Ld::distFld(0); j++) {
10103 eDistributions[j] = Ld::tp(1) * F1BCSsq * (nghbr_rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2);
10106 tmpDistId = Ld::distFld(0);
10107 for(
MInt j = 0; j < Ld::distFld(1); j++) {
10108 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
10109 eDistributions[tmpDistId + j] =
10110 Ld::tp(2) * F1BCSsq * (nghbr_rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
10113 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
10114 for(
MInt j = 0; j < Ld::distFld(2); j++) {
10115 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
10116 eDistributions[tmpDistId + j] =
10117 Ld::tp(3) * F1BCSsq * (nghbr_rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2);
10120 for(
MInt j = 0; j < nDist - 1; j++) {
10121 nePart[j] = m_solver->a_distribution(currentID, j) - eDistributions[j];
10127 der_p = CSsq * (m_solver->a_oldVariable(currentID, PV->RHO) - m_solver->a_oldVariable(nghbrID, PV->RHO));
10128 der_u = (m_solver->a_oldVariable(currentID, PV->U) - m_solver->a_oldVariable(nghbrID, PV->U));
10129 der_v = (m_solver->a_oldVariable(currentID, PV->V) - m_solver->a_oldVariable(nghbrID, PV->V));
10130 der_w = (m_solver->a_oldVariable(currentID, PV->W) - m_solver->a_oldVariable(nghbrID, PV->W));
10132 switch(direction) {
10135 L1 = (m_solver->a_oldVariable(currentID, PV->U) - sqrtKappa * LBCS)
10136 * (-der_p - (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * (-der_u) * sqrtKappa * LBCS);
10137 L2 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10143 u[0] = m_solver->a_oldVariable(currentID, PV->U)
10144 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10146 u[1] = m_solver->a_oldVariable(currentID, PV->V) - deltaT * L3;
10147 u[2] = m_solver->a_oldVariable(currentID, PV->W) - deltaT * L4;
10151 L1 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10153 L3 = m_solver->a_oldVariable(currentID, PV->U) * der_v;
10154 L4 = m_solver->a_oldVariable(currentID, PV->U) * der_w;
10155 L5 = (m_solver->a_oldVariable(currentID, PV->U) + sqrtKappa * LBCS)
10156 * (der_p + (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * der_u * sqrtKappa * LBCS);
10159 u[0] = m_solver->a_oldVariable(currentID, PV->U)
10160 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10162 u[1] = m_solver->a_oldVariable(currentID, PV->V) - deltaT * L3;
10163 u[2] = m_solver->a_oldVariable(currentID, PV->W) - deltaT * L4;
10168 L1 = (m_solver->a_oldVariable(currentID, PV->V) - sqrtKappa * LBCS)
10169 * (-der_p - (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * (-der_v) * sqrtKappa * LBCS);
10170 L2 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10176 u[0] = m_solver->a_oldVariable(currentID, PV->U) - deltaT * L3;
10177 u[1] = m_solver->a_oldVariable(currentID, PV->V)
10178 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10180 u[2] = m_solver->a_oldVariable(currentID, PV->W) - deltaT * L4;
10184 L1 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10186 L3 = m_solver->a_oldVariable(currentID, PV->V) * der_u;
10187 L4 = m_solver->a_oldVariable(currentID, PV->V) * der_w;
10188 L5 = (m_solver->a_oldVariable(currentID, PV->V) + sqrtKappa * LBCS)
10189 * (der_p + (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * der_v * sqrtKappa * LBCS);
10192 u[0] = m_solver->a_oldVariable(currentID, PV->U) - deltaT * L3;
10193 u[1] = m_solver->a_oldVariable(currentID, PV->V)
10194 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10196 u[2] = m_solver->a_oldVariable(currentID, PV->W) - deltaT * L4;
10201 L1 = (m_solver->a_oldVariable(currentID, PV->W) - sqrtKappa * LBCS)
10202 * (-der_p - (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * (-der_w) * sqrtKappa * LBCS);
10203 L2 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10209 u[0] = m_solver->a_oldVariable(currentID, PV->U) - deltaT * L3;
10210 u[1] = m_solver->a_oldVariable(currentID, PV->V) - deltaT * L4;
10211 u[2] = m_solver->a_oldVariable(currentID, PV->W)
10212 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10217 L1 = k_relax * F1B3 * (m_solver->a_oldVariable(currentID, PV->RHO) - rho_b);
10219 L3 = m_solver->a_oldVariable(currentID, PV->W) * der_u;
10220 L4 = m_solver->a_oldVariable(currentID, PV->W) * der_v;
10221 L5 = (m_solver->a_oldVariable(currentID, PV->W) + sqrtKappa * LBCS)
10222 * (der_p + (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * der_w * sqrtKappa * LBCS);
10225 u[0] = m_solver->a_oldVariable(currentID, PV->U) - deltaT * L3;
10226 u[1] = m_solver->a_oldVariable(currentID, PV->V) - deltaT * L4;
10227 u[2] = m_solver->a_oldVariable(currentID, PV->W)
10228 - deltaT * F1B2 / (m_solver->a_oldVariable(currentID, PV->RHO) + rho_offset) * F1BCS / sqrtKappa
10233 TERMM(1,
"Unrealistic case, please check your Boundary Conditions!!!");
10237 rho = m_solver->a_oldVariable(currentID, PV->RHO) - deltaT * F1B2 / kappa * F1BCSsq * (L5 + L1)
10238 - F1BCSsq * L2 / kappa;
10241 m_solver->a_variable(currentID, PV->U) = u[0];
10242 m_solver->a_variable(currentID, PV->V) = u[1];
10243 m_solver->a_variable(currentID, PV->W) = u[2];
10244 m_solver->a_variable(currentID, PV->RHO) = rho;
10249 tmp2 = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
10259 for(
MInt j = 0; j < Ld::distFld(0); j++) {
10260 if(!m_solver->a_hasNeighbor(currentID, Ld::oppositeDist(j))) {
10261 m_solver->a_oldDistribution(currentID, j) =
10262 Ld::tp(1) * F1BCSsq * (rho * CSsq +
b[j] +
b[j] *
b[j] * F1BCSsq * F1B2 - tmp2 * F1B2)
10263 + ((1 - m_omega) * nePart[j]);
10268 tmpDistId = Ld::distFld(0);
10269 for(
MInt j = 0; j < Ld::distFld(1); j++) {
10270 if(!m_solver->a_hasNeighbor(currentID, Ld::oppositeDist(tmpDistId + j))) {
10271 tmp = (
b[Ld::mFld1(2 * j)] +
b[Ld::mFld1(2 * j + 1)]);
10272 m_solver->a_oldDistribution(currentID, tmpDistId + j) =
10273 Ld::tp(2) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
10274 + ((1 - m_omega) * nePart[tmpDistId + j]);
10279 tmpDistId = Ld::distFld(0) + Ld::distFld(1);
10280 for(
MInt j = 0; j < Ld::distFld(2); j++) {
10281 if(!m_solver->a_hasNeighbor(currentID, Ld::oppositeDist(tmpDistId + j))) {
10282 tmp = (
b[Ld::mFld2(3 * j)] +
b[Ld::mFld2(3 * j + 1)] +
b[Ld::mFld2(3 * j + 2)]);
10283 m_solver->a_oldDistribution(currentID, tmpDistId + j) =
10284 Ld::tp(3) * F1BCSsq * (rho * CSsq + tmp + tmp * tmp * F1BCSsq * F1B2 - tmp2 * F1B2)
10285 + ((1 - m_omega) * nePart[tmpDistId + j]);
10294 TERMM(1,
"This Boundary Condition is not implemented for 2D");
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void slidingWall(MInt index)
void heatFluxBc(MInt index, MInt bcMode)
LbBndCndDxQy(LbSolver< nDim > *solver)
void writeBoundaryVTK(MFloat **vertices, MInt num, MInt segmentId)
Writes the rim of a boundary as VTP to file.
void recalcRho(MInt index)
void refillEmergedCell(const MInt)
void parabolicInflow(MInt index)
void extrapolateVelocities(MInt index, const MInt pCellId, MFloat *l_uu)
void charPressure2(MInt index, MInt direction)
void slipFlow(MInt index)
void charPressure(MInt index, MInt direction)
void refillEmergedCellNormalExtrapolationLinear(const MInt)
void dnt(MInt index, MInt direction)
void interpolatedBounceBackSingleSpeciesThermal(const MInt cellId, const MFloat *const wTPtr, const MFloat *const uW)
void calculateWallForcesMb(MInt set)
void bc20501_init(MInt index)
void calculateSublayerDistances(MInt index)
MFloat firstMomentSourceTerm(const MFloat *const uW, const MFloat rho, const MInt dist)
Momentum source term used in bounce back schemes for moving boundaries.
void interpolatedBounceBackMb_Bouzidi_qua(const MInt cellIndex, const MInt set)
Interpolated bounce back for moving walls using the quadratic BFL scheme.
void getBoundaryVelocity(const MInt index, MFloat *uW)
Reads boundary velocity from properties.
void getBoundaryVelocityMb(const MInt cellId, MFloat *uW)
Reads boundary velocity from the moving boundary cell collector.
void calculateWallForces(MInt index)
void calculateEqDistsWallSingleSpeciesThermal(const MInt pCellId, MFloat wT)
MFloat getBoundaryTemperature(const MInt index)
Reads boundary temperature from properties.
void interpolatedBounceBackMb_Bouzidi_lin_thermal(const MInt cellIndex, const MInt set)
void calculateWallDistances2D()
void calculateWallInterface(MInt cellId, MFloat *wallConc, MFloat *wallTemp)
void extrapolateVariable(const MInt index, const MInt pCellId, const MInt var, MFloat *const p_var)
void interpolatedBounceBackSingleSpecies(const MInt cellId, const MFloat *const uW)
void interpolatedBounceBackMb_Yu_qua(const MInt cellIndex, const MInt set)
Interpolated bounce back for moving walls using the quadratic scheme by Yu et al.
void interpolatedBounceBackSingleSpeciesTransport(const MInt cellId, const MFloat *const wCPtr, const MFloat *const uW)
MFloat zerothMomentSourceTerm(const MInt pCellId, const MInt dist, const MFloat var, const MFloat *uW)
void interpolatedBounceBackMb_Bouzidi_lin_transport(const MInt cellIndex, const MInt set)
void calculateEqDistsWallSingleSpeciesTransport(const MInt pCellId, MFloat wC)
void extrapolateVelocitiesMb()
void calcCharValuesOnFace(const MInt index, const MInt direction, const MInt bndCellId, MFloat &rho_b, MFloat *u_b)
void bc40072_40082_init(MInt index)
void interpolatedBounceBackSingleSpeciesThermalFlux(const MInt cellId, const MFloat qT, MInt bcIndex)
void calculateEqDistsWallSingleSpecies(const MInt pCellId)
void incrementForces(const MInt cellId, const MInt j, const MFloat *uW, MFloat *forces)
void charVelocity(MInt index, MInt direction)
void interpolatedBounceBackMb_Bouzidi_lin(const MInt cellIndex, const MInt set)
Interpolated bounce back for moving walls using the linear BFL scheme.
void outflowLinear(MInt index)
MFloat ** allOwnersGetBoundaryVertices(MInt segmentId, MInt *num)
Obtain all boundary vertices for a given segmentId.
void interpolatedAntiBounceBackMb_Bouzidi_qua(const MInt cellIndex, const MInt set)
void calculateWallDistances()
calculates the intersection point between the boundary wall and the trajectories of the distribution ...
void addWallDistanceFieldToOutputFile(ParallelIo ¶llelIo, const MBool writeHeader, const MBool writeData) override
void refillEmergedCellNormalExtrapolationQuadratic(const MInt)
virtual ~LbBndCndDxQy()
Destructor for the nDim/nDist specific boundary condition.
void calcCharValues(const MInt index, const MInt bndCellId, MFloat &rho_b, MFloat *u_b)
void writeBCOutput(MInt index)
void bcIBBNeumannInit(MInt index)
This class represents all LB models.
void setEqDists(const MInt cellId, const MFloat rho, const MFloat *const velocity)
Set BOTH distributions to equilibrium.
This class is a ScratchSpace.
T * getPointer() const
Deprecated: use begin() instead!
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
MBool approx(const T &, const U &, const T)
ATTRIBUTES1(ATTRIBUTE_NO_AUTOVEC) void FvCartesianSolverXD< nDim_
resets the solver
std::vector< std::pair< MString, MInt > > g_tc_geometry
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
constexpr MFloat FFPOW2(MInt x)
std::basic_string< char > MString
int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgatherv
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
constexpr MInt distType[Q]
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.
T linear(const T a, const T b, const T x)
Linear slope filter.
T cos(const T a, const T b, const T x)
Cosine slope filter.
IdType index(const FloatType *const x, const IdType level)
Return Hilbert index for given location and level in 2D or 3D.
void parallelFor(MInt begin, MInt end, UnaryFunction &&f)
Wrapper function for parallel for loop.
PARALLELIO_DEFAULT_BACKEND ParallelIo
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
This class contains the necessary data to define a boundary cell for the LB method.