25template <MBool isRans>
52template <MBool isRans>
55template <MBool isRans>
59 vector<unique_ptr<StructuredWindowMap<nDim>>>& spongeInfo = m_solver->m_windowInfo->m_spongeInfoMap;
60 MInt noSpongeInfo = spongeInfo.size();
69 for(
MInt i = 0; i < noSpongeInfo; ++i) {
71 for(
MInt dim = 0; dim < nDim; ++dim) {
72 size *= (spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim] + 1);
82 for(
MInt i = 0; i < noSpongeInfo; ++i) {
84 for(
MInt dim = 0; dim < nDim; ++dim) {
85 size *= (spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim] + 1);
87 spongeCoords[i] = &coordMem[totMemSize];
88 totMemSize += nDim * size;
100 for(
MInt i = 0; i < noSpongeInfo; ++i) {
102 for(
MInt dim = 0; dim < nDim; ++dim) {
103 if(spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim] == 0)
continue;
104 size *= (spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim]);
113 MInt totCellMemSize = 0;
114 for(
MInt i = 0; i < noSpongeInfo; ++i) {
116 for(
MInt dim = 0; dim < nDim; ++dim) {
117 if(spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim] == 0)
continue;
118 size *= (spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim]);
120 spongeSurfCoords[i] = &coordCellMem[totCellMemSize];
121 totCellMemSize += nDim * size;
127 MString gridFileName = m_grid->m_gridInputFileName;
145 ParallelIo::size_type ioOffset[2] = {0, 0};
146 ParallelIo::size_type ioSize[2] = {0, 0};
147 if(m_solver->domainId() == 0) {
148 for(
MInt i = 0; i < noSpongeInfo; ++i) {
150 for(
MInt dim = 1; dim >= 0; --dim) {
151 ioSize[dim] = (spongeInfo[i]->end1[1 - dim] - spongeInfo[i]->start1[1 - dim] + 1);
152 memSize *= ioSize[dim];
153 ioOffset[dim] = spongeInfo[i]->start1[1 - dim];
159 number << spongeInfo[i]->Id1;
160 bName += number.str();
161 pio.
readArray(&spongeCoords[i][0], bName,
"x", 2, ioOffset, ioSize);
162 pio.
readArray(&spongeCoords[i][memSize], bName,
"y", 2, ioOffset, ioSize);
165 for(
MInt i = 0; i < noSpongeInfo; ++i) {
168 number << spongeInfo[i]->Id1;
169 bName += number.str();
171 pio.
readArray(&empty, bName,
"x", 2, ioOffset, ioSize);
172 pio.
readArray(&empty, bName,
"y", 2, ioOffset, ioSize);
177 MPI_Bcast(&spongeCoords[0][0], totMemSize, MPI_DOUBLE, 0, m_StructuredComm, AT_,
"spongeCoords[0][0]");
181 for(
MInt ii = 0; ii < noSpongeInfo; ++ii) {
182 MInt label, size1, count = 0;
183 for(label = 0; label < nDim; label++) {
184 if(spongeInfo[ii]->end1[label] - spongeInfo[ii]->start1[label] == 0)
break;
188 size1 = spongeInfo[ii]->end1[1] - spongeInfo[ii]->start1[1] + 1;
189 for(
MInt i = 0; i < size1 - 1; i++) {
192 spongeSurfCoords[ii][count] = 0.5 * (spongeCoords[ii][I] + spongeCoords[ii][IP]);
193 spongeSurfCoords[ii][count + (size1 - 1)] =
194 0.5 * (spongeCoords[ii][I + size1] + spongeCoords[ii][IP + size1]);
200 size1 = spongeInfo[ii]->end1[0] - spongeInfo[ii]->start1[0] + 1;
201 for(
MInt i = 0; i < size1 - 1; i++) {
204 spongeSurfCoords[ii][count] = 0.5 * (spongeCoords[ii][I] + spongeCoords[ii][IP]);
205 spongeSurfCoords[ii][count + (size1 - 1)] =
206 0.5 * (spongeCoords[ii][I + size1] + spongeCoords[ii][IP + size1]);
212 mTerm(1, AT_,
"sponge direction is messed up");
218 m_log <<
"sponge layer build: searching for the nearest points (building simgma sponge)" << endl;
222 for(
MInt i = 0; i < noSpongeInfo; ++i) {
224 for(
MInt dim = 0; dim < nDim; ++dim) {
225 if(spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim] == 0)
continue;
226 noPoints *= (spongeInfo[i]->end1[dim] - spongeInfo[i]->start1[dim]);
229 vector<Point<2>> pts;
230 for(
MInt j = 0; j < noPoints; ++j) {
231 Point<2> a(spongeSurfCoords[i][j], spongeSurfCoords[i][j + noPoints]);
239 MFloat spongeThickness = spongeInfo[i]->spongeThickness;
240 for(
MInt id = 0;
id < m_noCells; ++
id) {
241 distance = -1.1111111111111111;
242 Point<2> pt(m_cells->coordinates[0][
id], m_cells->coordinates[1][
id]);
243 (void)tree.
nearest(pt, distance);
244 if(distance <= spongeThickness) {
246 spongeInfo[i]->sigma * pow((spongeThickness - distance) / spongeThickness, spongeInfo[i]->beta);
247 m_cells->fq[FQ->SPONGE_FACTOR][
id] =
mMax(m_cells->fq[FQ->SPONGE_FACTOR][
id], spongeFactor);
252 m_log <<
"Spone layer SUCESSFUL: finished building sigma sponge " << endl;
255template <MBool isRans>
259 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
260 switch(m_spongeLayerType) {
262 MFloat deltaRhoE = F0, deltaRho = F0;
263 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; j++) {
264 for(
MInt i = m_noGhostLayers; i < m_nCells[1] - m_noGhostLayers; i++) {
267 MInt cellId = cellIndex(i, j);
269 m_cells->pvariables[PV->P][cellId] / gammaMinusOne
270 + F1B2 * m_cells->pvariables[PV->RHO][cellId]
271 * (
POW2(m_cells->pvariables[PV->U][cellId]) +
POW2(m_cells->pvariables[PV->V][cellId]));
273 deltaRhoE = rhoE - CV->rhoEInfinity;
274 deltaRho = m_cells->pvariables[PV->RHO][cellId] - (CV->rhoInfinity * m_targetDensityFactor);
276 m_cells->rightHandSide[CV->RHO_E][cellId] -= m_cells->fq[FQ->SPONGE_FACTOR][cellId] * deltaRhoE
277 * m_cells->cellJac[cellId];
278 m_cells->rightHandSide[CV->RHO][cellId] -=
279 m_cells->fq[FQ->SPONGE_FACTOR][cellId] * deltaRho * m_cells->cellJac[cellId];
287 MFloat deltaRhoE = F0, deltaRho = F0;
288 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; j++) {
289 for(
MInt i = m_noGhostLayers; i < m_nCells[1] - m_noGhostLayers; i++) {
290 MInt cellId = cellIndex(i, j);
292 m_cells->pvariables[PV->P][cellId] / gammaMinusOne
293 + F1B2 * m_cells->pvariables[PV->RHO][cellId]
294 * (
POW2(m_cells->pvariables[PV->U][cellId]) +
POW2(m_cells->pvariables[PV->V][cellId]));
296 deltaRhoE = rhoE - m_cells->fq[FQ->SPONGE_RHO_E][cellId];
298 m_cells->pvariables[PV->RHO][cellId] - (m_cells->fq[FQ->SPONGE_RHO][cellId] * m_targetDensityFactor);
299 m_cells->rightHandSide[CV->RHO_E][cellId] -=
300 m_cells->fq[FQ->SPONGE_FACTOR][cellId] * deltaRhoE * m_cells->cellJac[cellId];
301 m_cells->rightHandSide[CV->RHO][cellId] -=
302 m_cells->fq[FQ->SPONGE_FACTOR][cellId] * deltaRho * m_cells->cellJac[cellId];
310 const MFloat FgammaMinusOne = F1 / (m_solver->m_gamma - F1);
311 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; j++) {
312 for(
MInt i = m_noGhostLayers; i < m_nCells[1] - m_noGhostLayers; i++) {
313 const MInt cellId = cellIndex(i, j);
314 const MFloat deltaP = (m_cells->pvariables[PV->P][cellId] - PV->PInfinity) * FgammaMinusOne;
315 m_cells->rightHandSide[CV->RHO_E][cellId] -=
316 m_cells->fq[FQ->SPONGE_FACTOR][cellId] * deltaP * m_cells->cellJac[cellId];
322 mTerm(1, AT_,
"Sponge type doesn't exist");
328template <MBool isRans>
330 vector<unique_ptr<StructuredWindowMap<nDim>>>& wallDistInfo = m_solver->m_windowInfo->m_wallDistInfoMap;
331 MInt noWallDistInfo = wallDistInfo.size();
335 for(
MInt id = 0;
id < m_noCells; ++
id) {
336 m_cells->fq[FQ->WALLDISTANCE][
id] = 99999;
344 for(
MInt i = 0; i < noWallDistInfo; ++i) {
346 for(
MInt dim = 0; dim < 2; ++dim) {
347 size *= (wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim] + 1);
357 for(
MInt i = 0; i < noWallDistInfo; ++i) {
359 for(
MInt dim = 0; dim < 2; ++dim) {
360 size *= (wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim] + 1);
362 wallDistCoords[i] = &coordMem[totMemSize];
363 totMemSize += 2 * size;
372 MInt cellmemSize = 0;
374 for(
MInt i = 0; i < noWallDistInfo; ++i) {
376 for(
MInt dim = 0; dim < 2; ++dim) {
377 if(wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim] == 0)
continue;
378 size *= (wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim]);
387 MInt totCellMemSize = 0;
388 for(
MInt i = 0; i < noWallDistInfo; ++i) {
390 for(
MInt dim = 0; dim < 2; ++dim) {
391 if(wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim] == 0)
continue;
392 size *= (wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim]);
394 wallDistSurfCoords[i] = &coordCellMem[totCellMemSize];
395 totCellMemSize += 2 * size;
400 MString gridFileName = m_grid->m_gridInputFileName;
414 ParallelIo::size_type ioOffset[2] = {0, 0};
415 ParallelIo::size_type ioSize[2] = {0, 0};
416 if(m_solver->domainId() == 0) {
417 for(
MInt i = 0; i < noWallDistInfo; ++i) {
419 for(
MInt dim = 1; dim >= 0; --dim) {
420 ioSize[dim] = (wallDistInfo[i]->end1[1 - dim] - wallDistInfo[i]->start1[1 - dim] + 1);
421 memSize *= ioSize[dim];
422 ioOffset[dim] = wallDistInfo[i]->start1[1 - dim];
428 number << wallDistInfo[i]->Id1;
429 bName += number.str();
430 pio.
readArray(&wallDistCoords[i][0], bName,
"x", 2, ioOffset, ioSize);
431 pio.
readArray(&wallDistCoords[i][memSize], bName,
"y", 2, ioOffset, ioSize);
434 for(
MInt i = 0; i < noWallDistInfo; ++i) {
437 number << wallDistInfo[i]->Id1;
438 bName += number.str();
440 pio.
readArray(&empty, bName,
"x", 2, ioOffset, ioSize);
441 pio.
readArray(&empty, bName,
"y", 2, ioOffset, ioSize);
447 MPI_Bcast(&wallDistCoords[0][0], totMemSize, MPI_DOUBLE, 0, m_solver->m_StructuredComm, AT_,
"wallDistCoords[0][0]");
452 for(
MInt ii = 0; ii < noWallDistInfo; ++ii) {
453 MInt label, size1, count = 0;
454 for(label = 0; label < 2; label++) {
455 if(wallDistInfo[ii]->end1[label] - wallDistInfo[ii]->start1[label] == 0)
break;
459 size1 = wallDistInfo[ii]->end1[1] - wallDistInfo[ii]->start1[1] + 1;
460 for(
MInt i = 0; i < size1 - 1; i++) {
463 wallDistSurfCoords[ii][count] = 0.5 * (wallDistCoords[ii][I] + wallDistCoords[ii][IP]);
464 wallDistSurfCoords[ii][count + (size1 - 1)] =
465 0.5 * (wallDistCoords[ii][I + size1] + wallDistCoords[ii][IP + size1]);
471 size1 = wallDistInfo[ii]->end1[0] - wallDistInfo[ii]->start1[0] + 1;
472 for(
MInt i = 0; i < size1 - 1; i++) {
475 wallDistSurfCoords[ii][count] = 0.5 * (wallDistCoords[ii][I] + wallDistCoords[ii][IP]);
476 wallDistSurfCoords[ii][count + (size1 - 1)] =
477 0.5 * (wallDistCoords[ii][I + size1] + wallDistCoords[ii][IP + size1]);
483 mTerm(1, AT_,
"wall direction is messed up");
489 m_log <<
"wall distance computation: searching for the nearest wall" << endl;
493 for(
MInt i = 0; i < noWallDistInfo; ++i) {
495 for(
MInt dim = 0; dim < 2; ++dim) {
496 if(wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim] == 0)
continue;
497 noPoints *= (wallDistInfo[i]->end1[dim] - wallDistInfo[i]->start1[dim]);
500 vector<Point<2>> pts;
501 for(
MInt j = 0; j < noPoints; ++j) {
502 Point<2> a(wallDistSurfCoords[i][j], wallDistSurfCoords[i][j + noPoints]);
510 for(
MInt id = 0;
id < m_noCells; ++
id) {
511 distance = -1.1111111111111111;
512 Point<2> pt(m_cells->coordinates[0][
id], m_cells->coordinates[1][
id]);
513 (void)tree.
nearest(pt, distance);
517 m_cells->fq[FQ->WALLDISTANCE][
id] =
mMin(m_cells->fq[FQ->WALLDISTANCE][
id], distance);
521 m_log <<
"Wall Distance Computation SUCESSFUL: Saved minimum distance to next wall for all cells " << endl;
740template <MBool isRans>
743 MFloat maxWallDistance = numeric_limits<MFloat>::max();
744 maxWallDistance = Context::getSolverProperty<MFloat>(
"maxWallDistance", m_solverId, AT_, &maxWallDistance);
745 for(
MInt id = 0;
id < m_noCells; ++
id) {
746 m_cells->fq[FQ->WALLDISTANCE][
id] = maxWallDistance;
749 const vector<unique_ptr<StructuredWindowMap<nDim>>>& wallDistInfo =
751 const MInt noWallDistInfo = wallDistInfo.size();
752 std::vector<MInt> wallNormalIndex(noWallDistInfo);
753 std::vector<MInt> normalDir(noWallDistInfo);
754 std::vector<std::array<MInt, 2 * nDim>> startEndTangential(noWallDistInfo);
756 MInt cellmemSize = 0;
757 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
759 const MInt*
const start = wallDistInfo[nn]->start1;
760 const MInt*
const end = wallDistInfo[nn]->end1;
761 const MInt face = wallDistInfo[nn]->face;
762 normalDir[nn] = face / 2;
763 wallNormalIndex[nn] = start[normalDir[nn]];
766 for(
MInt dim = 0; dim < nDim - 1; ++dim) {
767 const MInt tangentialDir = (normalDir[nn] + (dim + 1)) % nDim;
768 startEndTangential[nn][dim * 2 + 0] = start[tangentialDir];
769 startEndTangential[nn][dim * 2 + 1] =
770 end[tangentialDir] + 1;
771 size *= startEndTangential[nn][dim * 2 + 1] - startEndTangential[nn][dim * 2 + 0];
775 cout <<
"Debug output: wallDistInfo=" << nn <<
": face=" << face <<
"; normalDir=" << normalDir[nn]
776 <<
"; wallNormalIndex=" << wallNormalIndex[nn] <<
"; startEndTangential=" << startEndTangential[nn][0] <<
"|"
777 << startEndTangential[nn][1] <<
"normal start/end=" << start[normalDir[nn]] <<
"|" << end[normalDir[nn]]
784 MFloatScratchSpace coordGridMem(std::max(1, nDim * cellmemSize), AT_,
"coordGridMem");
786 for(
MInt dim = 0; dim < nDim; ++dim)
787 wallDistSurfCoords[dim] = &coordGridMem[dim * cellmemSize];
789 MIntScratchSpace isStartEndPoint(std::max(1, cellmemSize), AT_,
"isStartEndPoint");
793 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
795 MInt& i = (normalDir[nn] == 0) ? wallNormalIndex[nn] : tIdx;
796 MInt& j = (normalDir[nn] == 0) ? tIdx : wallNormalIndex[nn];
797 for(tIdx = startEndTangential[nn][0]; tIdx < startEndTangential[nn][1]; ++tIdx) {
798 const MInt p = getPointIdFromCell(i, j);
799 wallDistSurfCoords[0][cnt] = m_grid->m_coordinates[0][p];
800 wallDistSurfCoords[1][cnt] = m_grid->m_coordinates[1][p];
802 if(tIdx == startEndTangential[nn][0])
803 isStartEndPoint[cnt] = 1;
804 else if(tIdx == startEndTangential[nn][1] - 1)
805 isStartEndPoint[cnt] = -1;
807 isStartEndPoint[cnt] =
815 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
817 std::vector<MInt> recvcounts(noRanks);
818 MPI_Allgather(&cellmemSize, 1, MPI_INT, recvcounts.data(), 1, MPI_INT, m_solver->m_StructuredComm, AT_,
"cellmemSize",
820 std::vector<MInt> displs(noRanks);
821 for(
MInt r = 0; r < noRanks - 1; ++r) {
822 displs[r + 1] = displs[r] + recvcounts[r];
824 const MInt noTotalWallPoints = displs[noRanks - 1] + recvcounts[noRanks - 1];
826 std::vector<std::vector<MFloat>> wallDistSurfCoordsAll(nDim);
827 for(
MInt dim = 0; dim < nDim; ++dim) {
828 wallDistSurfCoordsAll[dim].resize(noTotalWallPoints);
829 MPI_Allgatherv(&wallDistSurfCoords[dim][0], cellmemSize, MPI_DOUBLE, wallDistSurfCoordsAll[dim].data(),
830 recvcounts.
data(), displs.data(), MPI_DOUBLE, m_solver->m_StructuredComm, AT_,
"wallDistSurfCoords",
831 "wallDistSurfCoordsAll");
833 std::vector<MInt> isStartEndPointAll(noTotalWallPoints);
834 MPI_Allgatherv(&isStartEndPoint[0], cellmemSize, MPI_INT, isStartEndPointAll.
data(), recvcounts.data(), displs.data(),
835 MPI_INT, m_solver->m_StructuredComm, AT_,
"isStartEndPoint",
"isStartEndPointAll");
842 std::set<MInt> globalWallIds;
845 std::vector<std::pair<MInt, MInt>> cellId2globalWallId(m_noCells, std::make_pair(-1, -1));
848 std::vector<MFloat> weighting(m_noCells, 0.0);
852 std::vector<Point<3>> pts;
854 std::vector<MInt> cellIdShifts(noTotalWallPoints + 1, 0);
855 for(
MInt globalWallId = 0; globalWallId < noTotalWallPoints; ++globalWallId) {
856 Point<3> a(wallDistSurfCoordsAll[0][globalWallId], wallDistSurfCoordsAll[1][globalWallId], 0, globalWallId);
858 cellIdShifts[globalWallId + 1] = cellIdShifts[globalWallId] - 1 * (isStartEndPointAll[globalWallId] == -1);
862 static constexpr MFloat radius = std::numeric_limits<MFloat>::max();
863 static constexpr MFloat eps = 1e-16;
868 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
869 Point<3> pt(m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId], 0);
870 MBool overflow =
false;
872 if(nfound != 3)
mTerm(1,
"Come on, your mesh should have at least 3 wall grid points!");
873 const MInt globalWallId1 = results[0];
874 MInt globalWallId1_ = results[1];
875 MInt globalWallId1__ = results[2];
877 const MFloat r2 =
POW2(wallDistSurfCoordsAll[0][globalWallId1] - wallDistSurfCoordsAll[0][globalWallId1_])
878 +
POW2(wallDistSurfCoordsAll[1][globalWallId1] - wallDistSurfCoordsAll[1][globalWallId1_]);
879 const MFloat r3 =
POW2(wallDistSurfCoordsAll[0][globalWallId1] - wallDistSurfCoordsAll[0][globalWallId1__])
880 +
POW2(wallDistSurfCoordsAll[1][globalWallId1] - wallDistSurfCoordsAll[1][globalWallId1__]);
885 if(nfound == 2 && r3 < r2) {
886 const MInt temp = globalWallId1_;
887 globalWallId1_ = globalWallId1__;
888 globalWallId1__ = temp;
897 MInt globalCellId1 = -1;
898 MInt globalCellId2 = -1;
899 MFloat distance{}, weight;
900 if(nfound == 1 && abs(isStartEndPointAll[globalWallId1]) == 1) {
902 const MInt globalWallId2 = globalWallId1 + isStartEndPointAll[globalWallId1];
903 globalCellId1 = (isStartEndPointAll[globalWallId1] == -1) ? globalWallId1 - 1 : globalWallId1;
904 globalCellId1 += cellIdShifts[globalWallId1];
905 const MFloat p1[nDim] = {wallDistSurfCoordsAll[0][globalWallId1], wallDistSurfCoordsAll[1][globalWallId1]};
906 const MFloat p2[nDim] = {wallDistSurfCoordsAll[0][globalWallId2], wallDistSurfCoordsAll[1][globalWallId2]};
907 const MFloat pTarget[nDim] = {m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId]};
909 shortestDistanceToLineElement(p1, p2, pTarget, distance, fraction);
911 if(fraction > 0.5 + 1e-8) {
913 msg <<
"ERROR: p1=" << p1[0] <<
"|" << p1[1] <<
" p2=" << p2[0] <<
"|" << p2[1] <<
" pTarget=" << pTarget[0]
914 <<
"|" << pTarget[1] <<
" distance=" << distance <<
" fraction=" << fraction << endl;
916 mTerm(1,
"Fraction is >0.5, so nearest grid point is supposed to be p2 and not p1!");
927 globalWallId2 = globalWallId1 - 1;
928 globalWallId3 = globalWallId1 + 1;
929 globalCellId1 = globalWallId2;
930 globalCellId1 += cellIdShifts[globalWallId2];
931 globalCellId2 = globalWallId1;
932 globalCellId2 += cellIdShifts[globalWallId1];
933 }
else if(nfound == 2) {
935 if(abs(isStartEndPointAll[globalWallId1]) + abs(isStartEndPointAll[globalWallId1_]) != 2) {
936 cout <<
"ERROR: (x|y)_1=" << setprecision(12) << wallDistSurfCoordsAll[0][globalWallId1] <<
"|"
937 << wallDistSurfCoordsAll[1][globalWallId1] <<
" (x|y)_2=" << wallDistSurfCoordsAll[0][globalWallId1_]
938 <<
"|" << wallDistSurfCoordsAll[1][globalWallId1_] << endl;
939 mTerm(1,
"One grid point found twice. Both grid points have neighbors to both sides, which is unexpected!");
941 globalWallId2 = globalWallId1 + isStartEndPointAll[globalWallId1];
942 globalWallId3 = globalWallId1_ + isStartEndPointAll[globalWallId1_];
943 globalCellId1 = (isStartEndPointAll[globalWallId1] == -1) ? globalWallId1 - 1 : globalWallId1;
944 globalCellId1 += cellIdShifts[globalWallId1];
945 globalCellId2 = (isStartEndPointAll[globalWallId1_] == -1) ? globalWallId1_ - 1 : globalWallId1_;
946 globalCellId2 += cellIdShifts[globalWallId1_];
949 msg <<
"p1=" << wallDistSurfCoordsAll[0][globalWallId1] <<
"|" << wallDistSurfCoordsAll[1][globalWallId1]
950 <<
", p2=" << wallDistSurfCoordsAll[0][globalWallId1_] <<
"|" << wallDistSurfCoordsAll[1][globalWallId1_]
951 <<
", p3=" << wallDistSurfCoordsAll[0][globalWallId1__] <<
"|" << wallDistSurfCoordsAll[1][globalWallId1__]
954 mTerm(1,
"Three wall grid points coincide. This situation is unknown!");
961 const MFloat p1[nDim] = {wallDistSurfCoordsAll[0][globalWallId1], wallDistSurfCoordsAll[1][globalWallId1]};
962 const MFloat p2[nDim] = {wallDistSurfCoordsAll[0][globalWallId2], wallDistSurfCoordsAll[1][globalWallId2]};
963 const MFloat p3[nDim] = {wallDistSurfCoordsAll[0][globalWallId3], wallDistSurfCoordsAll[1][globalWallId3]};
964 const MFloat pTarget[nDim] = {m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId]};
965 lineLengths[0] = shortestDistanceToLineElement(p1, p2, pTarget, distances[0], fractions[0]);
966 lineLengths[1] = shortestDistanceToLineElement(p1, p3, pTarget, distances[1], fractions[1]);
967 const MInt i = distances[1] < distances[0];
969 if(fractions[i] > 0.5 + 1e-8) {
971 msg <<
"Error p1=" << p1[0] <<
"|" << p1[1] <<
" p2=" << p2[0] <<
"|" << p2[1] <<
" p3=" << p3[0] <<
"|"
972 << p3[1] <<
" pTarget=" << pTarget[0] <<
"|" << pTarget[1] <<
" distance=" << distance
973 <<
" fraction=" << fractions[i] <<
" " << fractions[1 - i] << endl;
975 mTerm(1,
"Fraction >0.5, so nearest grid point can not be p1!");
978 weight = (fractions[i] * lineLengths[i] + 0.5 * lineLengths[1 - i]) / (0.5 * (lineLengths[0] + lineLengths[1]));
979 distance = distances[i];
982 const MInt temp = globalCellId1;
983 globalCellId1 = globalCellId2;
984 globalCellId2 = temp;
988 if(distance < m_cells->fq[FQ->WALLDISTANCE][cellId]) {
989 globalWallIds.insert(globalCellId1);
990 globalWallIds.insert(globalCellId2);
991 cellId2globalWallId[cellId] = std::make_pair(globalCellId1, globalCellId2);
992 weighting[cellId] = weight;
993 m_cells->fq[FQ->WALLDISTANCE][cellId] = distance;
999 globalWallIds.erase(-1);
1002 for(
MInt i = 1; i < (signed)displs.size(); ++i) {
1003 displs[i] = displs[i] + cellIdShifts[displs[i]];
1005 auto getDomainId = [&displs, noRanks](
const MInt id,
const MInt hint = 0) {
1006 for(
MInt rank = hint; rank < (signed)displs.size() - 1; ++rank) {
1007 if(displs[rank + 1] >
id)
return rank;
1013 std::vector<MInt> globalWallId2localId((globalWallIds.empty()) ? 0 : *globalWallIds.rbegin() + 1);
1015 std::vector<MInt> recvWallIds(globalWallIds.size());
1016 std::vector<MInt> sendcounts(noRanks);
1017 MInt domainId_temp = 0;
1018 MInt localWallId = 0;
1019 for(
auto it = globalWallIds.begin(); it != globalWallIds.end(); ++it, ++localWallId) {
1020 globalWallId2localId[*it] = localWallId;
1021 domainId_temp = getDomainId(*it, domainId_temp);
1023 recvWallIds[localWallId] = *it - displs[domainId_temp];
1024 ++sendcounts[domainId_temp];
1029 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1030 if(cellId2globalWallId[cellId].first == -1 && cellId2globalWallId[cellId].second == -1)
continue;
1033 const MInt temp = (cellId2globalWallId[cellId].second == -1) ? cellId2globalWallId[cellId].first
1034 : cellId2globalWallId[cellId].second;
1035 auto temp2 = std::make_tuple(globalWallId2localId[cellId2globalWallId[cellId].first], globalWallId2localId[temp],
1037 m_wallCellId2recvCell.insert({cellId, temp2});
1041 std::vector<MInt> snghbrs(noRanks);
1042 std::iota(snghbrs.begin(), snghbrs.end(), 0);
1044 m_wallSendcounts.resize(noRanks);
1052 m_solver->m_StructuredComm,
1053 m_solver->domainId(),
1055 m_wallSendcounts.data());
1062 if((
signed)m_wallSendCells.size() != std::accumulate(&m_wallSendcounts[0], &m_wallSendcounts[0] + noRanks, 0))
1063 mTerm(1,
"Neeeeeeiiiiiiiiin!");
1066 if(cellmemSize != 0) {
1067 MInt min = std::numeric_limits<MInt>::max();
1069 for(
auto id : m_wallSendCells) {
1071 if(
id >= cellmemSize - noWallDistInfo) {
1072 cout <<
"DEBUG id=" <<
id <<
" cellmemSize=" << cellmemSize << endl;
1073 mTerm(1,
"Something went wrong!");
1075 min =
mMin(
id, min);
1076 max =
mMax(
id, max);
1079 mTerm(1,
"Scheisse: min!=0");
1081 if(max != cellmemSize - 1 - noWallDistInfo) {
1082 cout <<
"SCHEISSE max=" << max <<
" cellmemSize=" << cellmemSize
1083 <<
" cellIdShifts[cellIdShifts.size()-2]=" << cellIdShifts[cellIdShifts.size() - 2] << endl;
1084 mTerm(1,
"Scheisse ......");
1090 cout <<
"::computeLocalWallDistance: rank=" << m_solver->domainId() <<
" cellmemSize=" << cellmemSize
1091 <<
" noTotalWallPoints=" << noTotalWallPoints <<
" #cells near wall=" << m_wallCellId2recvCell.size()
1092 <<
" #globalWallIds=" << globalWallIds.size() << endl;
1099template <MBool isRans>
1101 const MFloat (&p2)[nDim],
1102 const MFloat (&pTarget)[nDim],
1107 const MFloat linep1p2[nDim] = {p2[0] - p1[0], p2[1] - p1[1]};
1108 const MFloat linep1p2LengthPOW2 =
POW2(linep1p2[0]) +
POW2(linep1p2[1]);
1109 const MFloat linep1pT[nDim] = {pTarget[0] - p1[0], pTarget[1] - p1[1]};
1110 const MFloat dotProd = std::inner_product(std::begin(linep1p2), std::end(linep1p2), std::begin(linep1pT), 0.0);
1115 distance = sqrt(std::inner_product(std::begin(linep1pT), std::end(linep1pT), std::begin(linep1pT), 0.0));
1117 }
else if(dotProd > linep1p2LengthPOW2) {
1119 const MFloat linep2pT[nDim] = {pTarget[0] - p2[0], pTarget[1] - p2[1]};
1120 distance = sqrt(std::inner_product(std::begin(linep2pT), std::end(linep2pT), std::begin(linep2pT), 0.0));
1123 fraction = dotProd / linep1p2LengthPOW2;
1124 const MFloat pProjection[nDim] = {p1[0] + fraction * linep1p2[0], p1[1] + fraction * linep1p2[1]};
1125 const MFloat linepPpT[nDim] = {pTarget[0] - pProjection[0], pTarget[1] - pProjection[1]};
1126 distance = sqrt(std::inner_product(std::begin(linepPpT), std::end(linepPpT), std::begin(linepPpT), 0.0));
1129 if(fraction < 0.0 || fraction > 1.0)
mTerm(1,
"fraction < 0.0 or fraction > 1.0");
1130 return linep1p2LengthPOW2;
1156template <MBool isRans>
1161 vector<unique_ptr<StructuredWindowMap<nDim>>> wallDistInfo;
1162 vector<unique_ptr<StructuredWindowMap<nDim>>> FPDistInfo;
1163 for(
auto& auxDataMap : m_auxDataMap) {
1164 if(auxDataMap->isFluidPorousInterface) {
1165 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
1166 m_solver->m_windowInfo->mapCpy(auxDataMap, temp);
1167 FPDistInfo.push_back(move(temp));
1168 }
else if((
int)(auxDataMap->BC / 1000.0) == 1) {
1169 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
1170 m_solver->m_windowInfo->mapCpy(auxDataMap, temp);
1171 wallDistInfo.push_back(move(auxDataMap));
1175 std::cout <<
"DomainId=" << m_solver->domainId() <<
": " << FPDistInfo.size() <<
" FP maps & " << wallDistInfo.size()
1176 <<
" wall maps." << endl;
1181 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
1187 m_wallSendcounts.assign(noRanks, 0);
1190 std::vector<std::pair<MInt, MInt>> cellId2globalWallId;
1191 std::vector<MInt> wallDispls;
1194 std::vector<MFloat> wallWeighting;
1195 computeDistance2Map(wallDistInfo, m_cells->fq[FQ->WALLDISTANCE], cellId2globalWallId, wallDispls, wallWeighting);
1198 m_FPSendcounts.assign(noRanks, 0);
1201 std::vector<std::pair<MInt, MInt>> cellId2globalFPId;
1202 std::vector<MInt> FPDispls;
1205 std::vector<MFloat> FPWeighting;
1206 computeDistance2Map(FPDistInfo, &FP_distance[0], cellId2globalFPId, FPDispls, FPWeighting);
1211 std::vector<std::pair<MInt, MInt>> cellId2globalFPId_(cellId2globalFPId.begin(), cellId2globalFPId.end());
1212 if(m_solver->m_blockType !=
"porous") {
1213 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1214 cellId2globalFPId_[cellId] = std::make_pair(-1, -1);
1217 setUpNearMapComm(cellId2globalFPId_, FPDispls, FPWeighting, m_FPCellId2recvCell_porous, m_FPSendcounts_porous,
1218 m_FPSendCells_porous);
1222 modifyFPDistance(FPDistInfo, &FP_distance[0], cellId2globalFPId, wallWeighting);
1225 getCloserMap(m_cells->fq[FQ->WALLDISTANCE], cellId2globalWallId, &FP_distance[0], cellId2globalFPId,
1226 m_cells->fq[FQ->WALLDISTANCE]);
1229 setUpNearMapComm(cellId2globalWallId, wallDispls, wallWeighting, m_wallCellId2recvCell, m_wallSendcounts,
1233 setUpNearMapComm(cellId2globalFPId, FPDispls, FPWeighting, m_FPCellId2recvCell, m_FPSendcounts, m_FPSendCells);
1243template <MBool isRans>
1245 MFloat*
const FP_distance,
1246 std::vector<std::pair<MInt, MInt>>& cellId2globalFPId,
1247 const std::vector<MFloat>& wallWeighting) {
1248 if(!m_solver->m_porous)
return;
1250 MFloat maxWallDistance = numeric_limits<MFloat>::max();
1251 maxWallDistance = Context::getSolverProperty<MFloat>(
"maxWallDistance", m_solverId, AT_, &maxWallDistance);
1254 if(m_solver->m_blockType ==
"porous") {
1255 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1256 FP_distance[cellId] = maxWallDistance;
1257 cellId2globalFPId[cellId] = std::make_pair(-1, -1);
1262 const MFloat*
const RESTRICT por = &m_cells->fq[FQ->POROSITY][0];
1263 const MFloat*
const RESTRICT Da = &m_cells->fq[FQ->DARCY][0];
1264 const auto& c_wd = m_solver->m_c_wd;
1266 const MInt noWallDistInfo = FPDistInfo.size();
1267 std::vector<MInt> wallNormalIndex(noWallDistInfo);
1268 std::vector<MInt> normalDir(noWallDistInfo);
1269 std::vector<std::array<MInt, 2 * nDim>> startEndTangential(noWallDistInfo);
1271 MInt cellmemSize = 0;
1272 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
1273 const MInt*
const start = FPDistInfo[nn]->start1;
1274 const MInt*
const end = FPDistInfo[nn]->end1;
1275 const MInt face = FPDistInfo[nn]->face;
1276 normalDir[nn] = face / 2;
1277 wallNormalIndex[nn] = start[normalDir[nn]] - (face % 2);
1280 for(
MInt dim = 0; dim < nDim - 1; ++dim) {
1281 const MInt tangentialDir = (normalDir[nn] + (dim + 1)) % nDim;
1282 startEndTangential[nn][dim * 2 + 0] = start[tangentialDir];
1283 startEndTangential[nn][dim * 2 + 1] = end[tangentialDir];
1284 size *= startEndTangential[nn][dim * 2 + 1] - startEndTangential[nn][dim * 2 + 0];
1286 cellmemSize += size;
1288 cout <<
"Debug output: FPDistInfo=" << nn <<
": face=" << face <<
"; normalDir=" << normalDir[nn]
1289 <<
"; wallNormalIndex=" << wallNormalIndex[nn] <<
"; startEndTangential=" << startEndTangential[nn][0] <<
"|"
1290 << startEndTangential[nn][1] <<
"normal start/end=" << start[normalDir[nn]] <<
"|" << end[normalDir[nn]]
1301 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
1303 MInt& i = (normalDir[nn] == 0) ? wallNormalIndex[nn] : tIdx;
1304 MInt& j = (normalDir[nn] == 0) ? tIdx : wallNormalIndex[nn];
1305 for(tIdx = startEndTangential[nn][0]; tIdx < startEndTangential[nn][1]; ++tIdx) {
1306 const MInt cellId = cellIndex(i, j);
1307 correctionMem[cnt++] = c_wd * sqrt(Da[cellId] / por[cellId]);
1313 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
1315 std::vector<MInt> recvcounts(noRanks);
1316 MPI_Allgather(&cellmemSize, 1, MPI_INT, recvcounts.data(), 1, MPI_INT, m_solver->m_StructuredComm, AT_,
"cellmemSize",
1318 std::vector<MInt> displs(noRanks);
1319 for(
MInt r = 0; r < noRanks - 1; ++r) {
1320 displs[r + 1] = displs[r] + recvcounts[r];
1322 const MInt noTotalWallPoints = displs[noRanks - 1] + recvcounts[noRanks - 1];
1324 std::vector<MFloat> correctionMemAll(noTotalWallPoints);
1325 MPI_Allgatherv(&correctionMem[0], cellmemSize, MPI_DOUBLE, correctionMemAll.
data(), recvcounts.data(), displs.data(),
1326 MPI_DOUBLE, m_solver->m_StructuredComm, AT_,
"correctionMem",
"correctionMemAll");
1330 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1331 const MInt globalFPId1 = cellId2globalFPId[cellId].first;
1333 if(globalFPId1 > -1) {
1334 const MInt globalFPId2 = cellId2globalFPId[cellId].second;
1335 const MFloat my_FP_distance = FP_distance[cellId];
1336 const MFloat correction1 = correctionMemAll[globalFPId1];
1337 const MFloat correction2 = correctionMemAll[globalFPId2];
1338 const MFloat correction = wallWeighting[cellId] * correction1 + (1 - wallWeighting[cellId]) * correction2;
1339 const MFloat my_new_FP_distance = my_FP_distance + correction;
1340 if(my_new_FP_distance < maxWallDistance) {
1341 FP_distance[cellId] = my_new_FP_distance;
1343 FP_distance[cellId] = maxWallDistance;
1344 cellId2globalFPId[cellId] = std::make_pair(-1, -1);
1365template <MBool isRans>
1368 MFloat*
const r_cells_fq_distance,
1369 std::vector<std::pair<MInt, MInt>>& r_cellId2globalWallId,
1370 std::vector<MInt>& r_displs,
1371 std::vector<MFloat>& r_weighting) {
1373 MFloat maxWallDistance = numeric_limits<MFloat>::max();
1374 maxWallDistance = Context::getSolverProperty<MFloat>(
"maxWallDistance", m_solverId, AT_, &maxWallDistance);
1375 for(
MInt id = 0;
id < m_noCells; ++
id) {
1376 r_cells_fq_distance[
id] = maxWallDistance;
1380 const MInt noWallDistInfo = wallDistInfo.size();
1381 std::vector<MInt> wallNormalIndex(noWallDistInfo);
1382 std::vector<MInt> normalDir(noWallDistInfo);
1383 std::vector<std::array<MInt, 2 * nDim>> startEndTangential(noWallDistInfo);
1385 MInt cellmemSize = 0;
1386 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
1388 const MInt*
const start = wallDistInfo[nn]->start1;
1389 const MInt*
const end = wallDistInfo[nn]->end1;
1390 const MInt face = wallDistInfo[nn]->face;
1391 normalDir[nn] = face / 2;
1392 wallNormalIndex[nn] = start[normalDir[nn]];
1395 for(
MInt dim = 0; dim < nDim - 1; ++dim) {
1396 const MInt tangentialDir = (normalDir[nn] + (dim + 1)) % nDim;
1397 startEndTangential[nn][dim * 2 + 0] = start[tangentialDir];
1398 startEndTangential[nn][dim * 2 + 1] =
1399 end[tangentialDir] + 1;
1400 size *= startEndTangential[nn][dim * 2 + 1] - startEndTangential[nn][dim * 2 + 0];
1402 cellmemSize += size;
1404 cout <<
"Debug output: wallDistInfo=" << nn <<
": face=" << face <<
"; normalDir=" << normalDir[nn]
1405 <<
"; wallNormalIndex=" << wallNormalIndex[nn] <<
"; startEndTangential=" << startEndTangential[nn][0] <<
"|"
1406 << startEndTangential[nn][1] <<
"normal start/end=" << start[normalDir[nn]] <<
"|" << end[normalDir[nn]]
1413 MFloatScratchSpace coordGridMem(std::max(1, nDim * cellmemSize), AT_,
"coordGridMem");
1415 for(
MInt dim = 0; dim < nDim; ++dim)
1416 wallDistSurfCoords[dim] = &coordGridMem[dim * cellmemSize];
1418 MIntScratchSpace isStartEndPoint(std::max(1, cellmemSize), AT_,
"isStartEndPoint");
1422 for(
MInt nn = 0; nn < noWallDistInfo; ++nn) {
1424 MInt& i = (normalDir[nn] == 0) ? wallNormalIndex[nn] : tIdx;
1425 MInt& j = (normalDir[nn] == 0) ? tIdx : wallNormalIndex[nn];
1426 for(tIdx = startEndTangential[nn][0]; tIdx < startEndTangential[nn][1]; ++tIdx) {
1427 const MInt p = getPointIdFromCell(i, j);
1428 wallDistSurfCoords[0][cnt] = m_grid->m_coordinates[0][p];
1429 wallDistSurfCoords[1][cnt] = m_grid->m_coordinates[1][p];
1431 if(tIdx == startEndTangential[nn][0] && tIdx == startEndTangential[nn][1] - 1)
1432 isStartEndPoint[cnt] = 3;
1433 else if(tIdx == startEndTangential[nn][0])
1434 isStartEndPoint[cnt] = 1;
1435 else if(tIdx == startEndTangential[nn][1] - 1)
1436 isStartEndPoint[cnt] = -1;
1438 isStartEndPoint[cnt] =
1446 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
1448 std::vector<MInt> recvcounts(noRanks);
1449 MPI_Allgather(&cellmemSize, 1, MPI_INT, recvcounts.data(), 1, MPI_INT, m_solver->m_StructuredComm, AT_,
"cellmemSize",
1451 r_displs.resize(noRanks);
1452 for(
MInt r = 0; r < noRanks - 1; ++r) {
1453 r_displs[r + 1] = r_displs[r] + recvcounts[r];
1455 const MInt noTotalWallPoints = r_displs[noRanks - 1] + recvcounts[noRanks - 1];
1457 std::vector<std::vector<MFloat>> wallDistSurfCoordsAll(nDim);
1458 for(
MInt dim = 0; dim < nDim; ++dim) {
1459 wallDistSurfCoordsAll[dim].resize(noTotalWallPoints);
1460 MPI_Allgatherv(&wallDistSurfCoords[dim][0], cellmemSize, MPI_DOUBLE, wallDistSurfCoordsAll[dim].data(),
1461 recvcounts.
data(), r_displs.data(), MPI_DOUBLE, m_solver->m_StructuredComm, AT_,
1462 "wallDistSurfCoords",
"wallDistSurfCoordsAll");
1464 std::vector<MInt> isStartEndPointAll(noTotalWallPoints);
1465 MPI_Allgatherv(&isStartEndPoint[0], cellmemSize, MPI_INT, isStartEndPointAll.
data(), recvcounts.data(),
1466 r_displs.data(), MPI_INT, m_solver->m_StructuredComm, AT_,
"isStartEndPoint",
"isStartEndPointAll");
1468 std::vector<MInt> blockIds(noRanks, -1);
1469 const MInt myBlockId = m_solver->m_blockId;
1470 MPI_Allgather(&myBlockId, 1, MPI_INT, blockIds.data(), 1, MPI_INT, m_solver->m_StructuredComm, AT_,
"myBlockId",
1478 r_cellId2globalWallId.assign(m_noCells, std::make_pair(-1, -1));
1481 r_weighting.assign(m_noCells, 0.0);
1485 if(noTotalWallPoints == 0)
return;
1489 vector<Point<3>> pts;
1491 std::vector<MInt> cellIdShifts(noTotalWallPoints + 1, 0);
1492 for(
MInt globalWallId = 0; globalWallId < noTotalWallPoints; ++globalWallId) {
1493 Point<3> a(wallDistSurfCoordsAll[0][globalWallId], wallDistSurfCoordsAll[1][globalWallId], 0, globalWallId);
1495 cellIdShifts[globalWallId + 1] = cellIdShifts[globalWallId] - 1 * (isStartEndPointAll[globalWallId] == -1);
1500 auto getDomainId = [&r_displs, noRanks](
const MInt id,
const MInt hint = 0) {
1501 for(
MInt rank = hint; rank < (signed)r_displs.size() - 1; ++rank) {
1502 if(r_displs[rank + 1] >
id)
return rank;
1507 static constexpr MFloat radius = std::numeric_limits<MFloat>::max();
1508 static constexpr MFloat eps = 1e-16;
1513 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1514 Point<3> pt(m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId], 0);
1515 MBool overflow =
false;
1517 if(nfound != 3)
mTerm(1,
"Come on, your mesh should have at least 3 wall grid points!");
1518 MInt globalWallId1 = results[0];
1519 MInt globalWallId1_ = results[1];
1520 MInt globalWallId1__ = results[2];
1524 const MFloat r2 =
POW2(wallDistSurfCoordsAll[0][globalWallId1] - wallDistSurfCoordsAll[0][globalWallId1_])
1525 +
POW2(wallDistSurfCoordsAll[1][globalWallId1] - wallDistSurfCoordsAll[1][globalWallId1_]);
1526 const MFloat r3 =
POW2(wallDistSurfCoordsAll[0][globalWallId1] - wallDistSurfCoordsAll[0][globalWallId1__])
1527 +
POW2(wallDistSurfCoordsAll[1][globalWallId1] - wallDistSurfCoordsAll[1][globalWallId1__]);
1532 if(nfound == 2 && r3 < r2) {
1533 const MInt temp = globalWallId1_;
1534 globalWallId1_ = globalWallId1__;
1535 globalWallId1__ = temp;
1540 if(isStartEndPointAll[globalWallId1] == 3 && isStartEndPointAll[globalWallId1_] == 3)
mTerm(1,
"");
1541 if(isStartEndPointAll[globalWallId1] == 3) {
1542 globalWallId1 = globalWallId1_;
1545 if(isStartEndPointAll[globalWallId1_] == 3) {
1556 MInt globalCellId1 = -1;
1557 MInt globalCellId2 = -1;
1558 MFloat distance = std::numeric_limits<MFloat>::max(), weight;
1559 if(nfound == 1 && abs(isStartEndPointAll[globalWallId1]) == 1) {
1561 const MInt globalWallId2 = globalWallId1 + isStartEndPointAll[globalWallId1];
1562 globalCellId1 = (isStartEndPointAll[globalWallId1] == -1) ? globalWallId1 - 1 : globalWallId1;
1563 globalCellId1 += cellIdShifts[globalWallId1];
1564 const MFloat p1[nDim] = {wallDistSurfCoordsAll[0][globalWallId1], wallDistSurfCoordsAll[1][globalWallId1]};
1565 const MFloat p2[nDim] = {wallDistSurfCoordsAll[0][globalWallId2], wallDistSurfCoordsAll[1][globalWallId2]};
1566 const MFloat pTarget[nDim] = {m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId]};
1568 shortestDistanceToLineElement(p1, p2, pTarget, distance, fraction);
1570 if(fraction > 0.5 + 1e-8) {
1572 msg <<
"ERROR: p1=" << p1[0] <<
"|" << p1[1] <<
" p2=" << p2[0] <<
"|" << p2[1] <<
" pTarget=" << pTarget[0]
1573 <<
"|" << pTarget[1] <<
" distance=" << distance <<
" fraction=" << fraction << endl;
1575 mTerm(1,
"Fraction is >0.5, so nearest grid point is supposed to be p2 and not p1!");
1586 globalWallId2 = globalWallId1 - 1;
1587 globalWallId3 = globalWallId1 + 1;
1588 globalCellId1 = globalWallId2;
1589 globalCellId1 += cellIdShifts[globalWallId2];
1590 globalCellId2 = globalWallId1;
1591 globalCellId2 += cellIdShifts[globalWallId1];
1592 }
else if(nfound == 2) {
1594 if(abs(isStartEndPointAll[globalWallId1]) + abs(isStartEndPointAll[globalWallId1_]) != 2) {
1596 const MInt blockId1 = blockIds[getDomainId(globalWallId1)];
1597 const MInt blockId1_ = blockIds[getDomainId(globalWallId1_)];
1598 if(blockId1 == blockId1_) {
1599 cout << m_solver->domainId() <<
"|" << cellId <<
" " << globalWallId1 <<
" " << globalWallId1_ <<
" "
1600 << globalWallId1__ <<
": cellCoord=" << setprecision(12) << m_cells->coordinates[0][cellId] <<
"|"
1601 << m_cells->coordinates[1][cellId] <<
"; wallCoord1=" << wallDistSurfCoordsAll[0][globalWallId1] <<
"|"
1602 << wallDistSurfCoordsAll[1][globalWallId1]
1603 <<
"; wallCoords1_=" << wallDistSurfCoordsAll[0][globalWallId1_] <<
"|"
1604 << wallDistSurfCoordsAll[1][globalWallId1_]
1605 <<
"; wallCoords1__=" << wallDistSurfCoordsAll[0][globalWallId1__] <<
"|"
1606 << wallDistSurfCoordsAll[1][globalWallId1__] << endl;
1608 cout <<
"ERROR: (x|y)_1=" << setprecision(12) << wallDistSurfCoordsAll[0][globalWallId1] <<
"|"
1609 << wallDistSurfCoordsAll[1][globalWallId1] <<
" (x|y)_2=" << wallDistSurfCoordsAll[0][globalWallId1_]
1610 <<
"|" << wallDistSurfCoordsAll[1][globalWallId1_] << endl;
1611 mTerm(1,
"One grid point found twice. Both grid points have neighbors to both sides, which is unexpected!");
1613 if(blockId1 != myBlockId && blockId1_ != myBlockId)
mTerm(1,
"This case is not implemented yet!");
1614 if(blockId1_ == myBlockId) globalWallId1 = globalWallId1_;
1616 globalWallId2 = globalWallId1 - 1;
1617 globalWallId3 = globalWallId1 + 1;
1618 globalCellId1 = globalWallId2;
1619 globalCellId1 += cellIdShifts[globalWallId2];
1620 globalCellId2 = globalWallId1;
1621 globalCellId2 += cellIdShifts[globalWallId1];
1623 globalWallId2 = globalWallId1 + isStartEndPointAll[globalWallId1];
1624 globalWallId3 = globalWallId1_ + isStartEndPointAll[globalWallId1_];
1625 globalCellId1 = (isStartEndPointAll[globalWallId1] == -1) ? globalWallId1 - 1 : globalWallId1;
1626 globalCellId1 += cellIdShifts[globalWallId1];
1627 globalCellId2 = (isStartEndPointAll[globalWallId1_] == -1) ? globalWallId1_ - 1 : globalWallId1_;
1628 globalCellId2 += cellIdShifts[globalWallId1_];
1633 msg << setprecision(12) <<
"p1=" << wallDistSurfCoordsAll[0][globalWallId1] <<
"|"
1634 << wallDistSurfCoordsAll[1][globalWallId1] <<
", p2=" << wallDistSurfCoordsAll[0][globalWallId1_] <<
"|"
1635 << wallDistSurfCoordsAll[1][globalWallId1_] <<
", p3=" << wallDistSurfCoordsAll[0][globalWallId1__] <<
"|"
1636 << wallDistSurfCoordsAll[1][globalWallId1__] << endl;
1638 mTerm(1,
"Three wall grid points coincide. This situation is unknown!");
1645 const MFloat p1[nDim] = {wallDistSurfCoordsAll[0][globalWallId1], wallDistSurfCoordsAll[1][globalWallId1]};
1646 const MFloat p2[nDim] = {wallDistSurfCoordsAll[0][globalWallId2], wallDistSurfCoordsAll[1][globalWallId2]};
1647 const MFloat p3[nDim] = {wallDistSurfCoordsAll[0][globalWallId3], wallDistSurfCoordsAll[1][globalWallId3]};
1648 const MFloat pTarget[nDim] = {m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId]};
1649 lineLengths[0] = shortestDistanceToLineElement(p1, p2, pTarget, distances[0], fractions[0]);
1650 lineLengths[1] = shortestDistanceToLineElement(p1, p3, pTarget, distances[1], fractions[1]);
1651 const MInt i = distances[1] < distances[0];
1653 if(fractions[i] > 0.5 + 1e-8) {
1655 msg <<
"Error p1=" << p1[0] <<
"|" << p1[1] <<
" p2=" << p2[0] <<
"|" << p2[1] <<
" p3=" << p3[0] <<
"|"
1656 << p3[1] <<
" pTarget=" << pTarget[0] <<
"|" << pTarget[1] <<
" distance=" << distance
1657 <<
" fraction=" << fractions[i] <<
" " << fractions[1 - i] << endl;
1659 mTerm(1,
"Fraction >0.5, so nearest grid point can not be p1!");
1662 weight = (fractions[i] * lineLengths[i] + 0.5 * lineLengths[1 - i]) / (0.5 * (lineLengths[0] + lineLengths[1]));
1663 distance = distances[i];
1666 const MInt temp = globalCellId1;
1667 globalCellId1 = globalCellId2;
1668 globalCellId2 = temp;
1672 if(distance < r_cells_fq_distance[cellId]) {
1673 ASSERT(globalCellId1 != -1,
"");
1676 globalCellId2 = (globalCellId2 == -1) ? globalCellId1 : globalCellId2;
1677 r_cellId2globalWallId[cellId] = std::make_pair(globalCellId1, globalCellId2);
1678 r_weighting[cellId] = weight;
1679 r_cells_fq_distance[cellId] = distance;
1687 for(
MInt i = 1; i < (signed)r_displs.size(); ++i) {
1688 r_displs[i] = r_displs[i] + cellIdShifts[r_displs[i]];
1693 MInt noNearWallCells = 0;
1696 std::set<MInt> globalWallIds;
1697 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1698 if(r_cellId2globalWallId[cellId].first != -1) {
1700 globalWallIds.insert(r_cellId2globalWallId[cellId].first);
1702 if(r_cellId2globalWallId[cellId].second != -1) {
1703 globalWallIds.insert(r_cellId2globalWallId[cellId].second);
1707 cout <<
"::computeDistance2Map: rank=" << m_solver->domainId() <<
" cellmemSize=" << cellmemSize
1708 <<
" noTotalWallPoints=" << noTotalWallPoints <<
" #cells near wall=" << noNearWallCells
1709 <<
" #globalWallIds=" << globalWallIds.size() << endl;
1724template <MBool isRans>
1726 MFloat*
const r_cells_fq_distance,
1727 std::vector<MInt>& r_cellId2globalWallId,
1728 std::vector<MInt>& r_displs){
1731 MFloat maxWallDistance = numeric_limits<MFloat>::max();
1732 maxWallDistance = Context::getSolverProperty<MFloat>(
"maxWallDistance", m_solverId, AT_, &maxWallDistance);
1733 for(
MInt id=0;
id<m_noCells; ++
id){
1734 r_cells_fq_distance[
id] = maxWallDistance;
1738 const MInt noWallDistInfo = wallDistInfo.size();
1739 std::vector<MInt> wallNormalIndex(noWallDistInfo);
1740 std::vector<MInt> normalDir(noWallDistInfo);
1741 std::vector<std::array<MInt, 2*nDim>> startEndTangential(noWallDistInfo);
1743 MInt cellmemSize = 0;
1744 for (
MInt nn=0; nn<noWallDistInfo;++nn) {
1745 const MInt*
const start = wallDistInfo[nn]->start1;
1746 const MInt*
const end = wallDistInfo[nn]->end1;
1747 const MInt face = wallDistInfo[nn]->face;
1748 normalDir[nn] = face/2;
1749 wallNormalIndex[nn] = start[normalDir[nn]];
1752 for (
MInt dim = 0; dim < nDim-1; ++dim) {
1753 const MInt tangentialDir = (normalDir[nn]+(dim+1))%nDim;
1754 startEndTangential[nn][dim*2+0] = start[tangentialDir];
1755 startEndTangential[nn][dim*2+1] = end[tangentialDir];
1756 size *= startEndTangential[nn][dim*2+1] - startEndTangential[nn][dim*2+0];
1758 cellmemSize += size;
1760 cout <<
"Debug output: wallDistInfo=" << nn <<
": face=" << face <<
"; normalDir="
1761 << normalDir[nn] <<
"; wallNormalIndex=" << wallNormalIndex[nn] <<
"; startEndTangential="
1762 << startEndTangential[nn][0] <<
"|" << startEndTangential[nn][1] <<
"normal start/end=" << start[normalDir[nn]] <<
"|" << end[normalDir[nn]] << endl;
1770 for (
MInt dim = 0; dim < nDim; ++dim)
1771 wallDistSurfCoords[dim] = &coordCellMem[dim*cellmemSize];
1775 for (
MInt nn=0; nn<noWallDistInfo; ++nn) {
1777 MInt& i = (normalDir[nn]==0) ? wallNormalIndex[nn] : tIdx;
1778 MInt& j = (normalDir[nn]==0) ? tIdx : wallNormalIndex[nn];
1779 MInt inc[] = {0, 0};
1780 inc[1-normalDir[nn]] = 1;
1781 for (tIdx = startEndTangential[nn][0]; tIdx < startEndTangential[nn][1]; ++tIdx) {
1782 const MInt p1 = getPointIdFromCell(i, j);
1783 const MInt p2 = getPointIdFromPoint(p1, inc[0], inc[1]);
1784 wallDistSurfCoords[0][cnt] = 0.5*(m_grid->m_coordinates[0][p1] + m_grid->m_coordinates[0][p2]);
1785 wallDistSurfCoords[1][cnt] = 0.5*(m_grid->m_coordinates[1][p1] + m_grid->m_coordinates[1][p2]);
1794 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
1796 std::vector<MInt> recvcounts(noRanks);
1797 MPI_Allgather(&cellmemSize, 1, MPI_INT, recvcounts.data(), 1, MPI_INT, m_solver->m_StructuredComm, AT_,
1798 "cellmemSize",
"recvcounts");
1799 r_displs.resize(noRanks);
1800 for (
MInt r = 0; r < noRanks-1; ++r) {
1801 r_displs[r+1] = r_displs[r] + recvcounts[r];
1803 const MInt noTotalWallPoints = r_displs[noRanks-1] + recvcounts[noRanks-1];
1805 std::vector<std::vector<MFloat>> wallDistSurfCoordsAll(nDim);
1806 for (
MInt dim = 0; dim < nDim; ++dim) {
1807 wallDistSurfCoordsAll[dim].resize(noTotalWallPoints);
1808 MPI_Allgatherv(&wallDistSurfCoords[dim][0], cellmemSize, MPI_DOUBLE,
1809 wallDistSurfCoordsAll[dim].data(), recvcounts.data(), r_displs.data(), MPI_DOUBLE,
1810 m_solver->m_StructuredComm, AT_,
"wallDistSurfCoords",
"wallDistSurfCoordsAll");
1816 r_cellId2globalWallId.assign(m_noCells, -1);
1820 vector < Point<3> > pts;
1821 for(
MInt globalWallId=0; globalWallId<noTotalWallPoints; ++globalWallId){
1822 Point<3> a(wallDistSurfCoordsAll[0][globalWallId],wallDistSurfCoordsAll[1][globalWallId], 0, globalWallId);
1832 Point<3> pt(m_cells->coordinates[0][cellId],m_cells->coordinates[1][cellId], 0);
1833 const MInt globalWallId = tree.nearest(pt, distance);
1835 if (distance < r_cells_fq_distance[cellId]) {
1836 r_cellId2globalWallId[
cellId] = globalWallId;
1843 MInt noNearWallCells = 0;
1846 std::set<MInt> globalWallIds;
1848 if (r_cellId2globalWallId[cellId]!=-1) {
1850 globalWallIds.insert(r_cellId2globalWallId[cellId]);
1854 cout <<
"::computeDistance2Map: rank=" << m_solver->domainId() <<
" cellmemSize="
1855 << cellmemSize <<
" noTotalWallPoints=" << noTotalWallPoints <<
" #cells near wall="
1856 << noNearWallCells <<
" #globalWallIds=" << globalWallIds.size() << endl;
1874template <MBool isRans>
1875template <
typename T>
1877 std::vector<std::pair<MInt, MInt>>& cellId2globalWallId1,
1878 const MFloat*
const cells_fq_distance2,
1879 std::vector<std::pair<MInt, MInt>>& cellId2globalWallId2,
1880 MFloat*
const cells_fq_distance,
1883 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1884 if(cellId2globalWallId1[cellId].first != -1 && cellId2globalWallId2[cellId].first != -1) {
1886 const MBool swtch = comparator(cellId, cells_fq_distance1[cellId], cells_fq_distance2[cellId]);
1888 cellId2globalWallId2[cellId] = std::make_pair(-1, -1);
1889 cells_fq_distance[cellId] = cells_fq_distance1[cellId];
1891 cellId2globalWallId1[cellId] = std::make_pair(-1, -1);
1892 cells_fq_distance[cellId] = cells_fq_distance2[cellId];
1894 }
else if(cellId2globalWallId1[cellId].first != -1) {
1895 cells_fq_distance[cellId] = cells_fq_distance1[cellId];
1897 cells_fq_distance[cellId] = cells_fq_distance2[cellId];
1913template <MBool isRans>
1915 const std::vector<MInt>& displs,
1916 const std::vector<MFloat>& weighting,
1917 std::map<
MInt, std::tuple<MInt, MInt, MFloat>>& r_cellId2recvCell,
1918 std::vector<MInt>& r_sendcounts,
1919 std::vector<MInt>& r_sendCells) {
1921 std::set<MInt> globalWallIds;
1922 MInt noNearMapCells = 0;
1923 for(
MInt cellId = 0; cellId < m_noCells; ++cellId, ++noNearMapCells) {
1924 if(cellId2globalWallId[cellId].first != -1) {
1925 globalWallIds.insert(cellId2globalWallId[cellId].first);
1927 globalWallIds.insert(cellId2globalWallId[cellId].second);
1931 const MInt noRanks = displs.size();
1932 auto getDomainId = [&displs, noRanks](
const MInt id,
const MInt hint = 0) {
1933 for(
MInt rank = hint; rank < (signed)displs.size() - 1; ++rank) {
1934 if(displs[rank + 1] >
id)
return rank;
1940 std::vector<MInt> globalWallId2localId((globalWallIds.empty()) ? 0 : *globalWallIds.rbegin() + 1);
1942 std::vector<MInt> recvWallIds(globalWallIds.size());
1943 std::vector<MInt> sendcounts(noRanks, 0);
1944 MInt domainId_temp = 0;
1945 MInt localWallId = 0;
1946 for(
auto it = globalWallIds.begin(); it != globalWallIds.end(); ++it, ++localWallId) {
1947 globalWallId2localId[*it] = localWallId;
1948 domainId_temp = getDomainId(*it, domainId_temp);
1950 recvWallIds[localWallId] = *it - displs[domainId_temp];
1951 ++sendcounts[domainId_temp];
1955 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
1957 if(cellId2globalWallId[cellId].first == -1)
continue;
1958 auto temp2 = std::make_tuple(globalWallId2localId[cellId2globalWallId[cellId].first],
1959 globalWallId2localId[cellId2globalWallId[cellId].second],
1961 r_cellId2recvCell.insert({cellId, temp2});
1965 std::vector<MInt> snghbrs(noRanks);
1966 std::iota(snghbrs.begin(), snghbrs.end(), 0);
1968 r_sendcounts.resize(noRanks);
1976 m_solver->m_StructuredComm,
1977 m_solver->domainId(),
1979 r_sendcounts.data());
1984 if((
signed)r_sendCells.size() != std::accumulate(&r_sendcounts[0], &r_sendcounts[0] + noRanks, 0))
1985 mTerm(1,
"Neeeeeeiiiiiiiiin!");
1988 const MInt cellmemSize =
1989 (m_solver->domainId() == noRanks - 1) ? 0 : displs[m_solver->domainId() + 1] - displs[m_solver->domainId()];
1990 if(cellmemSize != 0) {
1991 MInt min = std::numeric_limits<MInt>::max();
1993 for(
auto id : r_sendCells) {
1994 if(
id >= cellmemSize)
mTerm(1,
"Something went wrong!");
1995 min =
mMin(
id, min);
1996 max =
mMax(
id, max);
1999 mTerm(1,
"Scheisse: min!=0");
2001 if(max != cellmemSize - 1)
mTerm(1,
"Scheisse......");
2005 cout <<
"::computeLocalWallDistance: rank=" << m_solver->domainId()
2006 <<
" cellmemSize=" << cellmemSize <<
" #cells near wall="
2007 << r_cellId2recvCell.size() <<
" #globalWallIds=" << globalWallIds.size() << endl;
2012template <MBool isRans>
2015 vector<unique_ptr<StructuredWindowMap<nDim>>> wallDistInfo;
2016 vector<MInt> wallMapIndex;
2017 vector<unique_ptr<StructuredWindowMap<nDim>>> FPDistInfo;
2018 vector<MInt> FPMapIndex;
2020 for(
auto& auxDataMap : m_auxDataMap) {
2021 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
2022 m_solver->m_windowInfo->mapCpy(auxDataMap, temp);
2023 if(auxDataMap->isFluidPorousInterface) {
2024 FPDistInfo.push_back(move(temp));
2025 FPMapIndex.push_back(cnt);
2026 }
else if((
int)(auxDataMap->BC / 1000.0) == 1) {
2027 wallDistInfo.push_back(move(temp));
2028 wallMapIndex.push_back(cnt);
2033 distributeMapProperties(wallDistInfo, m_wallSendCells, m_wallSendcounts, m_wallCellId2recvCell, wallMapIndex,
2034 m_cells->fq[FQ->UTAU]);
2035 distributeMapProperties(FPDistInfo, m_FPSendCells, m_FPSendcounts, m_FPCellId2recvCell, FPMapIndex,
2036 m_cells->fq[FQ->UTAU]);
2038 distributeMapProperties(FPDistInfo, m_FPSendCells_porous, m_FPSendcounts_porous, m_FPCellId2recvCell_porous,
2039 FPMapIndex, m_cells->fq[FQ->UTAU2]);
2048template <MBool isRans>
2051 const std::vector<MInt>& sendCells,
2052 const std::vector<MInt>& sendcounts,
2053 const std::map<
MInt, std::tuple<MInt, MInt, MFloat>>& cellId2recvCell,
2054 const std::vector<MInt>& mapIndex,
2055 MFloat*
const targetBuffer) {
2056 static const MFloat UT = m_solver->m_Ma * sqrt(PV->TInfinity);
2057 MFloat*
const RESTRICT p = &m_cells->pvariables[PV->P][0];
2058 MFloat*
const RESTRICT rho = &m_cells->pvariables[PV->RHO][0];
2061 std::vector<MFloat> cf;
2063 for(
MInt map = 0; map < (signed)auxDataMap.size(); ++map) {
2064 const MInt mapOffsetCf = m_cells->cfOffsets[mapIndex[map]];
2065 const MInt normalDir = auxDataMap[map]->face / 2;
2066 const MInt tangentialDir = 1 - normalDir;
2067 const MInt*
const start = auxDataMap[map]->start1;
2068 const MInt*
const end = auxDataMap[map]->end1;
2069 const MInt size = end[tangentialDir] - start[tangentialDir];
2070 ASSERT((
signed)cf.size() == cnt,
"cf.size() == cnt");
2071 cf.resize(cnt + size);
2073 if((auxDataMap[map]->face) % 2 == 0) {
2074 i = start[normalDir];
2076 i = end[normalDir] - 1;
2078 MInt& reali = (normalDir == 0) ? i : j;
2079 MInt& realj = (normalDir == 0) ? j : i;
2081 for(j = start[tangentialDir]; j < end[tangentialDir]; ++j, ++cnt, ++ii) {
2083 const MInt cellId = cellIndex(reali, realj);
2084 const MFloat T = m_solver->m_gamma * p[cellId] / rho[cellId];
2085 const MFloat nuLaminar = SUTHERLANDLAW(T) / rho[cellId];
2090 * sqrt(
POW2(m_cells->cf[mapOffsetCf + 0 * size + ii]) +
POW2(m_cells->cf[mapOffsetCf + 1 * size + ii])))
2097 for(cnt = 0; cnt < (signed)sendCells.size(); ++cnt) {
2098 sendBuffer[cnt] = cf[sendCells[cnt]];
2103 MPI_Comm_size(m_solver->m_StructuredComm, &noRanks);
2104 std::vector<MInt> snghbrs(noRanks);
2105 std::iota(snghbrs.begin(), snghbrs.end(), 0);
2112 m_solver->m_StructuredComm,
2113 m_solver->domainId(),
2117 for(std::map<
MInt, std::tuple<MInt, MInt, MFloat>>::const_iterator it = cellId2recvCell.begin();
2118 it != cellId2recvCell.end();
2120 const MInt id1 = get<0>(it->second);
2121 const MInt id2 = get<1>(it->second);
2122 const MFloat weight = get<2>(it->second);
2123 const MFloat result = weight * recvBuffer[id1] + (1 - weight) * recvBuffer[id2];
2125 targetBuffer[it->first] = result;
2131template <MBool isRans>
2132template <MBool calcCp, MBool calcCf, MBool
interface>
2134 MFloat (&output)[calcCp + nDim * calcCf]) {
2138 static const MFloat UT = m_solver->m_Ma * sqrt(PV->TInfinity);
2139 static const MFloat fstagnationPressure = F1 / (CV->rhoInfinity * F1B2 *
POW2(UT));
2140 static const MFloat fre0 = F1 / (m_solver->m_Re0);
2144 const MFloat xRef = 0.5 * (m_grid->m_coordinates[0][pIJ] + m_grid->m_coordinates[0][pIJP]);
2145 const MFloat yRef = 0.5 * (m_grid->m_coordinates[1][pIJ] + m_grid->m_coordinates[1][pIJP]);
2150 const MFloat dx2 = sqrt(
POW2(m_cells->coordinates[0][cellIdP1] - m_cells->coordinates[0][cellId])
2151 +
POW2(m_cells->coordinates[1][cellIdP1] - m_cells->coordinates[1][cellId]));
2152 const MFloat dx1 = sqrt(
POW2(m_cells->coordinates[0][cellId] - xRef) +
POW2(m_cells->coordinates[1][cellId] - yRef));
2156 const MFloat p1 = m_cells->pvariables[PV->P][cellId];
2157 const MFloat p2 = m_cells->pvariables[PV->P][cellIdP1];
2159 const MFloat pW = ((p1 - p2) / dx2) * dx1 + p1;
2160 const MFloat cpn = (pW - PV->PInfinity) * fstagnationPressure;
2169 MFloat supportVec[nDim] = {};
2170 MFloat firstVec[nDim] = {};
2171 MFloat normalVec[nDim] = {};
2172 MFloat cellVec[nDim] = {};
2173 for(
MInt dim = 0; dim < nDim; dim++) {
2174 supportVec[dim] = m_grid->m_coordinates[dim][pIJ];
2175 firstVec[dim] = m_grid->m_coordinates[dim][pIJP] - m_grid->m_coordinates[dim][pIJ];
2176 cellVec[dim] = m_cells->coordinates[dim][cellId];
2179 normalVec[0] = -firstVec[1];
2180 normalVec[1] = firstVec[0];
2181 const MFloat normalLength = sqrt(
POW2(normalVec[0]) +
POW2(normalVec[1]));
2184 for(
MInt dim = 0; dim < nDim; dim++) {
2185 orthDist += (cellVec[dim] - supportVec[dim]) * normalVec[dim];
2188 orthDist = fabs(orthDist / normalLength);
2191 const MFloat T1 = temperature(cellId);
2192 const MFloat T2 = temperature(cellIdP1);
2195 const MFloat tBc = ((T1 - T2) / dx2) * dx1 + T1;
2196 const MFloat mue = SUTHERLANDLAW(tBc);
2199 const MFloat u1 = m_cells->pvariables[PV->U][cellId];
2200 const MFloat v1 = m_cells->pvariables[PV->V][cellId];
2206 const MFloat u2 = m_cells->pvariables[PV->U][cellIdP1];
2207 const MFloat v2 = m_cells->pvariables[PV->V][cellIdP1];
2208 uBc = ((u1 - u2) / dx2) * dx1 + u1;
2209 vBc = ((v1 - v2) / dx2) * dx1 + v1;
2211 if(m_solver->m_movingGrid) {
2212 uBc = F1B2 * (m_grid->m_velocity[0][pIJ] + m_grid->m_velocity[0][pIJP]);
2213 vBc = F1B2 * (m_grid->m_velocity[1][pIJ] + m_grid->m_velocity[1][pIJP]);
2218 MFloat dudeta = (u1 - uBc) / orthDist;
2219 MFloat dvdeta = (v1 - vBc) / orthDist;
2223 if(m_solver->m_forceSecondOrder) {
2224 const MFloat u2 = m_cells->pvariables[PV->U][cellIdP1];
2225 const MFloat v2 = m_cells->pvariables[PV->V][cellIdP1];
2226 const MFloat dx3 = dx1 + dx2;
2227 dudeta = (u1 * dx3 * dx3 + (dx1 * dx1 - dx3 * dx3) * uBc - u2 * dx1 * dx1) / (dx1 * dx3 * dx3 - dx1 * dx1 * dx3);
2228 dvdeta = (v1 * dx3 * dx3 + (dx1 * dx1 - dx3 * dx3) * vBc - v2 * dx1 * dx1) / (dx1 * dx3 * dx3 - dx1 * dx1 * dx3);
2231 const MFloat taux = mue * dudeta * fre0;
2232 const MFloat tauy = mue * dvdeta * fre0;
2234 const MFloat cfx = taux * fstagnationPressure;
2235 const MFloat cfy = tauy * fstagnationPressure;
2238 output[calcCp + 0] = cfx, output[calcCp + 1] = cfy;
2264template <MBool isRans>
2265template <MBool calcCp, MBool calcCf, MBool calcIntegrals>
2267 static_assert(calcCp || calcCf,
"Something went wrong");
2270 const MInt noForceCoefs = m_solver->m_noForceDataFields;
2271 auto& m_forceCoef = m_solver->m_forceCoef;
2273 const MFloat UT = m_solver->m_Ma * sqrt(PV->TInfinity);
2274 const MFloat stagnationPressure = (CV->rhoInfinity * F1B2 *
POW2(UT));
2275 const MFloat fstagnationEnergy = F1 / (CV->rhoInfinity * F1B2 *
POW3(UT));
2280 const MInt noWalls = m_solver->m_windowInfo->m_auxDataWindowIds.size();
2283 for(
MInt i = 0; i < (
MInt)noForceCoefs * noWalls; ++i) {
2284 m_forceCoef[i] = F0;
2289 for(
MInt map = 0; map < (
MInt)m_auxDataMap.size(); ++map) {
2291 if(auxDataWindows) {
2292 MBool takeIt =
false;
2293 for(
auto& m : m_solver->m_windowInfo->m_auxDataWindowIds) {
2294 if(m_auxDataMap[map]->Id2 == m.second) {
2299 if(!takeIt)
continue;
2302 const MBool interface = m_auxDataMap[map]->BC >= 6000 && m_auxDataMap[map]->BC < 6010;
2306 const MInt mapOffsetCf = m_cells->cfOffsets[map];
2307 const MInt mapOffsetCp = m_cells->cpOffsets[map];
2308 MInt* start = m_auxDataMap[map]->start1;
2309 MInt* end = m_auxDataMap[map]->end1;
2320 MFloat powerp[2] = {F0, F0};
2321 MFloat powerv[2] = {F0, F0};
2324 MInt n10[nDim] = {};
2325 MInt n01[nDim] = {};
2326 MInt n1m1[nDim] = {};
2327 MInt pCoordDir[(2 * (nDim - 1) - 1) * nDim] = {};
2331 MFloat output[calcCp + nDim * calcCf];
2334 if((m_auxDataMap[map]->face) % 2 == 0) {
2336 normalDir = m_auxDataMap[map]->face / 2;
2337 i = start[normalDir];
2340 normalDir = (m_auxDataMap[map]->face - 1) / 2;
2341 i = end[normalDir] - 1;
2344 n1m1[normalDir] = -1 * n;
2345 n10[normalDir] = (
MInt)(0.5 + (0.5 * (
MFloat)n));
2346 n01[normalDir] = (
MInt)(-0.5 + (0.5 * (
MFloat)n));
2348 const MInt firstTangential = 1 - normalDir;
2350 pCoordDir[firstTangential] = 1;
2352 const MInt sizeJ = end[firstTangential] - start[firstTangential];
2353 MInt& reali = (normalDir == 0) ? i : j;
2354 MInt& realj = (normalDir == 0) ? j : i;
2358 for(j = start[firstTangential]; j < end[firstTangential]; j++) {
2360 const MInt cellId = cellIndex(reali, realj);
2361 const MInt cellIdP1 = cellIndex(reali + n1m1[0], realj + n1m1[1]);
2364 const MInt pIJ = getPointIdFromCell(reali + n10[0], realj + n10[1]);
2365 const MInt pIJP = getPointIdFromPoint(pIJ, pCoordDir[0], pCoordDir[1]);
2368 (this->*calc_cp_cf_)(cellId, cellIdP1, pIJ, pIJP, output);
2372 m_cells->cp[mapOffsetCp + jj] = output[0];
2376 m_cells->cf[mapOffsetCf + 0 * sizeJ + jj] = output[calcCp + 0];
2377 m_cells->cf[mapOffsetCf + 1 * sizeJ + jj] = output[calcCp + 1];
2380 if((calcCf && m_solver->m_detailAuxData) || calcIntegrals) {
2383 const MFloat xRef = 0.5 * (m_grid->m_coordinates[0][pIJ] + m_grid->m_coordinates[0][pIJP]);
2384 const MFloat yRef = 0.5 * (m_grid->m_coordinates[1][pIJ] + m_grid->m_coordinates[1][pIJP]);
2389 const MFloat dxidx = m_cells->surfaceMetrics[nDim * normalDir + 0][cellIndex(reali + n01[0], realj + n01[1])];
2390 const MFloat dxidy = m_cells->surfaceMetrics[nDim * normalDir + 1][cellIndex(reali + n01[0], realj + n01[1])];
2392 if(calcCf && m_solver->m_detailAuxData) {
2394 m_cells->cf[mapOffsetCf + 2 * sizeJ + jj] = dxidx;
2395 m_cells->cf[mapOffsetCf + 3 * sizeJ + jj] = dxidy;
2398 m_cells->cf[mapOffsetCf + 4 * sizeJ + jj] = xRef;
2399 m_cells->cf[mapOffsetCf + 5 * sizeJ + jj] = yRef;
2403 MFloat considerValue = F1;
2404 if(m_solver->m_auxDataCoordinateLimits) {
2405 if(m_solver->m_auxDataLimits[0] <= xRef && xRef <= m_solver->m_auxDataLimits[1]
2406 && m_solver->m_auxDataLimits[2] <= yRef && yRef <= m_solver->m_auxDataLimits[3]) {
2414 cp[0] += (-1.0) * output[0] * dxidx * considerValue;
2415 cp[1] += (-1.0) * output[0] * dxidy * considerValue;
2419 cf[0] += output[calcCp + 0] * (sqrt(dxidx * dxidx + dxidy * dxidy)) * considerValue;
2420 cf[1] += output[calcCp + 1] * (sqrt(dxidx * dxidx + dxidy * dxidy)) * considerValue;
2425 m_solver->m_movingGrid ? F1B2 * (m_grid->m_velocity[0][pIJ] + m_grid->m_velocity[0][pIJP]) : F0;
2427 m_solver->m_movingGrid ? F1B2 * (m_grid->m_velocity[1][pIJ] + m_grid->m_velocity[1][pIJP]) : F0;
2429 const MFloat dp = output[0] * stagnationPressure;
2431 const MFloat P_px = (-1.0) * dp * uWall * fstagnationEnergy;
2432 const MFloat P_py = (-1.0) * dp * vWall * fstagnationEnergy;
2434 const MFloat taux = output[calcCp + 0] * stagnationPressure;
2435 const MFloat tauy = output[calcCp + 1] * stagnationPressure;
2437 const MFloat P_cfx = (taux)*uWall * fstagnationEnergy;
2438 const MFloat P_cfy = (tauy)*vWall * fstagnationEnergy;
2440 powerp[0] += P_px * dxidx * considerValue;
2441 powerp[1] += P_py * dxidy * considerValue;
2443 powerv[0] += P_cfx * (sqrt(dxidx * dxidx + dxidy * dxidy)) * considerValue;
2444 powerv[1] += P_cfy * (sqrt(dxidx * dxidx + dxidy * dxidy)) * considerValue;
2447 area += sqrt(dxidx * dxidx + dxidy * dxidy) * considerValue;
2456 for(
auto it = m_solver->m_windowInfo->m_auxDataWindowIds.cbegin();
2457 it != m_solver->m_windowInfo->m_auxDataWindowIds.cend();
2459 if(m_auxDataMap[map]->Id2 == it->second) {
2460 m_forceCoef[count * noForceCoefs + 0] += cf[0];
2461 m_forceCoef[count * noForceCoefs + 1] += cf[1];
2462 m_forceCoef[count * noForceCoefs + 2] += 0.0;
2463 m_forceCoef[count * noForceCoefs + 3] += 0.0;
2464 m_forceCoef[count * noForceCoefs + 4] += cp[0];
2465 m_forceCoef[count * noForceCoefs + 5] += cp[1];
2466 m_forceCoef[count * noForceCoefs + 6] += area;
2470 m_forceCoef[count * noForceCoefs + 7] += powerv[0];
2471 m_forceCoef[count * noForceCoefs + 8] += powerv[1];
2472 m_forceCoef[count * noForceCoefs + 9] += powerp[0];
2473 m_forceCoef[count * noForceCoefs + 10] += powerp[1];
2488template <MBool isRans>
2493 for(
MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2494 (this->*initBndryCndHandler[bcId])(bcId);
2499template <MBool isRans>
2501 return i + (j * m_nCells[1]);
2504template <MBool isRans>
2506 return i + (j * (m_nCells[1] + 1));
2509template <MBool isRans>
2511 return origin + incI + incJ * m_nPoints[1];
2514template <MBool isRans>
2520 if(std::find(FQ->fqNames.begin(), FQ->fqNames.end(),
"wallDistance") != FQ->fqNames.end()) {
2521 const MInt IJ[nDim] = {1, m_nCells[1]};
2522 MInt* start = m_physicalBCMap[bcId]->start1;
2523 MInt* end = m_physicalBCMap[bcId]->end1;
2529 const MInt face = m_physicalBCMap[bcId]->face;
2530 const MInt normalDir = face / 2;
2531 const MInt firstTangentialDir = (normalDir + 1) % nDim;
2532 const MInt normalDirStart = start[normalDir];
2533 const MInt firstTangentialStart = start[firstTangentialDir];
2534 const MInt firstTangentialEnd = end[firstTangentialDir];
2535 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
2537 const MInt n = (face % 2) * 2 - 1;
2538 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
2539 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
2540 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
2541 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
2543 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
2544 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
2545 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
2546 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
2547 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
2549 m_cells->fq[FQ->WALLDISTANCE][cellIdG1] =
2550 F2 * m_cells->fq[FQ->WALLDISTANCE][cellIdA1] - m_cells->fq[FQ->WALLDISTANCE][cellIdA2];
2551 m_cells->fq[FQ->WALLDISTANCE][cellIdG2] =
2552 F2 * m_cells->fq[FQ->WALLDISTANCE][cellIdG1] - m_cells->fq[FQ->WALLDISTANCE][cellIdA1];
2557template <MBool isRans>
2562template <MBool isRans>
2565 m_isothermalWallTemperature = F1;
2567 m_isothermalWallTemperature =
2568 Context::getSolverProperty<MFloat>(
"isothermalWallTemperature", m_solverId, AT_, &m_isothermalWallTemperature);
2572template <MBool isRans>
2577template <MBool isRans>
2579 correctWallDistanceAtBoundary(bcId);
2582template <MBool isRans>
2587template <MBool isRans>
2589 correctWallDistanceAtBoundary(bcId);
2593template <MBool isRans>
2602template <MBool isRans>
2608template <MBool isRans>
2610 correctWallDistanceAtBoundary(bcId);
2622template <MBool isRans>
2624 const MInt IJ[nDim] = {1, m_nCells[1]};
2625 MInt* start = m_physicalBCMap[bcId]->start1;
2626 MInt* end = m_physicalBCMap[bcId]->end1;
2632 const MInt face = m_physicalBCMap[bcId]->face;
2633 const MInt normalDir = face / 2;
2634 const MInt firstTangentialDir = (normalDir + 1) % nDim;
2635 const MInt normalDirStart = start[normalDir];
2636 const MInt firstTangentialStart = start[firstTangentialDir];
2637 const MInt firstTangentialEnd = end[firstTangentialDir];
2638 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
2640 const MInt n = (face % 2) * 2 - 1;
2641 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
2642 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
2643 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
2646 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
2647 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
2648 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
2649 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
2653 m_solver->getBlasiusVelocity(cellIdG1, vel);
2654 m_cells->pvariables[PV->U][cellIdG1] = vel[0];
2655 m_cells->pvariables[PV->V][cellIdG1] = vel[1];
2656 m_cells->pvariables[PV->P][cellIdG1] = m_cells->pvariables[PV->P][cellIdA1];
2657 m_cells->pvariables[PV->RHO][cellIdG1] = CV->rhoInfinity;
2659 m_solver->getBlasiusVelocity(cellIdG2, vel);
2660 m_cells->pvariables[PV->U][cellIdG2] = vel[0];
2661 m_cells->pvariables[PV->V][cellIdG2] = vel[1];
2662 m_cells->pvariables[PV->P][cellIdG2] =
2663 F2 * m_cells->pvariables[PV->P][cellIdG1] - m_cells->pvariables[PV->P][cellIdA1];
2664 m_cells->pvariables[PV->RHO][cellIdG2] = CV->rhoInfinity;
2672template <MBool isRans>
2677 MInt Id = m_channelSurfaceIndexMap[bcId];
2678 if(Id < 0) cerr <<
"id smaller than zero ==> error" << endl;
2679 MInt* startface = &m_solver->m_windowInfo->channelSurfaceIndices[Id]->start1[0];
2680 MInt* endface = &m_solver->m_windowInfo->channelSurfaceIndices[Id]->end1[0];
2685 if(m_solver->m_initialCondition == 1233) {
2689 MFloat uTau = m_solver->m_ReTau * m_solver->m_Ma * sqrt(PV->TInfinity) / m_solver->m_Re;
2690 m_solver->m_deltaP = -CV->rhoInfinity *
POW2(uTau) * F2 * (m_solver->m_channelLength) / m_solver->m_channelHeight;
2691 m_solver->m_channelPresInlet = PV->PInfinity;
2692 m_solver->m_channelPresOutlet = PV->PInfinity + m_solver->m_deltaP;
2693 m_log <<
"=========== Turb. Channel Flow BC Summary =========== " << endl;
2694 m_log <<
"-->Turbulent channel flow deltaP: " << m_solver->m_deltaP << endl;
2695 m_log <<
"-->channel friciton velocity: " << uTau << endl;
2696 m_log <<
"-->Channel pressure inflow: " << m_solver->m_channelPresInlet << endl;
2697 m_log <<
"-->Channel pressure outflow: " << m_solver->m_channelPresOutlet << endl;
2698 m_log <<
"=========== Turb. Channel Flow BC Summary Finished =========== " << endl;
2699 }
else if(m_solver->m_initialCondition == 1234) {
2705 m_solver->m_deltaP = -12.0 * PV->UInfinity * SUTHERLANDLAW(PV->TInfinity) * m_solver->m_channelLength
2706 / (
POW2(m_solver->m_channelHeight) * m_solver->m_Re0);
2707 m_log <<
"=========== Lam. Channel Flow BC Summary =========== " << endl;
2708 m_log <<
"Laminar channel deltaP: " << m_solver->m_deltaP << endl;
2709 m_log <<
"Theoretical cD total (both channel walls): "
2710 << m_solver->m_deltaP * m_solver->m_channelHeight * m_solver->m_channelWidth
2711 / (0.5 * CV->rhoInfinity *
POW2(PV->UInfinity))
2713 m_log <<
"Theoretical cD (single wall): "
2714 << m_solver->m_deltaP * m_solver->m_channelHeight * m_solver->m_channelWidth
2715 / (0.5 * CV->rhoInfinity *
POW2(PV->UInfinity) * 2.0)
2717 m_log <<
"Theoretical cF total (both channel walls): "
2718 << m_solver->m_deltaP * m_solver->m_channelHeight
2719 / (0.5 * CV->rhoInfinity *
POW2(PV->UInfinity) * m_solver->m_channelLength)
2721 m_log <<
"Theoretical cF (single wall): "
2722 << m_solver->m_deltaP * m_solver->m_channelHeight
2723 / (0.5 * CV->rhoInfinity *
POW2(PV->UInfinity) * m_solver->m_channelLength * 2.0)
2725 m_log <<
"=========== Lam. Channel Flow BC Summary Finished =========== " << endl;
2728 for(
MInt dim = 0; dim < nDim; dim++) {
2729 if(startface[dim] == endface[dim]) {
2732 if(startface[dim] == m_noGhostLayers) {
2740 if(m_physicalBCMap[bcId]->face == 0) {
2741 MPI_Comm_rank(m_solver->m_commChannelIn, &m_channelInflowRank);
2752 for(
MInt j = startface[1]; j < endface[1]; j++) {
2753 cellId = cellIndex(ii, j);
2754 surface += sqrt(
POW2(m_cells->cellMetrics[0][cellId]) +
POW2(m_cells->cellMetrics[1][cellId]));
2762 for(
MInt j = startface[1]; j < endface[1]; j++) {
2763 cellId = cellIndex(ii - 1, j);
2764 surface += sqrt(
POW2(m_cells->cellMetrics[0][cellId]) +
POW2(m_cells->cellMetrics[1][cellId]));
2769 MPI_Allreduce(&surface, &m_channelSurfaceIn, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelIn, AT_,
"surface",
2770 "m_channelSurfaceIn");
2771 cout <<
"ChannelInSurface: " << m_channelSurfaceIn << endl;
2773 MPI_Allreduce(&surface, &m_channelSurfaceOut, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelOut, AT_,
2774 "surface",
"m_channelSurfaceOut");
2775 cout <<
"ChannelOutSurface: " << m_channelSurfaceOut << endl;
2781 mTerm(1, AT_,
"surface calculation for j faces(channel not implemented)");
2785 mTerm(1, AT_,
"surface calculation for given faces(channel not implemented)");
2797template <MBool isRans>
2799 MInt* start = m_physicalBCMap[bcId]->start1;
2800 MInt* end = m_physicalBCMap[bcId]->end1;
2802 for(
MInt var = 0; var < PV->noVariables; var++) {
2803 for(
MInt i = start[0]; i < end[0]; i++) {
2804 for(
MInt j = start[1]; j < end[1]; j++) {
2805 MInt cellId = cellIndex(i, j);
2806 MInt cellIdAdj = cellIndex(m_noGhostLayers, j);
2807 m_cells->pvariables[var][cellId] = m_cells->pvariables[var][cellIdAdj];
2821template <MBool isRans>
2823 MInt* start = m_physicalBCMap[bcId]->start1;
2824 MInt* end = m_physicalBCMap[bcId]->end1;
2826 m_solver->m_bc2600 =
true;
2828 switch(m_physicalBCMap[bcId]->face) {
2830 if(m_solver->m_bc2600InitialStartup) {
2832 for(
MInt i = start[0]; i < end[0]; i++) {
2833 for(
MInt j = start[1]; j < end[1]; j++) {
2834 const MInt cellId = cellIndex(i, j);
2835 const MInt cellIdAdj = cellIndex(m_noGhostLayers, j);
2836 for(
MInt var = 0; var < PV->noVariables; var++) {
2837 m_cells->pvariables[var][cellId] = m_cells->pvariables[var][cellIdAdj];
2844 for(
MInt i = start[0]; i < end[0]; i++) {
2845 for(
MInt j = m_noGhostLayers; j < end[1] - m_noGhostLayers; j++) {
2846 const MInt cellId = cellIndex(i, j);
2847 const MInt cellIdBc = i + (j - m_noGhostLayers) * m_noGhostLayers;
2848 for(
MInt var = 0; var < PV->noVariables; var++) {
2849 m_solver->m_bc2600Variables[var][cellIdBc] = m_cells->pvariables[var][cellId];
2857 mTerm(1, AT_,
"Face not implemented");
2863template <MBool isRans>
2865 MInt* start = m_physicalBCMap[bcId]->start1;
2866 MInt* end = m_physicalBCMap[bcId]->end1;
2867 for(
MInt var = 0; var < PV->noVariables; var++) {
2868 for(
MInt i = start[0]; i < end[0]; i++) {
2869 for(
MInt j = start[1]; j < end[1]; j++) {
2870 MInt cellId = cellIndex(i, j);
2871 MInt cellIdAdj = cellIndex(m_noGhostLayers, j);
2872 m_cells->pvariables[var][cellId] = m_cells->pvariables[var][cellIdAdj];
2876 m_bc2021Gradient = 1.0;
2877 m_bc2021Gradient = Context::getSolverProperty<MFloat>(
"bc2021Gradient", m_solverId, AT_, &m_bc2021Gradient);
2880template <MBool isRans>
2886template <MBool isRans>
2887template <RansMethod ransMethod>
2891 const MInt IJ[nDim] = {1, m_nCells[1]};
2892 MInt* start = m_physicalBCMap[bcId]->start1;
2893 MInt* end = m_physicalBCMap[bcId]->end1;
2899 const MInt face = m_physicalBCMap[bcId]->face;
2900 const MInt normalDir = face / 2;
2901 const MInt firstTangentialDir = (normalDir + 1) % nDim;
2902 const MInt normalDirStart = start[normalDir];
2903 const MInt firstTangentialStart = start[firstTangentialDir];
2904 const MInt firstTangentialEnd = end[firstTangentialDir];
2905 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
2907 const MInt n = (face % 2) * 2 - 1;
2908 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
2909 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
2910 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
2911 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
2913 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
2914 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
2915 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
2916 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
2917 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
2919 const MFloat p1 = m_cells->pvariables[PV->P][cellIdA1];
2920 const MFloat rho1 = m_cells->pvariables[PV->RHO][cellIdA1];
2921 const MFloat u1 = m_cells->pvariables[PV->U][cellIdA1];
2922 const MFloat v1 = m_cells->pvariables[PV->V][cellIdA1];
2924 const MFloat p2 = m_cells->pvariables[PV->P][cellIdA2];
2925 const MFloat rho2 = m_cells->pvariables[PV->RHO][cellIdA2];
2926 const MFloat u2 = m_cells->pvariables[PV->U][cellIdA2];
2927 const MFloat v2 = m_cells->pvariables[PV->V][cellIdA2];
2929 m_cells->pvariables[PV->RHO][cellIdG1] = rho1;
2930 m_cells->pvariables[PV->U][cellIdG1] = -u1;
2931 m_cells->pvariables[PV->V][cellIdG1] = -v1;
2932 m_cells->pvariables[PV->P][cellIdG1] = p1;
2934 m_cells->pvariables[PV->RHO][cellIdG2] = rho2;
2935 m_cells->pvariables[PV->U][cellIdG2] = -u2;
2936 m_cells->pvariables[PV->V][cellIdG2] = -v2;
2937 m_cells->pvariables[PV->P][cellIdG2] = p2;
2941 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
2943 const MFloat ransVar1 = m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdA1];
2944 const MFloat ransVar2 = m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdA2];
2946 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdG1] = -ransVar1;
2947 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdG2] = -ransVar2;
2953template <MBool isRans>
2956 const RansMethod ransMethod = m_solver->m_ransMethod;
2958 bc1000_<RANS_SA>(bcId);
2960 bc1000_<RANS_KEPSILON>(bcId);
2963 bc1000_<NORANS>(bcId);
2968template <MBool isRans>
2972 MInt* start = m_physicalBCMap[bcId]->start1;
2973 MInt* end = m_physicalBCMap[bcId]->end1;
2974 switch(m_physicalBCMap[bcId]->face) {
2978 if(m_physicalBCMap[bcId]->face == 2) {
2979 cellShift = 2 * m_noGhostLayers - 1;
2980 }
else if(m_physicalBCMap[bcId]->face == 3) {
2981 cellShift = 2 * (m_nCells[0] - 1) - 2 * m_noGhostLayers + 1;
2984 for(
MInt j = start[1]; j < end[1]; j++) {
2985 for(
MInt i = start[0]; i < end[0]; i++) {
2986 MInt cellIdA1 = -1, pIJ = -1;
2987 if(m_physicalBCMap[bcId]->face == 2) {
2988 pIJ = getPointIdFromCell(i, m_noGhostLayers);
2989 cellIdA1 = cellIndex(i, m_noGhostLayers);
2991 pIJ = getPointIdFromCell(i, m_solver->m_nPoints[0] - 3);
2992 cellIdA1 = cellIndex(i, m_nCells[0] - 3);
2994 const MFloat x1 = m_grid->m_coordinates[0][pIJ];
2995 const MFloat y1 = m_grid->m_coordinates[1][pIJ];
2996 const MFloat x2 = m_grid->m_coordinates[0][pIJ + 1];
2997 const MFloat y2 = m_grid->m_coordinates[1][pIJ + 1];
2999 const MFloat dydx = (y2 - y1) / (x2 - x1);
3000 const MFloat alpha = -atan(dydx);
3002 const MInt cellId = cellIndex(i, j);
3003 const MInt cellIdadj = cellIndex(i, cellShift - j);
3006 m_cells->pvariables[PV->RHO][cellIdA1];
3007 const MFloat u = m_cells->pvariables[PV->U][cellIdadj];
3008 const MFloat v = m_cells->pvariables[PV->V][cellIdadj];
3010 const MFloat uPrime = u * cos(alpha) - v * sin(alpha);
3011 const MFloat vPrime = -(u * sin(alpha) + v * cos(alpha));
3013 const MFloat uGC = uPrime * cos(-alpha) - vPrime * sin(-alpha);
3014 const MFloat vGC = uPrime * sin(-alpha) + vPrime * cos(-alpha);
3016 m_cells->pvariables[PV->RHO][cellId] = rho;
3017 m_cells->pvariables[PV->U][cellId] = uGC;
3018 m_cells->pvariables[PV->V][cellId] = vGC;
3021 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdA1];
3024 m_cells->pvariables[PV->RANS_VAR[0]][cellId] = -m_cells->pvariables[PV->RANS_VAR[0]][cellIdadj];
3031 mTerm(1, AT_,
"Face direction not implemented)");
3037template <MBool isRans>
3039 const MInt IJ[nDim] = {1, m_nCells[1]};
3040 MInt* start = m_physicalBCMap[bcId]->start1;
3041 MInt* end = m_physicalBCMap[bcId]->end1;
3043 MFloat temp = m_isothermalWallTemperature * PV->TInfinity;
3044 const MFloat gamma = m_solver->m_gamma;
3050 const MInt face = m_physicalBCMap[bcId]->face;
3051 const MInt normalDir = face / 2;
3052 const MInt firstTangentialDir = (normalDir + 1) % nDim;
3053 const MInt normalDirStart = start[normalDir];
3054 const MInt firstTangentialStart = start[firstTangentialDir];
3055 const MInt firstTangentialEnd = end[firstTangentialDir];
3056 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
3058 const MInt n = (face % 2) * 2 - 1;
3059 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
3060 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
3061 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
3062 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
3064 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
3065 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
3066 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
3067 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
3068 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
3070 const MFloat p1 = m_cells->pvariables[PV->P][cellIdA1];
3071 const MFloat rho1 = m_cells->pvariables[PV->RHO][cellIdA1];
3072 const MFloat u1 = m_cells->pvariables[PV->U][cellIdA1];
3073 const MFloat v1 = m_cells->pvariables[PV->V][cellIdA1];
3075 const MFloat p2 = m_cells->pvariables[PV->P][cellIdA2];
3076 const MFloat rho2 = m_cells->pvariables[PV->RHO][cellIdA2];
3077 const MFloat u2 = m_cells->pvariables[PV->U][cellIdA2];
3078 const MFloat v2 = m_cells->pvariables[PV->V][cellIdA2];
3080 const MFloat rhoWall = p1 * gamma / temp;
3081 const MFloat rhoG1 = F2 * rhoWall - rho1;
3082 const MFloat rhoG2 = F2 * rhoWall - rho2;
3084 m_cells->pvariables[PV->RHO][cellIdG1] = rhoG1;
3085 m_cells->pvariables[PV->U][cellIdG1] = -u1;
3086 m_cells->pvariables[PV->V][cellIdG1] = -v1;
3087 m_cells->pvariables[PV->P][cellIdG1] = p1;
3089 m_cells->pvariables[PV->RHO][cellIdG2] = rhoG2;
3090 m_cells->pvariables[PV->U][cellIdG2] = -u2;
3091 m_cells->pvariables[PV->V][cellIdG2] = -v2;
3092 m_cells->pvariables[PV->P][cellIdG2] = p2;
3097 const MFloat ransVar1 = m_cells->pvariables[PV->RANS_VAR[0]][cellIdA1];
3098 const MFloat ransVar2 = m_cells->pvariables[PV->RANS_VAR[0]][cellIdA2];
3100 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG1] = -ransVar1;
3101 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG2] = -ransVar2;
3107template <MBool isRans>
3111 MInt* start = m_physicalBCMap[bcId]->start1;
3112 MInt* end = m_physicalBCMap[bcId]->end1;
3114 const MInt IJ[nDim] = {1, m_nCells[1]};
3115 const MInt IJP[nDim] = {1, m_nPoints[1]};
3117 const MInt pp[2][4] = {{0, 0, 0, 1}, {0, 0, 1, 0}};
3123 const MInt face = m_physicalBCMap[bcId]->face;
3124 const MInt normalDir = face / 2;
3125 const MInt firstTangentialDir = (normalDir + 1) % nDim;
3126 const MInt normalDirStart = start[normalDir];
3127 const MInt firstTangentialStart = start[firstTangentialDir];
3128 const MInt firstTangentialEnd = end[firstTangentialDir];
3129 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
3130 const MInt incp[nDim] = {IJP[normalDir], IJP[firstTangentialDir]};
3132 const MInt n = (face % 2) * 2 - 1;
3133 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
3134 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
3135 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
3136 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
3138 const MInt g1p = normalDirStart + 2 * ((
MInt)(0.5 - (0.5 * (
MFloat)n)));
3140 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
3141 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
3142 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
3143 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
3144 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
3146 const MInt ij = g1p * incp[0] + t1 * incp[1];
3148 const MInt pp1 = getPointIdFromPoint(ij, pp[normalDir][0], pp[normalDir][1]);
3149 const MInt pp2 = getPointIdFromPoint(ij, pp[normalDir][2], pp[normalDir][3]);
3152 MFloat gridVel[2] = {F0, F0};
3157 for(
MInt dim = 0; dim < nDim; dim++) {
3160 gridVel[dim] = F1B2 * (m_grid->m_velocity[dim][pp1] + m_grid->m_velocity[dim][pp2]);
3164 const MFloat p1 = m_cells->pvariables[PV->P][cellIdA1];
3165 const MFloat rho1 = m_cells->pvariables[PV->RHO][cellIdA1];
3166 const MFloat u1 = m_cells->pvariables[PV->U][cellIdA1];
3167 const MFloat v1 = m_cells->pvariables[PV->V][cellIdA1];
3169 const MFloat p2 = m_cells->pvariables[PV->P][cellIdA2];
3170 const MFloat rho2 = m_cells->pvariables[PV->RHO][cellIdA2];
3171 const MFloat u2 = m_cells->pvariables[PV->U][cellIdA2];
3172 const MFloat v2 = m_cells->pvariables[PV->V][cellIdA2];
3176 const MFloat rhoG1 = rho1;
3177 const MFloat rhoG2 = rho2;
3179 const MFloat uG1 = F2 * gridVel[0] - u1;
3180 const MFloat vG1 = F2 * gridVel[1] - v1;
3182 const MFloat uG2 = F2 * gridVel[0] - u2;
3183 const MFloat vG2 = F2 * gridVel[1] - v2;
3185 m_cells->pvariables[PV->RHO][cellIdG1] = rhoG1;
3186 m_cells->pvariables[PV->U][cellIdG1] = uG1;
3187 m_cells->pvariables[PV->V][cellIdG1] = vG1;
3188 m_cells->pvariables[PV->P][cellIdG1] = pG1;
3190 m_cells->pvariables[PV->RHO][cellIdG2] = rhoG2;
3191 m_cells->pvariables[PV->U][cellIdG2] = uG2;
3192 m_cells->pvariables[PV->V][cellIdG2] = vG2;
3193 m_cells->pvariables[PV->P][cellIdG2] = pG2;
3202template <MBool isRans>
3207 MInt* start = m_physicalBCMap[bcId]->start1;
3208 MInt* end = m_physicalBCMap[bcId]->end1;
3209 switch(m_physicalBCMap[bcId]->face) {
3212 MInt cellIdadj = -1;
3213 for(
MInt j = start[1]; j < end[1]; j++) {
3214 for(
MInt i = start[0]; i < end[0]; i++) {
3215 cellId = cellIndex(m_noGhostLayers - 1 - i, j);
3216 cellIdadj = cellIndex(m_noGhostLayers - i, j);
3218 m_cells->pvariables[PV->RHO][cellId] = CV->rhoInfinity;
3219 m_cells->pvariables[PV->U][cellId] = PV->UInfinity;
3220 m_cells->pvariables[PV->V][cellId] = PV->VInfinity;
3221 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdadj];
3224 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3225 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] = PV->ransInfinity[ransVarId];
3234 MInt cellIdadj = -1;
3235 for(
MInt j = start[1]; j < end[1]; j++) {
3236 for(
MInt i = start[0]; i < end[0]; i++) {
3237 cellId = cellIndex(i, m_noGhostLayers - j - 1);
3238 cellIdadj = cellIndex(i, m_noGhostLayers - j);
3240 m_cells->pvariables[PV->RHO][cellId] = CV->rhoInfinity;
3241 m_cells->pvariables[PV->U][cellId] = PV->UInfinity;
3242 m_cells->pvariables[PV->V][cellId] = PV->VInfinity;
3243 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdadj];
3246 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3247 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] = PV->ransInfinity[ransVarId];
3255 mTerm(1, AT_,
"Face direction not implemented)");
3270template <MBool isRans>
3274 const MInt IJ[nDim] = {1, m_nCells[1]};
3275 const MFloat gamma = m_solver->m_gamma;
3276 MInt* start = m_physicalBCMap[bcId]->start1;
3277 MInt* end = m_physicalBCMap[bcId]->end1;
3283 const MInt face = m_physicalBCMap[bcId]->face;
3284 const MInt normalDir = face / 2;
3285 const MInt firstTangentialDir = (normalDir + 1) % nDim;
3286 const MInt normalDirStart = start[normalDir];
3287 const MInt firstTangentialStart = start[firstTangentialDir];
3288 const MInt firstTangentialEnd = end[firstTangentialDir];
3289 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
3291 const MInt n = (face % 2) * 2 - 1;
3292 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
3293 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
3294 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
3295 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
3297 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
3298 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
3299 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
3300 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
3301 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
3302 const MFloat dxidx = m_cells->surfaceMetrics[normalDir * nDim + 0][cellIdA1];
3303 const MFloat dxidy = m_cells->surfaceMetrics[normalDir * nDim + 1][cellIdA1];
3306 const MFloat gradxi = n * F1 / sqrt(dxidx * dxidx + dxidy * dxidy);
3307 const MFloat dxHelp = dxidx * gradxi;
3308 const MFloat dyHelp = dxidy * gradxi;
3310 const MFloat cBC = sqrt(gamma * m_cells->pvariables[PV->P][cellIdG1] / m_cells->pvariables[PV->RHO][cellIdG1]);
3311 const MFloat rhoBC = m_cells->pvariables[PV->RHO][cellIdG1];
3312 const MFloat rhoInner = m_cells->pvariables[PV->RHO][cellIdA1];
3313 const MFloat uInner = m_cells->pvariables[PV->U][cellIdA1];
3314 const MFloat vInner = m_cells->pvariables[PV->V][cellIdA1];
3315 const MFloat pInner = m_cells->pvariables[PV->P][cellIdA1];
3316 const MFloat maContravariant = (dxidx * uInner + dxidy * vInner - m_cells->dxt[normalDir][cellIdA1]) * gradxi;
3317 if(maContravariant < F0) {
3320 * (pInner + PV->PInfinity
3321 + rhoBC * cBC * (dxHelp * (uInner - PV->UInfinity) + dyHelp * (vInner - PV->VInfinity)));
3323 const MFloat rho = CV->rhoInfinity + (p - PV->PInfinity) /
POW2(cBC);
3324 const MFloat help = (p - PV->PInfinity) / (rhoBC * cBC);
3326 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3327 m_cells->pvariables[PV->U][cellIdG1] = (PV->UInfinity + help * dxHelp);
3328 m_cells->pvariables[PV->V][cellIdG1] = (PV->VInfinity + help * dyHelp);
3329 m_cells->pvariables[PV->P][cellIdG1] = p;
3331 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3332 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdG1] = PV->ransInfinity[ransVarId];
3337 const MFloat p = PV->PInfinity;
3338 const MFloat rho = rhoInner + (p - pInner) /
POW2(cBC);
3339 const MFloat help = (p - pInner) / (rhoBC * cBC);
3341 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3342 m_cells->pvariables[PV->U][cellIdG1] = (uInner - help * dxHelp);
3343 m_cells->pvariables[PV->V][cellIdG1] = (vInner - help * dyHelp);
3344 m_cells->pvariables[PV->P][cellIdG1] = p;
3346 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3347 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdG1] =
3348 (F2 * m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdA1]
3349 - m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdA2]);
3355 for(
MInt var = 0; var < PV->noVariables; var++) {
3356 m_cells->pvariables[var][cellIdG2] = F2 * m_cells->pvariables[var][cellIdG1] - m_cells->pvariables[var][cellIdA1];
3366template <MBool isRans>
3368 MInt* start = m_physicalBCMap[bcId]->start1;
3369 MInt* end = m_physicalBCMap[bcId]->end1;
3370 switch(m_physicalBCMap[bcId]->face) {
3372 for(
MInt j = start[1]; j < end[1]; j++) {
3373 for(
MInt i = start[0]; i < end[0]; i++) {
3374 MInt cellId = cellIndex(i, j);
3375 m_cells->pvariables[PV->RHO][cellId] = CV->rhoInfinity;
3376 m_cells->pvariables[PV->U][cellId] = PV->UInfinity;
3377 m_cells->pvariables[PV->V][cellId] = PV->VInfinity;
3378 m_cells->pvariables[PV->P][cellId] = PV->PInfinity;
3380 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3381 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] = PV->ransInfinity[ransVarId];
3402template <MBool isRans>
3404 const MInt IJ[nDim] = {1, m_nCells[1]};
3405 MInt* start = m_physicalBCMap[bcId]->start1;
3406 MInt* end = m_physicalBCMap[bcId]->end1;
3412 const MInt face = m_physicalBCMap[bcId]->face;
3413 const MInt normalDir = face / 2;
3414 const MInt firstTangentialDir = (normalDir + 1) % nDim;
3415 const MInt normalDirStart = start[normalDir];
3416 const MInt firstTangentialStart = start[firstTangentialDir];
3417 const MInt firstTangentialEnd = end[firstTangentialDir];
3418 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
3420 const MInt n = (face % 2) * 2 - 1;
3421 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
3422 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
3423 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
3424 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
3426 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
3427 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
3428 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
3429 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
3430 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
3432 const MFloat dxidx = m_cells->surfaceMetrics[normalDir * nDim + 0][cellIdA1];
3433 const MFloat dxidy = m_cells->surfaceMetrics[normalDir * nDim + 1][cellIdA1];
3436 const MFloat gradxi = n * F1 / sqrt(dxidx * dxidx + dxidy * dxidy);
3438 const MFloat rhoInner = m_cells->pvariables[PV->RHO][cellIdA1];
3439 const MFloat uInner = m_cells->pvariables[PV->U][cellIdA1];
3440 const MFloat vInner = m_cells->pvariables[PV->V][cellIdA1];
3441 const MFloat pInner = m_cells->pvariables[PV->P][cellIdA1];
3443 const MFloat maContravariant = (dxidx * uInner + dxidy * vInner) * gradxi;
3446 if(maContravariant < F0) {
3449 const MFloat rho = CV->rhoInfinity;
3451 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3452 m_cells->pvariables[PV->U][cellIdG1] = PV->UInfinity;
3453 m_cells->pvariables[PV->V][cellIdG1] = PV->VInfinity;
3454 m_cells->pvariables[PV->P][cellIdG1] = p;
3457 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG1] = CV->ransInfinity[0] / CV->rhoInfinity;
3461 const MFloat p = PV->PInfinity;
3462 const MFloat rho = rhoInner;
3464 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3465 m_cells->pvariables[PV->U][cellIdG1] = uInner;
3466 m_cells->pvariables[PV->V][cellIdG1] = vInner;
3467 m_cells->pvariables[PV->P][cellIdG1] = p;
3469 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG1] =
3470 (F2 * m_cells->pvariables[PV->RANS_VAR[0]][cellIdA1] - m_cells->pvariables[PV->RANS_VAR[0]][cellIdA2]);
3475 for(
MInt var = 0; var < PV->noVariables; var++) {
3476 m_cells->pvariables[var][cellIdG2] = F2 * m_cells->pvariables[var][cellIdG1] - m_cells->pvariables[var][cellIdA1];
3486template <MBool isRans>
3488 MInt* start = m_physicalBCMap[bcId]->start1;
3489 MInt* end = m_physicalBCMap[bcId]->end1;
3490 switch(m_physicalBCMap[bcId]->face) {
3492 for(
MInt j = start[1]; j < end[1]; j++) {
3493 for(
MInt i = start[0]; i < end[0]; i++) {
3494 MInt cellId = cellIndex(i, j);
3495 MInt cellIdadj = cellIndex(i - 1, j);
3497 for(
MInt var = 0; var < PV->noVariables; var++) {
3498 m_cells->pvariables[var][cellId] = m_cells->pvariables[var][cellIdadj];
3505 for(
MInt j = start[1]; j < end[1]; j++) {
3506 for(
MInt i = start[0]; i < end[0]; i++) {
3507 MInt cellId = cellIndex(i, j);
3508 MInt cellIdadj = cellIndex(i, j - 1);
3509 for(
MInt var = 0; var < PV->noVariables; var++) {
3510 m_cells->pvariables[var][cellId] = m_cells->pvariables[var][cellIdadj];
3517 mTerm(1, AT_,
"Face direction not implemented");
3527template <MBool isRans>
3529 const MInt IJ[nDim] = {1, m_nCells[1]};
3530 const MFloat gamma = m_solver->m_gamma;
3531 MInt* start = m_physicalBCMap[bcId]->start1;
3532 MInt* end = m_physicalBCMap[bcId]->end1;
3538 const MInt face = m_physicalBCMap[bcId]->face;
3539 const MInt normalDir = face / 2;
3540 const MInt firstTangentialDir = (normalDir + 1) % nDim;
3541 const MInt normalDirStart = start[normalDir];
3542 const MInt firstTangentialStart = start[firstTangentialDir];
3543 const MInt firstTangentialEnd = end[firstTangentialDir];
3544 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
3546 const MInt n = (face % 2) * 2 - 1;
3547 const MInt g1 = normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n));
3548 const MInt g2 = normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n));
3549 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
3550 const MInt a2 = normalDirStart + (
MInt)(0.5 - (2.5 * (
MFloat)n));
3552 for(
MInt t1 = firstTangentialStart; t1 < firstTangentialEnd; t1++) {
3553 const MInt cellIdG1 = g1 * inc[0] + t1 * inc[1];
3554 const MInt cellIdG2 = g2 * inc[0] + t1 * inc[1];
3555 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
3556 const MInt cellIdA2 = a2 * inc[0] + t1 * inc[1];
3557 const MFloat dxidx = m_cells->surfaceMetrics[normalDir * nDim + 0][cellIdA1];
3558 const MFloat dxidy = m_cells->surfaceMetrics[normalDir * nDim + 1][cellIdA1];
3561 const MFloat gradxi = n * F1 / sqrt(dxidx * dxidx + dxidy * dxidy);
3562 const MFloat dxHelp = dxidx * gradxi;
3563 const MFloat dyHelp = dxidy * gradxi;
3565 const MFloat cBC = sqrt(gamma * m_cells->pvariables[PV->P][cellIdG1] / m_cells->pvariables[PV->RHO][cellIdG1]);
3566 const MFloat rhoBC = m_cells->pvariables[PV->RHO][cellIdG1];
3567 const MFloat rhoInner = m_cells->pvariables[PV->RHO][cellIdA1];
3568 const MFloat uInner = m_cells->pvariables[PV->U][cellIdA1];
3569 const MFloat vInner = m_cells->pvariables[PV->V][cellIdA1];
3570 const MFloat pInner = m_cells->pvariables[PV->P][cellIdA1];
3572 const MFloat maContravariant = (dxidx * uInner + dxidy * vInner - m_cells->dxt[normalDir][cellIdA1]) * gradxi;
3574 if(maContravariant < F0) {
3577 F1B2 * (pInner + PV->PInfinity + rhoBC * cBC * (dxHelp * (uInner - 0.0) + dyHelp * (vInner - 0.0)));
3579 const MFloat rho = CV->rhoInfinity + (p - PV->PInfinity) /
POW2(cBC);
3580 const MFloat help = (p - PV->PInfinity) / (rhoBC * cBC);
3582 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3583 m_cells->pvariables[PV->U][cellIdG1] = (0.0 + help * dxHelp);
3584 m_cells->pvariables[PV->V][cellIdG1] = (0.0 + help * dyHelp);
3585 m_cells->pvariables[PV->P][cellIdG1] = p;
3587 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG1] = PV->ransInfinity[0];
3591 const MFloat p = PV->PInfinity;
3592 const MFloat rho = rhoInner + (p - pInner) /
POW2(cBC);
3593 const MFloat help = (p - pInner) / (rhoBC * cBC);
3595 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3596 m_cells->pvariables[PV->U][cellIdG1] = (uInner - help * dxHelp);
3597 m_cells->pvariables[PV->V][cellIdG1] = (vInner - help * dyHelp);
3598 m_cells->pvariables[PV->P][cellIdG1] = p;
3600 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG1] =
3601 (F2 * m_cells->pvariables[PV->RANS_VAR[0]][cellIdA1] - m_cells->pvariables[PV->RANS_VAR[0]][cellIdA2]);
3606 for(
MInt var = 0; var < PV->noVariables; var++) {
3607 m_cells->pvariables[var][cellIdG2] = F2 * m_cells->pvariables[var][cellIdG1] - m_cells->pvariables[var][cellIdA1];
3618template <MBool isRans>
3620 MInt* start = m_physicalBCMap[bcId]->start1;
3621 MInt* end = m_physicalBCMap[bcId]->end1;
3623 switch(m_physicalBCMap[bcId]->face) {
3625 for(
MInt j = start[1]; j < end[1]; j++) {
3626 MInt cellId = cellIndex(start[0], j);
3627 MInt cellIdadj = cellIndex(start[0] - 1, j);
3629 m_cells->pvariables[PV->RHO][cellId] = m_cells->pvariables[PV->RHO][cellIdadj];
3630 m_cells->pvariables[PV->U][cellId] = m_cells->pvariables[PV->U][cellIdadj];
3631 m_cells->pvariables[PV->V][cellId] = m_cells->pvariables[PV->V][cellIdadj];
3632 m_cells->pvariables[PV->P][cellId] = PV->PInfinity;
3635 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3636 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] =
3637 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdadj];
3641 for(
MInt var = 0; var < PV->noVariables; var++) {
3642 MInt cellIdP1 = cellIndex(start[0] + 1, j);
3643 m_cells->pvariables[var][cellIdP1] =
3644 2.0 * m_cells->pvariables[var][cellId] - m_cells->pvariables[var][cellIdadj];
3650 for(
MInt i = start[0]; i < end[0]; i++) {
3651 MInt cellId = cellIndex(i, start[1]);
3652 MInt cellIdadj = cellIndex(i, start[1] - 1);
3654 m_cells->pvariables[PV->RHO][cellId] = m_cells->pvariables[PV->RHO][cellIdadj];
3655 m_cells->pvariables[PV->U][cellId] = m_cells->pvariables[PV->U][cellIdadj];
3656 m_cells->pvariables[PV->V][cellId] = m_cells->pvariables[PV->V][cellIdadj];
3657 m_cells->pvariables[PV->P][cellId] = PV->PInfinity;
3660 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3661 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] =
3662 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdadj];
3666 for(
MInt var = 0; var < PV->noVariables; var++) {
3667 MInt cellIdP1 = cellIndex(i, start[1] + 1);
3668 m_cells->pvariables[var][cellIdP1] =
3669 2.0 * m_cells->pvariables[var][cellId] - m_cells->pvariables[var][cellIdadj];
3677 mTerm(1, AT_,
"Face direction not implemented");
3685template <MBool isRans>
3688 MInt* start = m_physicalBCMap[bcId]->start1;
3689 MInt* end = m_physicalBCMap[bcId]->end1;
3691 switch(m_physicalBCMap[bcId]->face) {
3693 mTerm(1,
"Not implemted yet!");
3697 mTerm(1,
"Not implemted yet!");
3702 MInt cellIdadj = -1;
3703 const MInt cellShift = 2 * m_noGhostLayers - 1;
3705 for(
MInt j = start[1]; j < end[1]; j++) {
3706 for(
MInt i = start[0]; i < end[0]; i++) {
3707 cellId = cellIndex(i, j);
3708 cellIdadj = cellIndex(i, cellShift - j);
3710 m_cells->pvariables[PV->RHO][cellId] = m_cells->pvariables[PV->RHO][cellIdadj];
3711 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdadj];
3712 m_cells->pvariables[PV->U][cellId] = m_cells->pvariables[PV->U][cellIdadj];
3713 m_cells->pvariables[PV->V][cellId] = -m_cells->pvariables[PV->V][cellIdadj];
3715 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3716 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] =
3717 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdadj];
3727 MInt cellIdadj = -1;
3728 const MInt cellShift = 2 * (m_nCells[0] - 1) - 2 * m_noGhostLayers + 1;
3730 for(
MInt j = start[1]; j < end[1]; j++) {
3731 for(
MInt i = start[0]; i < end[0]; i++) {
3733 cellId = cellIndex(i, j);
3734 cellIdadj = cellIndex(i, cellShift - j);
3736 m_cells->pvariables[PV->RHO][cellId] = m_cells->pvariables[PV->RHO][cellIdadj];
3737 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdadj];
3738 m_cells->pvariables[PV->U][cellId] = m_cells->pvariables[PV->U][cellIdadj];
3739 m_cells->pvariables[PV->V][cellId] = -m_cells->pvariables[PV->V][cellIdadj];
3741 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3742 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellId] =
3743 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdadj];
3752 mTerm(1, AT_,
"Face direction not implemented)");
3758template <MBool isRans>
3762 MInt* start = m_physicalBCMap[bcId]->start1;
3763 MInt* end = m_physicalBCMap[bcId]->end1;
3764 switch(m_physicalBCMap[bcId]->face) {
3766 for(
MInt j = start[1]; j < end[1]; j++) {
3767 const MInt cellIdG1 = cellIndex(1, j);
3768 const MInt cellIdG2 = cellIndex(0, j);
3769 const MInt cellIdA1 = cellIndex(2, j);
3772 const MFloat dxidx = m_cells->surfaceMetrics[0][cellIdA1];
3773 const MFloat dxidy = m_cells->surfaceMetrics[1][cellIdA1];
3777 const MFloat gradxi = -1 * F1 / sqrt(dxidx * dxidx + dxidy * dxidy);
3779 const MFloat dxHelp = dxidx * gradxi;
3780 const MFloat dyHelp = dxidy * gradxi;
3782 const MFloat cBC = sqrt(m_solver->m_gamma * pressure(cellIdG1) / m_cells->pvariables[PV->RHO][cellIdG1]);
3783 const MFloat rhoBC = m_cells->pvariables[PV->RHO][cellIdG1];
3785 const MFloat uInner = m_cells->pvariables[PV->U][cellIdA1];
3786 const MFloat vInner = m_cells->pvariables[PV->V][cellIdA1];
3787 const MFloat pInner = pressure(cellIdA1);
3789 const MFloat uInflow = PV->UInfinity * (m_cells->coordinates[1][cellIdG1] * m_bc2021Gradient);
3790 const MFloat vInflow = 0.0;
3794 F1B2 * (pInner + PV->PInfinity + rhoBC * cBC * (dxHelp * (uInner - uInflow) + dyHelp * (vInner - vInflow)));
3796 const MFloat rho = CV->rhoInfinity + (p - PV->PInfinity) /
POW2(cBC);
3797 const MFloat help = (p - PV->PInfinity) / (rhoBC * cBC);
3799 m_cells->pvariables[PV->RHO][cellIdG1] = rho;
3800 m_cells->pvariables[PV->U][cellIdG1] = uInflow + help * dxHelp;
3801 m_cells->pvariables[PV->V][cellIdG1] = vInflow + help * dyHelp;
3802 m_cells->pvariables[PV->P][cellIdG1] = p;
3805 for(
MInt ransVarId = 0; ransVarId < m_solver->m_noRansEquations; ++ransVarId) {
3806 m_cells->pvariables[PV->RANS_VAR[ransVarId]][cellIdG1] = PV->ransInfinity[ransVarId];
3811 for(
MInt var = 0; var < PV->noVariables; var++) {
3812 m_cells->pvariables[var][cellIdG2] =
3813 F2 * m_cells->pvariables[var][cellIdG1] - m_cells->pvariables[var][cellIdA1];
3821 mTerm(1, AT_,
"Face direction not implemented)");
3826template <MBool isRans>
3830 const MFloat gamma = m_solver->m_gamma;
3831 const MFloat gammaMinusOne = m_solver->m_gamma - F1;
3832 const MFloat fgamma = F1 / gamma;
3833 MInt* start = m_physicalBCMap[bcId]->start1;
3834 MInt* end = m_physicalBCMap[bcId]->end1;
3835 switch(m_physicalBCMap[bcId]->face) {
3839 for(
MInt j = start[1]; j < end[1]; j++) {
3840 const MInt cellId = cellIndex(m_noGhostLayers, j);
3841 const MInt pointId = getPointIdFromCell(m_noGhostLayers, j);
3842 const MInt pointIdP1 = getPointIdFromPoint(pointId, 0, 1);
3844 const MFloat dx = m_grid->m_coordinates[0][pointIdP1] - m_grid->m_coordinates[0][pointId];
3845 const MFloat dy = m_grid->m_coordinates[1][pointIdP1] - m_grid->m_coordinates[1][pointId];
3846 const MFloat rhou = m_cells->pvariables[PV->RHO][cellId] * m_cells->pvariables[PV->U][cellId];
3847 const MFloat rhov = m_cells->pvariables[PV->RHO][cellId] * m_cells->pvariables[PV->V][cellId];
3848 mflux += dx * rhou + dy * rhov;
3849 surface += sqrt(
POW2(dx) +
POW2(dy));
3853 MInt cellIdII1 = cellIndex(m_noGhostLayers, end[1] - m_noGhostLayers);
3855 const MFloat rhouAVG = mflux / surface;
3857 MFloat pressure = min(F1, max(F0, m_cells->pvariables[PV->P][cellIdII1] * gamma));
3861 for(
MInt i = 0; i < 20; i++) {
3862 pressure = pow((F1 - pow((rhouAVG / (sqrt(F2 * gammaMinusOne) * pow(pressure, fgamma))), F2)),
3863 (gammaMinusOne * fgamma));
3872 mTerm(1, AT_,
"Face direction not implemented)");
3878template <MBool isRans>
3882 MInt* start = m_physicalBCMap[bcId]->start1;
3883 MInt* end = m_physicalBCMap[bcId]->end1;
3890 MInt Id = m_channelSurfaceIndexMap[bcId];
3891 MInt* startface = &m_solver->m_windowInfo->channelSurfaceIndices[Id]->start1[0];
3892 MInt* endface = &m_solver->m_windowInfo->channelSurfaceIndices[Id]->end1[0];
3894 MFloat globalTin[2] = {F0, F0};
3895 MFloat globalTout[2] = {F0, F0};
3896 MFloat globalPin[2] = {F0, F0};
3897 MFloat globalPout[2] = {F0, F0};
3901 switch(m_physicalBCMap[bcId]->face) {
3906 MFloat localPin[2] = {F0, F0};
3907 MFloat localTin[2] = {F0, F0};
3908 MFloat localVel = F0, globalVel = F0;
3909 MFloat localMassFlux = F0, globalMassFlux = F0;
3911 for(
MInt j = startface[1]; j < endface[1]; j++) {
3912 MInt ii = end[0] - 1;
3913 MInt cellIdP1 = cellIndex(ii + 1, j);
3914 MInt cellIdP2 = cellIndex(ii + 2, j);
3916 surface = sqrt(
POW2(m_cells->surfaceMetrics[0][cellIdP1]) +
POW2(m_cells->surfaceMetrics[1][cellIdP1]));
3917 localPin[0] += surface * m_cells->pvariables[PV->P][cellIdP1];
3918 localPin[1] += surface * m_cells->pvariables[PV->P][cellIdP2];
3919 localTin[0] += surface * temperature(cellIdP1);
3920 localTin[1] += surface * temperature(cellIdP2);
3921 localVel += surface * (m_cells->pvariables[PV->U][cellIdP1]);
3922 localMassFlux += surface * (m_cells->pvariables[PV->U][cellIdP1] * m_cells->pvariables[PV->RHO][cellIdP1]);
3927 MPI_Allreduce(localPin, globalPin, 2, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelIn, AT_,
"localPin",
3929 MPI_Allreduce(localTin, globalTin, 2, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelIn, AT_,
"localTin",
3931 MPI_Allreduce(&localMassFlux, &globalMassFlux, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelIn, AT_,
3932 "localMassFlux",
"globalMassFlux");
3933 MPI_Allreduce(&localVel, &globalVel, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelIn, AT_,
"localVel",
3937 globalPin[0] /= m_channelSurfaceIn;
3938 globalTin[0] /= m_channelSurfaceIn;
3939 globalPin[1] /= m_channelSurfaceIn;
3940 globalTin[1] /= m_channelSurfaceIn;
3941 globalMassFlux /= m_channelSurfaceIn;
3942 globalVel /= m_channelSurfaceIn;
3943 MFloat currentRe = m_solver->m_Re / PV->UInfinity * globalVel;
3948 MPI_Bcast(globalTin, 2, MPI_DOUBLE, m_solver->m_channelRoots[2], m_solver->m_commChannelWorld, AT_,
"globalTin");
3949 MPI_Bcast(globalPin, 2, MPI_DOUBLE, m_solver->m_channelRoots[2], m_solver->m_commChannelWorld, AT_,
"globalPin");
3950 MPI_Bcast(globalTout, 2, MPI_DOUBLE, m_solver->m_channelRoots[3], m_solver->m_commChannelWorld, AT_,
3952 MPI_Bcast(globalPout, 2, MPI_DOUBLE, m_solver->m_channelRoots[3], m_solver->m_commChannelWorld, AT_,
3958 if(m_channelInflowRank == 0 &&
globalTimeStep % m_solver->m_residualInterval == 0 && m_solver->m_RKStep == 0) {
3962 f_channel = fopen(
"./massflow.dat",
"a+");
3964 fprintf(f_channel,
" %f", m_solver->m_physicalTime);
3965 fprintf(f_channel,
" %f", m_solver->m_time);
3966 fprintf(f_channel,
" %f", m_solver->m_timeStep);
3967 fprintf(f_channel,
" %f", currentRe);
3968 fprintf(f_channel,
" %f", globalMassFlux);
3969 fprintf(f_channel,
" %f", globalPin[0]);
3970 fprintf(f_channel,
" %f", globalPin[1]);
3971 fprintf(f_channel,
" %f", globalTin[0]);
3972 fprintf(f_channel,
" %f", globalTout[0]);
3973 fprintf(f_channel,
" %f", globalPout[0]);
3974 fprintf(f_channel,
" %f", globalPout[1]);
3975 fprintf(f_channel,
" %f", (globalTin[0] - globalTout[1]));
3976 fprintf(f_channel,
"\n");
3982 if(m_solver->m_channelFullyPeriodic) {
3983 m_solver->m_inflowVelAvg = globalVel;
3987 for(
MInt j = start[1]; j < end[1]; j++) {
3989 const MInt cellId = cellIndex(i, j);
3991 MFloat pressureFluctuation = m_cells->pvariables[PV->P][cellId] - globalPout[1];
3992 MFloat x = m_cells->coordinates[0][cellId];
3993 MFloat pressureInflowMean =
3994 m_solver->m_deltaP / m_solver->m_channelLength * (x - m_solver->m_channelInflowPlaneCoordinate)
3996 MFloat pressureNew = pressureInflowMean + pressureFluctuation;
3997 MFloat temperatureFlucOutflow = temperature(cellId) - globalTout[1];
3998 MFloat temperatureNew = PV->TInfinity + temperatureFlucOutflow;
3999 MFloat rhoNew = m_solver->m_gamma * pressureNew / temperatureNew;
4001 m_cells->pvariables[PV->RHO][cellId] = rhoNew;
4002 m_cells->pvariables[PV->P][cellId] = pressureNew;
4004 for(
MInt var = 0; var < PV->noVariables; var++) {
4005 m_cells->pvariables[var][cellIndex(start[0], j)] = 2.0 * m_cells->pvariables[var][cellIndex(start[0] + 1, j)]
4006 - m_cells->pvariables[var][cellIndex(start[0] + 2, j)];
4015 MFloat localPout[] = {F0, F0};
4016 MFloat localTout[] = {F0, F0};
4017 for(
MInt j = startface[1]; j < endface[1]; j++) {
4019 MInt cellIdM1 = cellIndex(ii - 1, j);
4020 MInt cellIdM2 = cellIndex(ii - 2, j);
4021 surface = sqrt(
POW2(m_cells->surfaceMetrics[0][cellIdM1]) +
POW2(m_cells->surfaceMetrics[1][cellIdM1]));
4022 localPout[0] += surface * m_cells->pvariables[PV->P][cellIdM2];
4023 localPout[1] += surface * m_cells->pvariables[PV->P][cellIdM1];
4024 localTout[0] += surface * temperature(cellIdM2);
4025 localTout[1] += surface * temperature(cellIdM1);
4030 MPI_Allreduce(localPout, globalPout, 2, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelOut, AT_,
"localPout",
4032 MPI_Allreduce(localTout, globalTout, 2, MPI_DOUBLE, MPI_SUM, m_solver->m_commChannelOut, AT_,
"localTout",
4036 globalPout[0] /= m_channelSurfaceOut;
4037 globalTout[0] /= m_channelSurfaceOut;
4038 globalPout[1] /= m_channelSurfaceOut;
4039 globalTout[1] /= m_channelSurfaceOut;
4043 MPI_Bcast(globalTin, 2, MPI_DOUBLE, m_solver->m_channelRoots[2], m_solver->m_commChannelWorld, AT_,
"globalTin");
4044 MPI_Bcast(globalPin, 2, MPI_DOUBLE, m_solver->m_channelRoots[2], m_solver->m_commChannelWorld, AT_,
"globalPin");
4045 MPI_Bcast(globalTout, 2, MPI_DOUBLE, m_solver->m_channelRoots[3], m_solver->m_commChannelWorld, AT_,
4047 MPI_Bcast(globalPout, 2, MPI_DOUBLE, m_solver->m_channelRoots[3], m_solver->m_commChannelWorld, AT_,
4053 if(m_solver->m_channelFullyPeriodic) {
4057 for(
MInt j = start[1]; j < end[1]; j++) {
4059 const MInt cellId = cellIndex(i, j);
4061 MFloat pressureFluctuation = m_cells->pvariables[PV->P][cellId] - globalPin[0];
4062 MFloat x = m_cells->coordinates[0][cellId];
4063 MFloat pressureOutflowMean =
4064 m_solver->m_deltaP / m_solver->m_channelLength * (x - m_solver->m_channelInflowPlaneCoordinate)
4066 MFloat pressureNew = pressureOutflowMean + pressureFluctuation;
4067 MFloat deltaT = (globalTin[0] - globalTout[1]);
4068 MFloat temperatureInflow = temperature(cellId);
4069 MFloat temperatureNew = temperatureInflow - deltaT;
4070 MFloat rhoNew = m_solver->m_gamma * pressureNew / temperatureNew;
4072 m_cells->pvariables[PV->RHO][cellId] = rhoNew;
4073 m_cells->pvariables[PV->P][cellId] = pressureNew;
4075 for(
MInt var = 0; var < PV->noVariables; var++) {
4076 m_cells->pvariables[var][cellIndex(start[0] + 1, j)] = 2.0 * m_cells->pvariables[var][cellIndex(start[0], j)]
4077 - m_cells->pvariables[var][cellIndex(start[0] - 1, j)];
4083 mTerm(1, AT_,
"Face not implemented");
4091template <MBool isRans>
4109 const MFloat gamma = m_solver->m_gamma;
4110 const MFloat gammaMinusOne = gamma - F1;
4112 const MFloat rescalEPS = pow(10, -16.0);
4113 const MFloat alpha = 4.0;
4115 const MFloat rc = pow(m_solver->m_Pr, F1B3);
4116 const MFloat ctema = F1B2 * gammaMinusOne *
POW2(m_solver->m_Ma) * rc;
4117 const MFloat maxIntegrationHeight = 2.0 * m_rescalingBLT;
4120 const MFloat b_vd = sqrt(ctema / (F1 + ctema));
4121 const MFloat uvd8 = PV->UInfinity * asin(b_vd) / b_vd;
4122 const MInt i = m_noGhostLayers - 1;
4130 thetaLocal.
fill(F0);
4133 thetaGlobal.
fill(F0);
4136 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; ++j) {
4137 const MInt cellId = cellIndex(i, j);
4138 const MInt pointIdM1 = getPointIdFromCell(i, j);
4139 const MInt pointIdP1 = getPointIdFromPoint(pointIdM1, 0, 1);
4141 if(m_grid->m_coordinates[1][pointIdM1] > maxIntegrationHeight) {
4145 const MFloat urat = m_cells->pvariables[PV->U][cellId] / PV->UInfinity;
4146 const MFloat momThick = m_cells->pvariables[PV->U][cellId] * m_cells->pvariables[PV->RHO][cellId] * fabs(F1 - urat)
4147 / (CV->rhoUInfinity);
4149 const MFloat ydist = m_grid->m_coordinates[1][pointIdP1] - m_grid->m_coordinates[1][pointIdM1];
4150 thetaLocal(0) += momThick * ydist;
4153 MPI_Allreduce(thetaLocal.
begin(), thetaGlobal.
begin(), 2, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4154 "thetaLocal.begin()",
"thetaGlobal.begin()");
4156 thetaGlobal(0) =
mMax(thetaGlobal(0), 0.0000001);
4157 thetaGlobal(1) =
mMax(thetaGlobal(1), 0.0000001);
4160 && m_solver->domainId() == m_solver->m_rescalingCommGrRootGlobal) {
4161 cout << m_solver->domainId() <<
" ThetaInflow " << thetaGlobal(0) <<
" ThetaRecyclingStation " << thetaGlobal(1)
4165 f_channel = fopen(
"./theta_inflow.dat",
"a+");
4167 fprintf(f_channel,
" %f", m_solver->m_physicalTime);
4168 fprintf(f_channel,
" %f", m_solver->m_time);
4169 fprintf(f_channel,
" %f", m_solver->m_timeStep);
4170 fprintf(f_channel,
" %f", thetaGlobal[0]);
4171 fprintf(f_channel,
" %f", thetaGlobal[1]);
4172 fprintf(f_channel,
"\n");
4179 const MInt noWallProperties = 3;
4180 MFloatScratchSpace wallPropertiesLocal(noWallProperties, AT_,
"wallPropertiesLocalInlet");
4182 wallPropertiesLocal.
fill(F0);
4183 wallProperties.
fill(F0);
4186 m_solver->m_rescalingCommGrComm, AT_,
"wallPropertiesLocal.begin()",
"wallProperties.begin()");
4195 MFloat utauRe = wallProperties(0);
4207 const MFloat facc = F1 / (F2 * (n - F1));
4209 gams = pow(thetaGlobal(1) / fabs(thetaGlobal(0)), facc);
4210 gams =
mMin(gams, 1.8);
4211 utauIn = utauRe * gams;
4216 for(
MInt j = 0; j < m_nCells[0]; ++j) {
4217 const MInt cellId = cellIndex(i, j);
4218 const MFloat rho = m_cells->pvariables[PV->RHO][cellId];
4219 const MFloat frho = F1 / rho;
4220 const MFloat p = m_cells->pvariables[PV->P][cellId];
4221 const MFloat temp = p * gamma * frho;
4222 const MFloat mu = SUTHERLANDLAW(temp);
4224 coordInInner(j) = utauIn * rho * m_cells->coordinates[1][cellId] / (mu * sqrt(m_solver->m_Re0));
4225 coordInOuter(j) = m_cells->coordinates[1][cellId] * rho / (m_rescalingBLT * CV->rhoInfinity);
4228 const MInt wallLocalOffset = m_solver->m_nOffsetCells[0];
4229 MFloat tempWallInletLocal = F0;
4230 MFloat tempWallInletGlobal = F0;
4232 if(wallLocalOffset == 0 && m_solver->m_nActiveCells[0] >= m_noGhostLayers) {
4233 const MInt cellId = cellIndex(i, m_noGhostLayers);
4234 tempWallInletLocal = temperature(cellId);
4237 MPI_Allreduce(&tempWallInletLocal, &tempWallInletGlobal, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4238 "tempWallInletLocal",
"tempWallInletGlobal");
4243 const MInt noVariables = PV->noVariables + 1;
4244 MInt totalCells = m_grid->getMyBlockNoCells(0) + 1;
4250 varSliceLocal.
fill(F0);
4253 m_solver->m_rescalingCommGrComm, AT_,
"varSliceLocal.begin()",
"varSlice.begin()");
4274 const MFloat ctem1 = (F1 + ctema) * (F1 -
POW2(gams));
4275 const MFloat ctem2 = F2 * ctema * gams * (F1 - gams);
4276 const MFloat ctem3 = (F1 - gams) * (F1 + gams + F2 * ctema * gams);
4279 MInt jEnd = m_nCells[0];
4281 if(m_solver->m_nOffsetCells[0] == 0) {
4282 jStart = m_noGhostLayers;
4284 if(m_solver->m_nOffsetCells[0] + m_solver->m_nActiveCells[0] == m_grid->getMyBlockNoCells(0)) {
4285 jEnd = m_nCells[0] - m_noGhostLayers;
4288 MFloat blEdgeVValueLocal = F0;
4289 MBool edgePointIsSet =
false;
4290 MInt edgePointJ = 0;
4293 for(
MInt j = jStart; j < jEnd; ++j) {
4294 const MInt cellId = cellIndex(i, j);
4297 if(coordInOuter(j - 1) < 1.05 && coordInOuter(j) >= 1.05) {
4298 blEdgeVValueLocal = m_cells->pvariables[PV->V][cellIndex(i, j - 1)];
4302 if(coordInOuter(j) < 1.05) {
4303 MFloat uInner = F0, vInner = F0, TInner = F0, mutInner = F0;
4304 MFloat uOuter = F0, vOuter = F0, TOuter = F0, mutOuter = F0;
4305 const MFloat count = alpha * (coordInOuter(j) -
b);
4306 const MFloat denom = (F1 - F2 *
b) * coordInOuter(j) +
b;
4307 const MFloat ratio = count / denom;
4308 const MFloat wfun = F1B2 * (F1 + tanh(ratio) / tanh(alpha));
4310 for(
MInt jj = 0; jj < totalCells - 1; ++jj) {
4311 const MInt localId = jj;
4312 const MInt localIdP1 = jj + 1;
4314 const MFloat yInnerRe = varSlice(3, localId);
4315 const MFloat yInnerReP1 = varSlice(3, localIdP1);
4317 if((yInnerRe - coordInInner(j)) < rescalEPS && yInnerReP1 > coordInInner(j)) {
4318 const MFloat dy1 = coordInInner(j) - yInnerRe;
4319 const MFloat dy2 = yInnerReP1 - coordInInner(j);
4320 const MFloat dy = yInnerReP1 - yInnerRe;
4322 const MFloat u = varSlice(0, localId);
4323 const MFloat uP1 = varSlice(0, localIdP1);
4324 const MFloat v = varSlice(1, localId);
4325 const MFloat vP1 = varSlice(1, localIdP1);
4326 const MFloat t = varSlice(2, localId);
4327 const MFloat tP1 = varSlice(2, localIdP1);
4328 const MFloat mut = varSlice(5, localId);
4329 const MFloat mutP1 = varSlice(5, localIdP1);
4330 uInner = (uP1 * dy1 + u * dy2) / dy;
4331 vInner = (vP1 * dy1 + v * dy2) / dy;
4332 TInner = (tP1 * dy1 + t * dy2) / dy;
4333 mutInner = (mutP1 * dy1 + mut * dy2) / dy;
4338 for(
MInt jj = 0; jj < totalCells - 1; ++jj) {
4339 const MInt localId = jj;
4340 const MInt localIdP1 = jj + 1;
4342 const MFloat yOuterRe = varSlice(4, localId);
4343 const MFloat yOuterReP1 = varSlice(4, localIdP1);
4345 if((yOuterRe - coordInOuter(j)) < rescalEPS && yOuterReP1 > coordInOuter(j)) {
4346 const MFloat dy1 = coordInOuter(j) - yOuterRe;
4347 const MFloat dy2 = yOuterReP1 - coordInOuter(j);
4348 const MFloat dy = yOuterReP1 - yOuterRe;
4350 const MFloat u = varSlice(0, localId);
4351 const MFloat uP1 = varSlice(0, localIdP1);
4352 const MFloat v = varSlice(1, localId);
4353 const MFloat vP1 = varSlice(1, localIdP1);
4354 const MFloat t = varSlice(2, localId);
4355 const MFloat tP1 = varSlice(2, localIdP1);
4356 const MFloat mut = varSlice(5, localId);
4357 const MFloat mutP1 = varSlice(5, localIdP1);
4358 uOuter = (uP1 * dy1 + u * dy2) / dy;
4359 vOuter = (vP1 * dy1 + v * dy2) / dy;
4360 TOuter = (tP1 * dy1 + t * dy2) / dy;
4361 mutOuter = (mutP1 * dy1 + mut * dy2) / dy;
4365 const MFloat TInnerA =
POW2(gams) * TInner + ctem1 * PV->TInfinity;
4366 const MFloat TOuterA =
POW2(gams) * TOuter - (ctem2 * (uOuter / PV->UInfinity) - ctem3) * PV->TInfinity;
4369 const MFloat uvdInner = PV->UInfinity * asin(b_vd * uInner / PV->UInfinity) / b_vd;
4370 const MFloat uvdOuter = PV->UInfinity * asin(b_vd * uOuter / PV->UInfinity) / b_vd;
4374 uInner = gams * uvdInner;
4375 uOuter = gams * uvdOuter + (F1 - gams) * uvd8;
4377 uInner = PV->UInfinity * sin(b_vd * uInner / PV->UInfinity) / b_vd;
4378 uOuter = PV->UInfinity * sin(b_vd * uOuter / PV->UInfinity) / b_vd;
4381 const MFloat tempWallInlet = tempWallInletGlobal;
4382 const MFloat tempWallRecycling = wallProperties(2);
4384 const MFloat viscWallInlet = SUTHERLANDLAW(tempWallInlet);
4385 const MFloat viscWallRecycling = SUTHERLANDLAW(tempWallRecycling);
4386 const MFloat thetaInlet = thetaGlobal(0);
4387 const MFloat thetaRecycling = thetaGlobal(1);
4388 mutInner = mutInner * (viscWallInlet / viscWallRecycling);
4389 mutOuter = mutOuter * gams * (thetaInlet / thetaRecycling);
4391 const MFloat uMean = uInner * (F1 - wfun) + uOuter * wfun;
4392 const MFloat vMean = vInner * (F1 - wfun) + vOuter * wfun;
4393 const MFloat tMean = TInnerA * (F1 - wfun) + TOuterA * wfun;
4394 MFloat mutMean = mutInner * (F1 - wfun) + mutOuter * wfun;
4396 const MFloat clebf = 6.6;
4397 const MFloat blt = m_rescalingBLT;
4398 const MFloat cleb = F1 / (F1 + pow((m_cells->coordinates[1][cellId] / (clebf * blt)), 6.0));
4400 const MFloat pres = PV->PInfinity;
4401 const MFloat rhoIn = gamma * pres / tMean;
4403 m_cells->pvariables[PV->RHO][cellId] = rhoIn * cleb;
4404 m_cells->pvariables[PV->U][cellId] = uMean;
4405 m_cells->pvariables[PV->V][cellId] = vMean;
4406 m_cells->pvariables[PV->P][cellId] = pres;
4407 m_cells->pvariables[PV->RANS_VAR[0]][cellId] = mutMean / rhoIn;
4410 if(!edgePointIsSet) {
4412 edgePointIsSet =
true;
4415 const MFloat pres = PV->PInfinity;
4416 const MFloat rhoIn = gamma * pres / PV->TInfinity;
4418 const MFloat uMean = PV->UInfinity;
4419 const MFloat vMean = PV->VInfinity;
4421 m_cells->pvariables[PV->RHO][cellId] = rhoIn;
4422 m_cells->pvariables[PV->U][cellId] = uMean;
4423 m_cells->pvariables[PV->V][cellId] = vMean;
4424 m_cells->pvariables[PV->P][cellId] = pres;
4425 m_cells->pvariables[PV->RANS_VAR[0]][cellId] = PV->ransInfinity[0];
4429 MFloat blEdgeVValueGlobal = F0;
4430 MPI_Allreduce(&blEdgeVValueLocal, &blEdgeVValueGlobal, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4431 "blEdgeVValueLocal",
"blEdgeVValueGlobal");
4433 if(edgePointIsSet) {
4434 for(
MInt j = edgePointJ; j < jEnd; ++j) {
4435 const MInt cellId = cellIndex(i, j);
4436 m_cells->pvariables[PV->V][cellId] = blEdgeVValueGlobal;
4437 const MFloat pres = PV->PInfinity;
4438 m_cells->pvariables[PV->P][cellId] = pres;
4442 for(
MInt j = 0; j < m_nCells[0]; ++j) {
4444 const MInt cellId = cellIndex(1, j);
4445 const MInt cellIdM1 = cellIndex(0, j);
4446 const MInt cellIdadj = cellIndex(2, j);
4448 for(
MInt var = 0; var < PV->noVariables; var++) {
4449 m_cells->pvariables[var][cellIdM1] = 2.0 * m_cells->pvariables[var][cellId] - m_cells->pvariables[var][cellIdadj];
4456template <MBool isRans>
4458 MInt* start = m_physicalBCMap[bcId]->start1;
4462 const MFloat F727 = 72.0 / 7.0;
4463 const MInt i = start[0];
4465 const MFloat maxIntegrationHeight = 2.0 * m_rescalingBLT;
4474 thetaLocal.
fill(F0);
4475 thetaGlobal.
fill(F0);
4479 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; ++j) {
4480 const MInt cellId = cellIndex(i, j);
4481 const MInt pointIdM1 = getPointIdFromCell(i, j);
4482 const MInt pointIdP1 = getPointIdFromPoint(pointIdM1, 0, 1);
4484 if(m_grid->m_coordinates[1][pointIdM1] > maxIntegrationHeight) {
4488 const MFloat urat = m_cells->pvariables[PV->U][cellId] / PV->UInfinity;
4489 const MFloat momThick = m_cells->pvariables[PV->U][cellId] * m_cells->pvariables[PV->RHO][cellId] * fabs(F1 - urat)
4490 / (CV->rhoUInfinity);
4493 const MFloat ydist = m_grid->m_coordinates[1][pointIdP1] - m_grid->m_coordinates[1][pointIdM1];
4494 thetaLocal(1) += momThick * ydist;
4499 MPI_Allreduce(thetaLocal.
begin(), thetaGlobal.
begin(), 2, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4500 "thetaLocal.begin()",
"thetaGlobal.begin()");
4506 const MFloat delta = F727 * thetaGlobal(1);
4507 const MInt noVar = 3;
4508 const MInt wallLocalOffset = m_solver->m_nOffsetCells[0];
4512 wallPropertiesLocal.
fill(F0);
4513 wallProperties.
fill(F0);
4516 if(wallLocalOffset == 0 && m_solver->m_nActiveCells[1] >= m_noGhostLayers) {
4517 const MInt cellId = cellIndex(i, m_noGhostLayers);
4518 const MFloat rho = m_cells->pvariables[PV->RHO][cellId];
4519 const MFloat p = m_cells->pvariables[PV->P][cellId];
4520 const MFloat t = p * m_solver->m_gamma / rho;
4521 const MFloat mu = SUTHERLANDLAW(t);
4522 const MFloat uWall = fabs(m_cells->pvariables[PV->U][cellId]);
4523 const MFloat ydist = m_cells->coordinates[1][cellId] - yWall;
4524 const MFloat uTau = sqrt(uWall * mu / (ydist * rho));
4526 wallPropertiesLocal(0) = uTau;
4527 wallPropertiesLocal(1) = rho;
4528 wallPropertiesLocal(2) = t;
4532 m_solver->m_rescalingCommGrComm, AT_,
"wallPropertiesLocal.begin()",
"wallProperties.begin()");
4534 MFloat tempWallInletLocal = F0;
4535 MFloat tempWallInletGlobal = F0;
4536 MPI_Allreduce(&tempWallInletLocal, &tempWallInletGlobal, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4537 "tempWallInletLocal",
"tempWallInletGlobal");
4543 MInt totalCells = m_grid->getMyBlockNoCells(0) + 1;
4545 const MInt noVariables = PV->noVariables + 1;
4549 for(
MInt j = m_noGhostLayers; j < m_nCells[0] - m_noGhostLayers; ++j) {
4550 const MInt cellId = cellIndex(i, j);
4551 const MFloat rho = m_cells->pvariables[PV->RHO][cellId];
4552 const MFloat frho = F1 / rho;
4553 const MFloat p = pressure(cellId);
4554 const MFloat temp = p * m_solver->m_gamma * frho;
4555 const MFloat mu = SUTHERLANDLAW(temp);
4556 const MFloat uTauRe = wallProperties(0);
4557 const MFloat yIn = (m_cells->coordinates[1][cellId] - yWall) * uTauRe * rho / (mu * sqrt(m_solver->m_Re0));
4558 const MFloat yOut = (m_cells->coordinates[1][cellId] - yWall) * rho / (delta * CV->rhoInfinity);
4559 const MFloat u = m_cells->pvariables[PV->U][cellId];
4560 const MFloat v = m_cells->pvariables[PV->V][cellId];
4563 const MFloat mut = m_cells->pvariables[PV->RANS_VAR[0]][cellId] * rho;
4566 const MInt localId = m_solver->m_nOffsetCells[0] + j - m_noGhostLayers + 1;
4569 varSliceLocal(0, localId) = u;
4570 varSliceLocal(1, localId) = v;
4571 varSliceLocal(2, localId) = temp;
4572 varSliceLocal(3, localId) = yIn;
4573 varSliceLocal(4, localId) = yOut;
4574 varSliceLocal(5, localId) = mut;
4578 if(m_solver->m_nOffsetCells[0] == 0) {
4579 varSliceLocal(0, 0) = 0.0;
4580 varSliceLocal(1, 0) = 0.0;
4581 varSliceLocal(2, 0) = varSliceLocal(2, 1);
4582 varSliceLocal(3, 0) = 0.0;
4583 varSliceLocal(4, 0) = 0.0;
4584 varSliceLocal(5, 0) = varSliceLocal(5, 1);
4589 m_solver->m_rescalingCommGrComm, AT_,
"varSliceLocal.begin()",
"varSlice.begin()");
4591 MFloat blEdgeVValueLocal = F0;
4592 MFloat blEdgeVValueGlobal = F0;
4593 MPI_Allreduce(&blEdgeVValueLocal, &blEdgeVValueGlobal, 1, MPI_DOUBLE, MPI_SUM, m_solver->m_rescalingCommGrComm, AT_,
4594 "blEdgeVValueLocal",
"blEdgeVValueGlobal");
4603template <MBool isRans>
4605 MInt* start = m_physicalBCMap[bcId]->start1;
4606 MInt* end = m_physicalBCMap[bcId]->end1;
4608 switch(m_physicalBCMap[bcId]->face) {
4610 for(
MInt i = start[0]; i < end[0]; i++) {
4611 for(
MInt j = start[1]; j < end[1]; j++) {
4612 MInt cellId = cellIndex(m_noGhostLayers - 1 - i, j);
4613 MInt cellIdadj = cellIndex(m_noGhostLayers - i, j);
4616 m_cells->pvariables[PV->P][cellId] = m_cells->pvariables[PV->P][cellIdadj];
4622 mTerm(1, AT_,
"Face not implemented");
4631template <MBool isRans>
4635 const MInt IJ[nDim] = {1, m_nCells[1]};
4636 MInt* start = m_physicalBCMap[bcId]->start1;
4637 MInt* end = m_physicalBCMap[bcId]->end1;
4639 constexpr MFloat eps = 1e-8;
4640 const MFloat gamma = m_solver->m_gamma;
4641 const MFloat gammaOverGammaMinusOne = gamma / (gamma - 1);
4643 if(m_physicalBCMap[bcId]->Nstar == -1) {
4648 const MInt face = m_physicalBCMap[bcId]->face;
4649 const MInt normalDir = face / 2;
4650 const MInt firstTangentialDir = (normalDir + 1) % nDim;
4651 const MInt normalDirStart = start[normalDir];
4652 const MInt firstTangentialStart = start[firstTangentialDir];
4653 const MInt firstTangentialEnd = end[firstTangentialDir];
4654 const MInt inc[nDim] = {IJ[normalDir], IJ[firstTangentialDir]};
4656 const MInt n = (face % 2) * 2 - 1;
4657 const MInt g[2] = {normalDirStart + (
MInt)(0.5 - (0.5 * (
MFloat)n)),
4658 normalDirStart + (
MInt)(0.5 + (0.5 * (
MFloat)n))};
4659 const MInt a1 = normalDirStart + (
MInt)(0.5 - (1.5 * (
MFloat)n));
4662 for(
MInt t1 = firstTangentialStart, pos = 0; t1 < firstTangentialEnd; t1++, ++pos) {
4663 const MInt cellIdG1 = g[0] * inc[0] + t1 * inc[1];
4664 const MFloat normalVec[nDim] = {m_cells->fq[FQ->NORMAL[0]][cellIdG1], m_cells->fq[FQ->NORMAL[1]][cellIdG1]};
4665 const MInt cellIdA1 = a1 * inc[0] + t1 * inc[1];
4666 const MFloat por_x = m_cells->fq[FQ->POROSITY][cellIdA1];
4667 for(
MInt i = 0; i < 2 ; ++i) {
4668 const MInt cellIdG = g[i] * inc[0] + t1 * inc[1];
4670 const MFloat por_y = m_cells->fq[FQ->POROSITY][cellIdG];
4671 const MFloat rho_y = m_cells->pvariables[PV->RHO][cellIdG];
4672 const MFloat p_y = m_cells->pvariables[PV->P][cellIdG];
4673 const MFloat u_y = m_cells->pvariables[PV->U][cellIdG];
4674 const MFloat v_y = m_cells->pvariables[PV->V][cellIdG];
4675 const MFloat k_y = (isRans) ? m_cells->pvariables[PV->RANS_VAR[0]][cellIdG] : 0.0;
4678 const MFloat U_y = u_y * normalVec[0] + v_y * normalVec[1];
4679 const MFloat V_y[nDim] = {u_y - U_y * normalVec[0], v_y - U_y * normalVec[1]};
4682 const MFloat auxconst1 = gammaOverGammaMinusOne * p_y / pow(rho_y, gamma);
4683 const MFloat auxconst2 = (por_y / por_x) * rho_y * k_y;
4684 const MFloat auxconst3 = -(gammaOverGammaMinusOne * p_y / rho_y + 0.5 *
POW2(U_y) + k_y);
4685 const MFloat auxconst4 = 0.5 *
POW2(por_y / por_x * rho_y * U_y);
4690 MFloat res = auxconst1 * pow(rho_x, gamma + 1) + auxconst2 * rho_x + auxconst3 *
POW2(rho_x) + auxconst4;
4692 MInt testcounter = 0;
4695 const MFloat dresdrho = (gamma + 1) * auxconst1 * pow(rho_x, gamma) + auxconst2 + 2 * auxconst3 * rho_x;
4696 const MFloat deltarho_x = -res / dresdrho;
4697 rho_x += deltarho_x;
4699 res = auxconst1 * pow(rho_x, gamma + 1) + auxconst2 * rho_x + auxconst3 *
POW2(rho_x) + auxconst4;
4702 if(testcounter > 100)
break;
4705 if(testcounter > 10) {
4706 cout <<
"Loop in BC6002 took " << testcounter <<
" steps!"
4707 <<
" domainId=" << m_solver->domainId() <<
" cellId: " << cellIdG <<
" (" << g[i] <<
"|" << t1
4708 <<
") res=" << res <<
" (x|y)=" << m_cells->coordinates[0][cellIdG] <<
"|"
4709 << m_cells->coordinates[1][cellIdG] << por_y <<
" " << rho_y <<
" " << p_y <<
" " << u_y <<
" " << v_y
4714 const MFloat temp = por_y * rho_y / (por_x * rho_x);
4715 const MFloat p_x = p_y * pow(rho_x / rho_y, gamma);
4716 const MFloat U_x = temp * U_y;
4717 const MFloat u_x = U_x * normalVec[0] + V_y[0] ;
4718 const MFloat v_x = U_x * normalVec[1] + V_y[1] ;
4721 m_cells->pvariables[PV->RHO][cellIdG] = rho_x;
4722 m_cells->pvariables[PV->P][cellIdG] = p_x;
4723 m_cells->pvariables[PV->U][cellIdG] = u_x;
4724 m_cells->pvariables[PV->V][cellIdG] = v_x;
4726 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG] *= temp;
4727 m_cells->pvariables[PV->RANS_VAR[1]][cellIdG] *= temp;
4732 const MInt singularId = m_physicalBCMap[bcId]->SingularId;
4733 const auto& singularity = m_solver->m_singularity[singularId];
4736 const MInt* start2 = singularity.start;
4737 const MInt* end2 = singularity.end;
4738 for(
MInt d = 0; d < nDim; ++d) {
4739 if(end[d] - start[d] != end2[d] - start2[d])
mTerm(1,
"SCHEISSE");
4746 for(
MInt j = start[1], jj = start2[1]; j < end[1]; j++, jj++) {
4747 for(
MInt i = start[0], ii = start2[0]; i < end[0]; i++, ii++) {
4748 const MInt cellIdG = cellIndex(i, j);
4749 const MInt cellIdA1 = cellIndex(ii, jj);
4750 const MFloat normalVec[nDim] = {m_cells->fq[FQ->NORMAL[0]][cellIdG], m_cells->fq[FQ->NORMAL[1]][cellIdG]};
4751 const MFloat por_x = m_cells->fq[FQ->POROSITY][cellIdA1];
4753 const MFloat por_y = m_cells->fq[FQ->POROSITY][cellIdG];
4754 const MFloat rho_y = m_cells->pvariables[PV->RHO][cellIdG];
4755 const MFloat p_y = m_cells->pvariables[PV->P][cellIdG];
4756 const MFloat u_y = m_cells->pvariables[PV->U][cellIdG];
4757 const MFloat v_y = m_cells->pvariables[PV->V][cellIdG];
4758 const MFloat k_y = (isRans) ? m_cells->pvariables[PV->RANS_VAR[0]][cellIdG] : 0.0;
4761 const MFloat U_y = u_y * normalVec[0] + v_y * normalVec[1];
4762 const MFloat V_y[nDim] = {u_y - U_y * normalVec[0], v_y - U_y * normalVec[1]};
4765 const MFloat auxconst1 = gammaOverGammaMinusOne * p_y / pow(rho_y, gamma);
4766 const MFloat auxconst2 = (por_y / por_x) * rho_y * k_y;
4767 const MFloat auxconst3 = -(gammaOverGammaMinusOne * p_y / rho_y + 0.5 *
POW2(U_y) + k_y);
4768 const MFloat auxconst4 = 0.5 *
POW2(por_y / por_x * rho_y * U_y);
4773 MFloat res = auxconst1 * pow(rho_x, gamma + 1) + auxconst2 * rho_x + auxconst3 *
POW2(rho_x) + auxconst4;
4775 MInt testcounter = 0;
4778 const MFloat dresdrho = (gamma + 1) * auxconst1 * pow(rho_x, gamma) + auxconst2 + 2 * auxconst3 * rho_x;
4779 const MFloat deltarho_x = -res / dresdrho;
4780 rho_x += deltarho_x;
4782 res = auxconst1 * pow(rho_x, gamma + 1) + auxconst2 * rho_x + auxconst3 *
POW2(rho_x) + auxconst4;
4785 if(testcounter > 100)
break;
4788 if(testcounter > 10) {
4789 cout <<
"Loop in BC6002 took " << testcounter <<
" steps!"
4790 <<
" domainId=" << m_solver->domainId() <<
" cellId: " << cellIdG <<
" res=" << res
4791 <<
" (x|y)=" << m_cells->coordinates[0][cellIdG] <<
"|" << m_cells->coordinates[1][cellIdG] << por_y
4792 <<
" " << rho_y <<
" " << p_y <<
" " << u_y <<
" " << v_y << endl;
4796 const MFloat temp = por_y * rho_y / (por_x * rho_x);
4797 const MFloat p_x = p_y * pow(rho_x / rho_y, gamma);
4798 const MFloat U_x = temp * U_y;
4799 const MFloat u_x = U_x * normalVec[0] + V_y[0] ;
4800 const MFloat v_x = U_x * normalVec[1] + V_y[1] ;
4803 m_cells->pvariables[PV->RHO][cellIdG] = rho_x;
4804 m_cells->pvariables[PV->P][cellIdG] = p_x;
4805 m_cells->pvariables[PV->U][cellIdG] = u_x;
4806 m_cells->pvariables[PV->V][cellIdG] = v_x;
4808 m_cells->pvariables[PV->RANS_VAR[0]][cellIdG] *= temp;
4809 m_cells->pvariables[PV->RANS_VAR[1]][cellIdG] *= temp;
4817template <MBool isRans>
4819 return m_cells->pvariables[PV->P][cellId];
4822template <MBool isRans>
4824 const MFloat gamma = m_solver->m_gamma;
4825 MFloat t = gamma * m_cells->pvariables[PV->P][cellId] / m_cells->pvariables[PV->RHO][cellId];
MLong allocatedBytes()
Return the number of allocated bytes.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
2D structured solver class
Base class of the structured solver.
MInt timer(const MInt timerId) const
MInt m_rescalingCommGrRoot
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
Class for the 2D stuctured boundary conditions.
MInt getPointIdFromPoint(MInt origin, MInt incI, MInt incJ)
void bc2006(MInt)
Characteristic in/outflow boundary for zero velocities.
void computeWallDistances()
void computeFrictionPressureCoef_(const MBool auxDataWindow=false, const MBool computePower=false)
void getCloserMap(const MFloat *const, std::vector< std::pair< MInt, MInt > > &, const MFloat *const, std::vector< std::pair< MInt, MInt > > &, MFloat *const, T comparator={})
void correctWallDistanceAtBoundary(MInt)
void bc2003(MInt)
Subsonic in/outflow simple.
void correctBndryCndIndices()
void calc_cp_cf(const MInt, const MInt, const MInt, const MInt, MFloat(&)[calcCp+nDim *calcCf])
virtual void distributeWallAndFPProperties() override
void bc2007(MInt)
Subsonic Outflow extrapolate all but pressure, prescribe p8.
MInt getPointIdFromCell(MInt i, MInt j)
void readAndDistributeSpongeCoordinates()
void bc2005(MInt)
Supersonic Outflow,.
void bc2600(MInt)
Prescribe given profile BC.
void bc2999(MInt)
Blasius bl inflow boundary condition.
MInt cellIndex(MInt i, MInt j)
void bc2002(MInt)
Supersonic Inflow.
void distributeMapProperties(const std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &, const std::vector< MInt > &, const std::vector< MInt > &, const std::map< MInt, std::tuple< MInt, MInt, MFloat > > &cellId2recvCell, const std::vector< MInt > &, MFloat *const)
void bc2004(MInt)
Subsonic Outflow, not really non-reflecting for face 0,1,3.
StructuredBndryCnd2D(FvStructuredSolver< 2 > *solver, StructuredGrid< 2 > *grid)
void setUpNearMapComm(const std::vector< std::pair< MInt, MInt > > &, const std::vector< MInt > &, const std::vector< MFloat > &, std::map< MInt, std::tuple< MInt, MInt, MFloat > > &, std::vector< MInt > &, std::vector< MInt > &)
void initBc2510(MInt)
Rescaling inflow.
void bc2001(MInt)
Subsonic Inflow <== tfs2001.
void computeDistance2Map(const std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &, MFloat *const, std::vector< std::pair< MInt, MInt > > &, std::vector< MInt > &, std::vector< MFloat > &)
Compute shortest distance to given set of maps.
virtual void computeLocalWallDistances() override
void initBc2402(MInt)
Channel flow BC.
MFloat shortestDistanceToLineElement(const MFloat(&)[nDim], const MFloat(&)[nDim], const MFloat(&)[nDim], MFloat &, MFloat &)
virtual void computeLocalExtendedDistancesAndSetComm() override
FvStructuredSolver2D * m_solver
void bc3000(MInt)
Symmetry plane BC.
void modifyFPDistance(const std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &, MFloat *const, std::vector< std::pair< MInt, MInt > > &, const std::vector< MFloat > &)
Modifies the fluid-porous distance.
void initBc2600(MInt)
Prescribe profile BC.
virtual void bc6002(MInt) override
Base class of the structured boundary conditions.
MPI_Comm m_StructuredComm
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
void printAllocatedMemory(const MLong oldAllocatedBytes, const MString &solverName, const MPI_Comm comm)
Prints currently allocated memory.
std::basic_string< char > MString
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier
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_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_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
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
MFloat distance(const MFloat *a, const MFloat *b)
std::vector< T > mpiExchangePointToPoint(const T *const sendBuffer, const MInt *const snghbrs, const MInt nosnghbrs, const MInt *const sendcounts, const MInt *const rnghbrs, const MInt nornghbrs, const MPI_Comm &mpi_comm, const MInt domainId, const MInt dataBlockSize, MInt *const recvcounts_=nullptr, MInt *const rdispls_=nullptr)
MInt nearest(Point< DIM > pt, MFloat &dist)
MInt locatenearest(Point< DIM > pt, MFloat r, MInt *list, MFloat *dn, MInt nmax, MBool &overflow)