11template <
class base_iterator,
class SolverType>
14 return p->m_solver->a_reconstructionNeighborId(p->m_stgToCellId[*(*
this)], dir);
18template <
class base_iterator,
class SolverType>
21 return p->m_stgToCellId[*(*this)];
25template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
28 const MPI_Comm commStg,
29 MInt* sortedBndryCellIds,
31 MInt stgFaceNormalDir,
33 MInt stgWallNormalDir,
38 m_solverId(solver->m_solverId),
40 m_sutherlandConstant(solver->m_sutherlandConstant),
41 m_sutherlandPlusOne(solver->m_sutherlandPlusOne),
43 m_noStgLCells(noStgLCells),
44 m_stgFaceNormalDir(stgFaceNormalDir),
45 m_stgWallNormalDir(stgWallNormalDir),
49 a(new
Accessor(sortedBndryCellIds, noStgLCells, m_solver, commStg, cutOff)) {
52 IF_CONSTEXPR(nDim == 2)
mTerm(1, AT_,
"Only implemented for 3D!");
54 for(
MInt i = 0; i < nDim; i++) {
79template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
81 std::uniform_real_distribution<MFloat> randRealDistNumber(0, 1);
82 return randRealDistNumber(randomEddyPosGenerator());
95template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
97 std::uniform_real_distribution<MFloat> randRealDistNumber(0, 1);
98 return pow(randRealDistNumber(randomEddyPosGenerator()), m_stgEddieDistribution);
102template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
104 return 15.0 * pow((rand() /
double(RAND_MAX)) - 0.35, F3) + F1;
108template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
121template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
124 m_stgInitialStartup =
false;
125 m_stgRootRank =
false;
128 MPI_Comm_rank(m_commStg, &m_commStgMyRank);
130 m_commStgMyRank = -1;
134 std::string prop_name;
137 std::stringstream errorMsg;
138 errorMsg <<
": This property is not allowed to exist without an assignment to a BC" << std::endl;
141 prop_name =
"bc" + std::to_string(m_bcId) +
"STGSeed";
143 m_randomEddySeed = Context::getSolverProperty<MInt>(prop_name, m_solverId, AT_, &m_randomEddySeed);
144 m_PRNGEddy.seed(m_randomEddySeed);
147 m_zonal = m_solver->m_zonal;
149 prop_name =
"bc" + std::to_string(m_bcId) +
"preliminary";
150 m_preliminary = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_preliminary);
152 prop_name =
"bc" + std::to_string(m_bcId) +
"preliminaryRans2D";
153 m_preliminaryRans2D = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_preliminary);
155 if(m_preliminaryRans2D) m_preliminary =
true;
157 prop_name =
"bc" + std::to_string(m_bcId) +
"newStgMethod";
158 m_newStgMethod = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_newStgMethod);
160 prop_name =
"bc" + std::to_string(m_bcId) +
"stgCylinderTransformation";
161 m_cylinderTransformation = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_cylinderTransformation);
165 m_isotropicTurbulence =
166 Context::getSolverProperty<MBool>(
"isotropicTurbulence", m_solverId, AT_, &m_isotropicTurbulence);
174 m_BLEddieFraction = F1;
175 m_freeStreamTurbulence =
false;
177 m_freeStreamTurbulence =
178 Context::getSolverProperty<MBool>(
"freeStreamTurbulence", m_solverId, AT_, &m_freeStreamTurbulence);
179 m_uuFS = Context::getSolverProperty<MFloat>(
"uuFS", m_solverId, AT_, &m_uuFS);
180 m_vvFS = Context::getSolverProperty<MFloat>(
"vvFS", m_solverId, AT_, &m_vvFS);
181 m_wwFS = Context::getSolverProperty<MFloat>(
"wwFS", m_solverId, AT_, &m_wwFS);
182 m_SijSijFS = Context::getSolverProperty<MFloat>(
"SijSijFS", m_solverId, AT_, &m_SijSijFS);
183 m_BLEddieFraction = Context::getSolverProperty<MFloat>(
"BLEddieFraction", m_solverId, AT_, &m_BLEddieFraction);
199 prop_name =
"bc" + std::to_string(m_bcId) +
"stgSubSup";
202 m_stgSubSup = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_stgSubSup);
217 prop_name =
"bc" + std::to_string(m_bcId) +
"stgSupersonic";
218 m_stgSupersonic =
false;
220 m_stgSupersonic = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_stgSupersonic);
222 if(m_stgSupersonic && m_stgSubSup) {
224 if(m_solver->domainId() == 0) {
225 std::cout <<
"WARNING: You activated conflicting properties stgSubSup "
226 <<
"and stgSupersonic, thus only the pure supersonic formulation will be used. "
227 <<
"Switch off stgSupersonic to get the mixed formulation" << std::endl;
246 prop_name =
"bc" + std::to_string(m_bcId) +
"BLT1";
248 m_stgBLT1 = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgBLT1);
264 prop_name =
"bc" + std::to_string(m_bcId) +
"BLT2";
266 m_stgBLT2 = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgBLT2);
282 prop_name =
"bc" + std::to_string(m_bcId) +
"BLT3";
284 m_stgBLT3 = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgBLT3);
286 mAlloc(m_stgLengthFactors, 3,
"m_stgLengthFactors", F0, AT_);
287 m_stgLengthFactors[0] = 1.0;
288 m_stgLengthFactors[1] = 0.6;
289 m_stgLengthFactors[2] = 1.5;
306 prop_name =
"bc" + std::to_string(m_bcId) +
"stgLengthFactors";
308 for(
MInt i = 0; i < 3; i++) {
309 m_stgLengthFactors[i] = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgLengthFactors[i], i);
313 mAlloc(m_stgRSTFactors, 3,
"m_stgRSTFactors", F0, AT_);
314 m_stgRSTFactors[0] = 1.0;
315 m_stgRSTFactors[1] = 0.4;
316 m_stgRSTFactors[2] = 0.5;
333 prop_name =
"bc" + std::to_string(m_bcId) +
"stgRSTFactors";
335 for(
MInt i = 0; i < 3; i++) {
336 m_stgRSTFactors[i] = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgRSTFactors[i], i);
352 prop_name =
"bc" + std::to_string(m_bcId) +
"stgMaxNoEddies";
353 m_stgMaxNoEddies = 200;
354 m_stgMaxNoEddies = Context::getSolverProperty<MInt>(prop_name, m_solverId, AT_, &m_stgMaxNoEddies);
368 prop_name =
"bc" + std::to_string(m_bcId) +
"stgExple";
370 m_stgExple = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgExple);
385 mTerm(1, AT_,
"stgEddieDistribution" + errorMsg.str());
386 prop_name =
"bc" + std::to_string(m_bcId) +
"stgEddieDistribution";
387 m_stgEddieDistribution = 1.0;
389 m_stgEddieDistribution = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgEddieDistribution);
405 prop_name =
"bc" + std::to_string(m_bcId) +
"stgCreateNewEddies";
406 m_stgCreateNewEddies =
false;
408 m_stgCreateNewEddies = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_stgCreateNewEddies);
423 prop_name =
"bc" + std::to_string(m_bcId) +
"stgInitialStartup";
424 m_stgInitialStartup =
false;
425 m_stgInitialStartup = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_stgInitialStartup);
439 mTerm(1, AT_,
"stgEddieLengthScales" + errorMsg.str());
440 prop_name =
"bc" + std::to_string(m_bcId) +
"stgEddieLengthScales";
441 m_stgEddieLengthScales =
false;
443 m_stgEddieLengthScales = Context::getSolverProperty<MBool>(prop_name, m_solverId, AT_, &m_stgEddieLengthScales);
458 prop_name =
"bc" + std::to_string(m_bcId) +
"stgShapeFunction";
459 m_stgShapeFunction = 4;
461 m_stgShapeFunction = Context::getSolverProperty<MInt>(prop_name, m_solverId, AT_, &m_stgShapeFunction);
470 m_stgNoEddieProperties = 6;
471 if(m_stgEddieLengthScales) {
472 m_stgNoEddieProperties = 9;
474 mAlloc(m_stgEddies, m_stgMaxNoEddies, m_stgNoEddieProperties,
"m_solver->m_stgEddies", -F1, AT_);
477 mAlloc(m_stgEddyStrength, m_stgMaxNoEddies,
"m_solver->m_stgEddyStrength", F1, AT_);
479 m_log <<
"===========================================================" << std::endl
480 <<
" STG PROPERTIES " << std::endl
481 <<
"===========================================================" << std::endl
482 <<
"Initial Start: " << m_stgInitialStartup << std::endl
483 <<
"SubSup (Mixed subsonic/supersonic bc): " << m_stgSubSup << std::endl
484 <<
"Supersonic BC: " << m_stgSupersonic << std::endl
485 <<
"BLT 1,2,3: " << m_stgBLT1 <<
", " << m_stgBLT2 <<
", " << m_stgBLT3 << std::endl
486 <<
"Length factors: " << m_stgLengthFactors[0] <<
", " << m_stgLengthFactors[1] <<
", " << m_stgLengthFactors[2]
488 <<
"Number of eddies: " << m_stgMaxNoEddies << std::endl
489 <<
"Length scale exponent: " << m_stgExple << std::endl
490 <<
"Eddie distribution: " << m_stgEddieDistribution << std::endl
491 <<
"Create new eddies: " << m_stgCreateNewEddies << std::endl
492 <<
"Eddie lengthscales: " << m_stgEddieLengthScales << std::endl
493 <<
"Shape function: " << m_stgShapeFunction << std::endl
494 <<
"Number of eddie properties: " << m_stgNoEddieProperties << std::endl
495 <<
"Number of stg variables: " << STG::noStgVars << std::endl
496 <<
"===========================================================" << std::endl;
504template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
508 MPI_Comm_rank(m_commStg, &m_stgMyRank);
509 m_commStgRoot = commStgRoot;
511 mAlloc(m_stgMaxVel, m_nDim,
"m_stgMaxVel", 0.0, AT_);
512 mAlloc(m_stgVbStart, m_nDim,
"m_stgVbStart", 0.0, AT_);
513 mAlloc(m_stgVbEnd, m_nDim,
"m_stgVbEnd", 0.0, AT_);
516 if(m_stgMyRank == m_commStgRoot) {
517 std::cout <<
globalTimeStep <<
" Initializing BC " + std::to_string(m_bcId) << std::endl;
521 readRANSProfileStg();
523 if(m_solver->m_resetInitialCondition) {
524 m_stgDelta99Inflow = 0.0;
525 m_initialRange =
true;
527 getBoundaryLayerThickness();
531 mAlloc(m_inflowStart, m_nDim,
"m_inflowStart", AT_);
532 mAlloc(m_inflowEnd, m_nDim,
"m_inflowEnd", AT_);
533 getInflowStartEnd(m_inflowStart, m_inflowEnd);
534 setVb(m_inflowStart, m_inflowEnd);
542 && !m_stgCreateNewEddies)
543 || (m_solver->m_wasAdapted) || (m_solver->m_wasBalancedZonal)) {
550 if(m_stgMyRank == m_commStgRoot) {
552 std::cerr <<
"-------Creating new Eddies inside Virtual Box------" << std::endl;
556 for(
MInt n = 0; n < m_stgMaxNoEddies; n++) {
557 generateNewEddies(xk, epsi);
559 bcast_eddies[n + m_stgMaxNoEddies * 0] = xk[0];
560 bcast_eddies[n + m_stgMaxNoEddies * 1] = xk[1];
561 bcast_eddies[n + m_stgMaxNoEddies * 2] = xk[2];
562 bcast_eddies[n + m_stgMaxNoEddies * 3] = epsi[0];
563 bcast_eddies[n + m_stgMaxNoEddies * 4] = epsi[1];
564 bcast_eddies[n + m_stgMaxNoEddies * 5] = epsi[2];
566 bcast_eddyStrength[n] = F1;
568 bcast_eddyStrength[n] = generate_rand_normalDist();
574 MPI_Bcast(bcast_eddies.
begin(), 6 * m_stgMaxNoEddies, MPI_DOUBLE, m_commStgRoot, m_commStg, AT_,
575 "bcast_eddies.begin()");
576 MPI_Bcast(bcast_eddyStrength.
begin(), m_stgMaxNoEddies, MPI_DOUBLE, m_commStgRoot, m_commStg, AT_,
577 "bcast_eddyStrength.begin()");
579 for(
MInt n = 0; n < m_stgMaxNoEddies; n++) {
580 m_stgEddies[n][0] = bcast_eddies[n + m_stgMaxNoEddies * 0];
581 m_stgEddies[n][1] = bcast_eddies[n + m_stgMaxNoEddies * 1];
582 m_stgEddies[n][2] = bcast_eddies[n + m_stgMaxNoEddies * 2];
583 m_stgEddies[n][3] = bcast_eddies[n + m_stgMaxNoEddies * 3];
584 m_stgEddies[n][4] = bcast_eddies[n + m_stgMaxNoEddies * 4];
585 m_stgEddies[n][5] = bcast_eddies[n + m_stgMaxNoEddies * 5];
587 m_stgEddyStrength[n] = bcast_eddyStrength[n];
593template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
597 MInt noStgBcCells = 0;
598 MInt noBcStgLocations = 0;
601 m_stgWallNormalLocations.clear();
607 const MInt cellId =
a->getCellId(it);
609 MFloat halfCellLength = m_solver->grid().halfCellLength(cellId);
611 periodicL = m_solver->a_coordinate(cellId, m_periodicDir) - F1B3 * halfCellLength;
614 if(abs(m_solver->a_coordinate(cellId, m_periodicDir) + halfCellLength - eps - periodicL) < halfCellLength) {
615 m_stgWallNormalLocations.push_back(m_solver->a_coordinate(cellId, m_wallDir));
625 MPI_Comm_size(m_commStg, &comm_size);
630 MInt globalNoBcStgLocations = 0;
631 MPI_Allreduce(&noBcStgLocations, &globalNoBcStgLocations, 1, MPI_INT, MPI_SUM, m_commStg, AT_,
"noBcStgLocations",
632 "globalNoBcStgLocations");
634 ScratchSpace<MFloat> globalBcStgLocations(globalNoBcStgLocations,
"globalBcStgLocations", FUN_);
640 MPI_Gather(&noBcStgLocations, 1, MPI_INT, &recvbuf[0], 1, MPI_INT, 0, m_commStg, AT_,
"noBcStgLocations",
"recvbuf");
642 if(m_stgMyRank == m_commStgRoot) {
644 for(
MInt dom = 0; dom < comm_size; dom++) {
645 displs[dom] = offset;
646 offset += recvbuf[dom];
650 MPI_Gatherv(&m_stgWallNormalLocations[0], noBcStgLocations, MPI_DOUBLE, &globalBcStgLocations[0],
651 &recvbuf[m_stgMyRank], &displs[m_stgMyRank], MPI_DOUBLE, 0, m_commStg, AT_,
"m_StgwallNormalLocations",
652 "globalBcStgLocations");
654 MPI_Bcast(&globalBcStgLocations[0], globalNoBcStgLocations, MPI_DOUBLE, 0, m_commStg, AT_,
"globalBcStgLocations");
656 m_stgGlobalWallNormalLocations.clear();
658 for(
MInt i = 0; i < globalNoBcStgLocations; i++) {
660 if(std::find(m_stgGlobalWallNormalLocations.begin(), m_stgGlobalWallNormalLocations.end(), L)
661 == m_stgGlobalWallNormalLocations.end()) {
662 m_stgGlobalWallNormalLocations.push_back(L);
667 m_stgGlobalNoWallNormalLocations = (
MInt)m_stgGlobalWallNormalLocations.size();
669 std::sort(m_stgGlobalWallNormalLocations.begin(), m_stgGlobalWallNormalLocations.end());
674 mAlloc(m_stgPeriodicCellId, m_stgGlobalNoWallNormalLocations,
"m_stgPeriodicCellIndex", FUN_);
675 mAlloc(m_stgGlobalNoPeriodicLocations, m_stgGlobalNoWallNormalLocations,
"m_stgGlobalNoPeriodicLocations", 0, FUN_);
677 for(
MInt i = 0; i < m_stgGlobalNoWallNormalLocations; i++) {
678 m_stgPeriodicCellId[i].clear();
681 mAlloc(m_stgPeriodicIndex, noStgBcCells,
"m_stgPeriodicIndex", -1, FUN_);
683 vector<MInt> noPeriodicLocations(m_stgGlobalNoWallNormalLocations, F0);
685 for(
MInt i = 0; i < m_stgGlobalNoWallNormalLocations; i++) {
687 const MInt cellId =
a->getCellId(it);
689 if(abs(m_solver->a_coordinate(cellId, m_wallDir) - m_stgGlobalWallNormalLocations[i]) < eps) {
690 m_stgPeriodicIndex[IBC] = i;
691 if(!m_solver->a_isHalo(cellId)) {
692 m_stgPeriodicCellId[i].push_back(IBC);
693 ++noPeriodicLocations[i];
699 MPI_Allreduce(&noPeriodicLocations[0], &m_stgGlobalNoPeriodicLocations[0], m_stgGlobalNoWallNormalLocations, MPI_INT,
700 MPI_SUM, m_commStg, AT_,
"noPeriodicLocations",
"m_stgGlobalNoPeriodicLocations");
703template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
708 std::stringstream filename;
709 filename << m_solver->outputDir() <<
"stg" << std::to_string(m_bcId) <<
"RestartNew_" <<
globalTimeStep
710 << ParallelIo::fileExt();
712 m_log <<
"Writing restart file " << filename.str() <<
" ..." << std::endl;
714 if(m_stgMyRank == m_commStgRoot) {
715 cerr <<
"Writing restart file " << filename.str() <<
" ..." << std::endl;
719 std::stringstream stgPrefix_;
720 stgPrefix_ <<
"stgVar" << m_bcId <<
"_";
721 MString stgPrefix = stgPrefix_.str();
723 ParallelIo parallelIo((filename.str()).c_str(), PIO_REPLACE, m_commStg);
724 parallelIo.setAttributes(&(m_stgMaxNoEddies), (stgPrefix +
"stgMaxNoEddies").c_str(), 1);
726 parallelIo.defineArray(PIO_FLOAT, (stgPrefix +
"FQeddies").c_str(), m_stgMaxNoEddies * m_stgNoEddieProperties);
728 parallelIo.defineArray(PIO_FLOAT, (stgPrefix +
"FQeddyStrength").c_str(), m_stgMaxNoEddies);
730 parallelIo.setAttribute(
"FQeddies",
"name", (stgPrefix +
"FQeddies").c_str());
731 parallelIo.setOffset(m_stgMaxNoEddies * m_stgNoEddieProperties, 0);
732 parallelIo.writeArray(&(m_stgEddies[0][0]), (stgPrefix +
"FQeddies").c_str());
734 parallelIo.setAttribute(
"FQeddyStrength",
"name", (stgPrefix +
"FQeddyStrength").c_str());
735 parallelIo.setOffset(m_stgMaxNoEddies, 0);
736 parallelIo.writeArray(&(m_stgEddyStrength[0]), (stgPrefix +
"FQeddyStrength").c_str());
739template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
744 std::stringstream filename;
745 filename << m_solver->restartDir() <<
"stg" << std::to_string(m_bcId) <<
"RestartNew_" <<
globalTimeStep
746 << ParallelIo::fileExt();
748 m_log <<
"Loading restart file " << filename.str() <<
" ..." << std::endl;
750 if(m_stgMyRank == m_commStgRoot) {
751 cerr <<
"Loading restart file " << filename.str() <<
" ..." << std::endl;
755 std::stringstream stgPrefix_;
756 stgPrefix_ <<
"stgVar" << m_bcId <<
"_";
757 MString stgPrefix = stgPrefix_.str();
761 ParallelIo parallelIo((filename.str()).c_str(), PIO_READ, m_commStg);
763 parallelIo.getAttribute(&stgMaxNoEddies, (stgPrefix +
"stgMaxNoEddies").c_str());
764 if(stgMaxNoEddies != m_stgMaxNoEddies && !m_stgCreateNewEddies)
765 TERMM(-1,
"bc" + std::to_string(m_bcId) +
": Number of eddies has changed!");
766 ParallelIo::size_type stgEddies_ = parallelIo.getArraySize((stgPrefix +
"FQeddies").c_str());
767 if(stgEddies_ != stgMaxNoEddies * m_stgNoEddieProperties) TERMM(-1,
"");
768 ParallelIo::size_type stgEddyStrength_ = parallelIo.getArraySize((stgPrefix +
"FQeddyStrength").c_str());
769 if(stgEddyStrength_ != stgMaxNoEddies) TERMM(-1,
"");
771 parallelIo.setOffset(stgEddies_, 0);
772 parallelIo.readArray(&(m_stgEddies[0][0]), (stgPrefix +
"FQeddies").c_str());
774 parallelIo.setOffset(stgEddyStrength_, 0);
775 parallelIo.readArray(&(m_stgEddyStrength[0]), (stgPrefix +
"FQeddyStrength").c_str());
787template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
789 if((
globalTimeStep != m_solver->m_restartTimeStep) && !m_solver->m_wasAdapted
790 &&
globalTimeStep % m_solver->m_restartInterval == 0 && m_solver->m_RKStep == 0) {
794 if(m_solver->m_RKStep == 0) {
797 || m_solver->m_wasAdapted)) {
798 readRANSProfileStg();
800 getBoundaryLayerThickness();
801 getInflowStartEnd(m_inflowStart, m_inflowEnd);
802 setVb(m_inflowStart, m_inflowEnd);
805 calcReynoldsStressConvVelLengthScale();
810 calcReynoldsStressConvVelLengthScale();
817 if(!m_solver->m_wasAdapted) {
828 calcTotalFluctuationCholesky();
844template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
845template <
class _, std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
849 std::stringstream errorMsg;
850 std::string prop_name;
851 errorMsg <<
": This property is not allowed to exist without an assignment to a BC" << std::endl;
853 m_stgDelta99Inflow = -1.0;
855 MInt factor = (m_stgWallNormalDir % 2 == 0) ? -1 : 1;
858 prop_name =
"bc" + std::to_string(m_bcId) +
"deltaIn";
860 mTerm(1, AT_,
"deltaIn" + errorMsg.str());
862 m_stgDelta99Inflow = Context::getSolverProperty<MFloat>(prop_name, m_solverId, AT_, &m_stgDelta99Inflow);
865 MFloat maxVelPos = std::numeric_limits<MFloat>::max();
866 MFloat minPos = std::numeric_limits<MFloat>::max();
867 MFloat maxPos = std::numeric_limits<MFloat>::lowest();
868 MFloat halfCellLength = F0;
870 const MInt IBC =
a->getStgId(it);
871 const MInt cellId =
a->getCellId(it);
872 MFloat y = LES->a_coordinate(cellId, m_wallDir);
873 MFloat z = LES->a_coordinate(cellId, m_periodicDir);
875 if(m_stgLVariables[m_stgDir][IBC] >= maxVel) {
876 maxVel = m_stgLVariables[m_stgDir][IBC];
877 if(m_cylinderTransformation) {
880 maxVelPos = m_solver->a_coordinate(cellId, m_wallDir);
883 if(m_cylinderTransformation) {
891 if(m_solver->a_coordinate(cellId, m_wallDir) < minPos) {
892 minPos = m_solver->a_coordinate(cellId, m_wallDir);
893 halfCellLength = m_solver->grid().halfCellLength(cellId);
895 if(m_solver->a_coordinate(cellId, m_wallDir) > maxPos) {
896 maxPos = m_solver->a_coordinate(cellId, m_wallDir);
901 MPI_Allreduce(MPI_IN_PLACE, &maxVel, 1, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
"maxVel",
"1");
902 MPI_Allreduce(MPI_IN_PLACE, &maxVelPos, 1, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"maxVelPos",
"1");
903 MPI_Allreduce(MPI_IN_PLACE, &minPos, 1, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"minPos",
"1");
904 MPI_Allreduce(MPI_IN_PLACE, &maxPos, 1, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
"maxPos",
"1");
906 if(maxVel < 0.9 * m_solver->m_UInfinity) {
907 m_initialRange =
true;
908 m_stgDelta99Inflow = 2 * halfCellLength;
911 if(!m_initialRange) {
912 MFloat delta0 = std::numeric_limits<MFloat>::max();
915 MFloat delta0_u1 = std::numeric_limits<MFloat>::max();
916 MFloat delta0_u2 = std::numeric_limits<MFloat>::lowest();
918 const MInt cellId =
a->getCellId(it);
919 const MInt IBC =
a->getStgId(it);
920 MFloat pos = m_solver->a_coordinate(cellId, m_wallDir);
921 if(m_cylinderTransformation) {
922 MFloat y = LES->a_coordinate(cellId, m_wallDir);
923 MFloat z = LES->a_coordinate(cellId, m_periodicDir);
924 pos = sqrt(
y *
y + z * z);
927 if(m_solver->a_isHalo(cellId))
continue;
929 if(factor * m_stgLVariables[m_stgDir][IBC] > factor * 0.99 * maxVel && pos < delta0_2 && pos < maxVelPos) {
931 delta0_u2 = m_stgLVariables[m_stgDir][IBC];
934 if(factor * m_stgLVariables[m_stgDir][IBC] < factor * 0.99 * maxVel && pos > delta0_1 && pos < maxVelPos) {
936 delta0_u1 = m_stgLVariables[m_stgDir][IBC];
940 MFloat deltaOffset = (factor == 1) ? minPos : maxPos;
943 * (delta0_1 + (delta0_2 - delta0_1) / (delta0_u2 - delta0_u1) * (0.99 * maxVel - delta0_u1) - deltaOffset);
945 if(delta0 < 1e-16) delta0 = std::numeric_limits<MFloat>::max();
947 MPI_Allreduce(&delta0, &m_stgDelta99Inflow, 1, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"m_stgDelta99Inflow",
953 if(m_stgMyRank == m_commStgRoot) {
954 std::cerr <<
"---------- Boundary layer thickness (" <<
globalTimeStep <<
"," << m_bcId <<
"): ----------"
956 std::cerr << m_stgDelta99Inflow << std::endl;
962template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
963template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
965 MInt bndryLayerIndex = 0;
966 MFloat u99_0 = F0, u99_1 = F0;
967 MInt start_[] = {0,
a->start(1) +
a->m_noGhostLayers, 2};
968 MInt end_[] = {1,
a->end(1) -
a->m_noGhostLayers, 3};
971 const MInt IBC =
a->getStgId(it);
972 const MInt IJMK =
a->getNghbrStg(it, 2);
973 if(m_stgLVariables[PV->U][IBC] >= 0.99 * LES->UInfinity()
974 && m_stgLVariables[PV->U][IJMK] < 0.99 * LES->UInfinity()) {
975 u99_0 = m_stgLVariables[PV->U][IJMK];
976 u99_1 = m_stgLVariables[PV->U][IBC];
977 bndryLayerIndex = it->getijk(1) - 1;
981 MFloat bndryLayerThicknessLocal = 0.0;
982 MFloat bndryLayerThicknessGlobal = 0.0;
984 if(bndryLayerIndex > 0) {
985 bndryLayerThicknessLocal = LES->a_coordinate(
a->cellIndex(0, bndryLayerIndex, 2), 1)
986 + (0.99 * LES->UInfinity() - u99_0) / (u99_1 - u99_0)
987 * (LES->a_coordinate(
a->cellIndex(0, bndryLayerIndex + 1, 2), 1)
988 - LES->a_coordinate(
a->cellIndex(0, bndryLayerIndex, 2), 1));
990 MPI_Allreduce(&bndryLayerThicknessLocal, &bndryLayerThicknessGlobal, 1, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
991 "bndryLayerThicknessLocal",
"bndryLayerThicknessGlobal");
992 if(m_stgMyRank == m_commStgRoot) {
993 std::cout <<
"Boundary Layer thickness delta99: " << bndryLayerThicknessGlobal << std::endl;
998template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
999template <
class _, std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
1003 MFloat inflowStartLocal[] = {std::numeric_limits<MFloat>::max(), std::numeric_limits<MFloat>::max(),
1004 std::numeric_limits<MFloat>::max()};
1005 MFloat inflowEndlocal[] = {-std::numeric_limits<MFloat>::max(), -std::numeric_limits<MFloat>::max(),
1006 -std::numeric_limits<MFloat>::max()};
1008 MInt cellId =
a->getCellId(it);
1009 if(m_solver->a_isHalo(cellId))
continue;
1011 if(m_cylinderTransformation) {
1012 MFloat y = LES->a_coordinate(cellId, m_wallDir);
1013 MFloat z = LES->a_coordinate(cellId, m_periodicDir);
1014 MFloat alpha = get_angle(
y, z);
1016 if(inflowStartLocal[0] > LES->a_coordinate(cellId, 0)) inflowStartLocal[0] = LES->a_coordinate(cellId, 0);
1017 if(inflowEndlocal[0] < LES->a_coordinate(cellId, 0)) inflowEndlocal[0] = LES->a_coordinate(cellId, 0);
1018 if(inflowStartLocal[1] > r) inflowStartLocal[1] = r;
1019 if(inflowEndlocal[1] < r) inflowEndlocal[1] = r;
1020 if(inflowStartLocal[2] > alpha) inflowStartLocal[2] = alpha;
1021 if(inflowEndlocal[2] < alpha) inflowEndlocal[2] = alpha;
1024 for(
MInt d = 0; d < nDim; ++d) {
1025 if(inflowStartLocal[d] > LES->a_coordinate(cellId, d)) inflowStartLocal[d] = LES->a_coordinate(cellId, d);
1026 if(inflowEndlocal[d] < LES->a_coordinate(cellId, d)) inflowEndlocal[d] = LES->a_coordinate(cellId, d);
1031 std::fill(inflowStart, inflowStart + nDim, 9999999);
1032 std::fill(inflowEnd, inflowEnd + nDim, -9999999);
1033 MPI_Allreduce(inflowStartLocal, inflowStart, nDim, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"inflowStartLocal",
1035 MPI_Allreduce(inflowEndlocal, inflowEnd, nDim, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
"inflowEndlocal",
"inflowEnd");
1037 if(m_stgWallNormalDir % 2 == 0) {
1038 MFloat temp = inflowStart[m_wallDir];
1039 inflowStart[m_wallDir] = inflowEnd[m_wallDir];
1040 inflowEnd[m_wallDir] = temp;
1044 if(m_stgMyRank == m_commStgRoot) {
1045 std::cerr <<
"inflowStartEnd(" << m_bcId <<
"): " << inflowStart[0] <<
" " << inflowStart[1] <<
" "
1046 << inflowStart[2] <<
" " << inflowEnd[0] <<
" " << inflowEnd[1] <<
" " << inflowEnd[2] << std::endl;
1052template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1053template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
1055 MInt minIndex = getPointIdFromCell(
a->m_noGhostLayers,
a->m_noGhostLayers,
a->m_noGhostLayers);
1057 getPointIdFromCell(
a->m_noGhostLayers,
a->m_noGhostLayers,
a->m_noGhostLayers + m_solver->m_nActiveCells[0]);
1058 MFloat inflowStartLocal[3] = {LES->a_coordinates(minIndex, 0), LES->a_coordinates(minIndex, 1),
1059 LES->a_coordinates(minIndex, 2)};
1060 MFloat inflowEndlocal[3] = {LES->a_coordinates(maxIndex, 0), LES->a_coordinates(maxIndex, 1),
1061 LES->a_coordinates(maxIndex, 2)};
1062 std::fill(inflowStart, inflowStart + nDim, 99999.9);
1063 std::fill(inflowEnd, inflowEnd + nDim, F0);
1064 MPI_Allreduce(inflowStartLocal, inflowStart, nDim, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"inflowStartLocal",
1066 MPI_Allreduce(inflowEndlocal, inflowEnd, nDim, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
"inflowEndlocal",
"inflowEnd");
1070template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1075 const MFloat vbDepth = (inflowEnd[m_periodicDir] - inflowStart[m_periodicDir]) * m_stgBLT3;
1076 const MFloat offset = F1B2 * (inflowEnd[m_periodicDir] - inflowStart[m_periodicDir]) * (m_stgBLT3 - F1);
1078 if(m_stgMyRank == m_commStgRoot) {
1079 m_stgRootRank =
true;
1083 MInt factor = (m_stgFaceNormalDir % 2 == 0) ? 1 : -1;
1084 bcast_vb[m_stgDir] = inflowStart[m_stgDir] - factor * m_stgBLT1 * m_stgDelta99Inflow * F1B2;
1085 bcast_vb[m_stgDir + 3] = inflowStart[m_stgDir] + factor * m_stgBLT1 * m_stgDelta99Inflow * F1B2;
1088 factor = (m_stgWallNormalDir % 2 != 0) ? 1 : -1;
1089 bcast_vb[m_wallDir] = inflowStart[m_wallDir];
1090 bcast_vb[m_wallDir + 3] = inflowStart[m_wallDir] + factor * m_stgBLT2 * m_stgDelta99Inflow;
1092 if(m_freeStreamTurbulence) {
1093 m_stgWallEnd = inflowStart[m_wallDir] + factor * m_stgBLT2 * m_stgDelta99Inflow;
1094 bcast_vb[m_wallDir + 3] = inflowEnd[m_wallDir];
1097 if(m_isotropicTurbulence) {
1098 m_stgWallEnd = inflowStart[m_wallDir];
1099 bcast_vb[m_wallDir + 3] = inflowEnd[m_wallDir];
1103 bcast_vb[m_periodicDir] = inflowStart[m_periodicDir] - offset;
1104 bcast_vb[m_periodicDir + 3] = inflowStart[m_periodicDir] - offset + vbDepth;
1107 MPI_Bcast(bcast_vb.
begin(), 6, MPI_DOUBLE, m_commStgRoot, m_commStg, AT_,
"bcast_vb.begin()");
1109 if(m_freeStreamTurbulence) {
1110 MPI_Bcast(&m_stgWallEnd, 1, MPI_DOUBLE, m_commStgRoot, m_commStg, AT_,
"m_stgWallEnd");
1113 m_stgVbStart[0] = bcast_vb[0];
1114 m_stgVbStart[1] = bcast_vb[1];
1115 m_stgVbStart[2] = bcast_vb[2];
1116 m_stgVbEnd[0] = bcast_vb[3];
1117 m_stgVbEnd[1] = bcast_vb[4];
1118 m_stgVbEnd[2] = bcast_vb[5];
1121 if(m_stgMyRank == m_commStgRoot) {
1122 std::cout <<
"setVbStart(" << m_bcId <<
"): " << m_stgVbStart[0] <<
" " << m_stgVbStart[1] <<
" " << m_stgVbStart[2]
1124 std::cout <<
"setVbEnd(" << m_bcId <<
"): " << m_stgVbEnd[0] <<
" " << m_stgVbEnd[1] <<
" " << m_stgVbEnd[2]
1126 if(m_freeStreamTurbulence) {
1127 std::cout <<
"setVbEndFS(" << m_bcId <<
"): " << m_stgWallEnd << endl;
1137template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1138template <
class _, std::enable_if_t<SolverTypeR == MAIA_FINITE_VOLUME, _*>,
1139 std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
1143 if(m_zonal && !m_preliminary) {
1145 const MInt IBC =
a->getStgId(it);
1146 const MInt cellId =
a->m_stgToCellId[IBC];
1149 for(
MInt varId = 0; varId < (
MInt)m_solver->m_noRANSVariables; varId++) {
1150 ASSERT(cellId < (
MInt)m_solver->m_RANSValues[varId].size(),
1151 "Trying to access data [" + std::to_string(cellId) +
"] in RANSValues with length "
1152 + std::to_string(m_solver->m_RANSValues[varId].size())
1153 +
", domainId: " + std::to_string(m_solver->domainId()));
1156 m_stgLVariables[STG::AVG_RHO][IBC] = m_solver->m_RANSValues[PV->RHO][cellId];
1157 m_stgLVariables[STG::AVG_U][IBC] = m_solver->m_RANSValues[PV->U][cellId];
1158 m_stgLVariables[STG::AVG_V][IBC] = m_solver->m_RANSValues[PV->V][cellId];
1159 m_stgLVariables[STG::AVG_W][IBC] = m_solver->m_RANSValues[PV->W][cellId];
1160 m_stgLVariables[STG::AVG_P][IBC] = m_solver->m_RANSValues[PV->P][cellId];
1162 m_stgLVariables[STG::NU_T][IBC] = m_solver->m_RANSValues[PV->N][cellId];
1164 for(
MInt d = 0; d < m_nDim; d++) {
1165 m_stgLVariables[STG::AVG_UU[d]][IBC] = m_solver->m_RANSValues[PV->VV[d]][cellId];
1171 m_stgLVariables[STG::FLUC_U][IBC] =
1172 m_solver->a_pvariable(cellId, PV->U) - m_solver->m_RANSValues[PV->U][cellId];
1173 m_stgLVariables[STG::FLUC_V][IBC] =
1174 m_solver->a_pvariable(cellId, PV->V) - m_solver->m_RANSValues[PV->V][cellId];
1175 m_stgLVariables[STG::FLUC_W][IBC] =
1176 m_solver->a_pvariable(cellId, PV->W) - m_solver->m_RANSValues[PV->W][cellId];
1181 if(m_preliminaryRans2D) {
1184 MString prop_name =
"bc" + std::to_string(m_bcId);
1185 fn << prop_name <<
"preliminaryDataRans2D.txt";
1187 if(m_stgMyRank == m_commStgRoot) cerr <<
"loading STG preliminary data from " << fname <<
"...";
1189 ifstream preliminaryData;
1190 preliminaryData.open(fname);
1192 vector<MFloat> data;
1196 while(preliminaryData >> num) {
1197 data.push_back(num);
1201 prop_name =
"bc" + std::to_string(m_bcId) +
"preliminaryRansDataCount";
1202 MInt preliminaryDataVarCount =
1203 Context::getSolverProperty<MInt>(prop_name, m_solverId, AT_, &preliminaryDataVarCount);
1205 MInt dataCount = data.size() / preliminaryDataVarCount;
1207 vector<vector<MFloat>> preData(dataCount, vector<MFloat>(preliminaryDataVarCount, 0));
1210 for(
MInt d = 0; d < dataCount; d++) {
1211 for(
MInt dd = 0; dd < preliminaryDataVarCount; dd++) {
1212 index = preliminaryDataVarCount * d + dd;
1213 preData[d][dd] = data[index];
1217 preliminaryData.close();
1220 const MInt IBC =
a->getStgId(it);
1221 const MInt cellId =
a->m_stgToCellId[IBC];
1222 MFloat pos = m_solver->a_coordinate(cellId, m_wallDir);
1224 for(
MInt d = 0; d < dataCount - 1; d++) {
1225 if(pos >= preData[d][0] && pos < preData[d + 1][0]) {
1227 m_stgLVariables[STG::AVG_U][IBC] =
1229 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1231 m_stgLVariables[STG::AVG_V][IBC] =
1233 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1235 m_stgLVariables[STG::AVG_RHO][IBC] =
1237 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1239 m_stgLVariables[STG::AVG_P][IBC] =
1241 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1243 m_stgLVariables[STG::NU_T][IBC] =
1245 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1247 m_stgLVariables[STG::S11][IBC] =
1249 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1251 m_stgLVariables[STG::S12][IBC] =
1253 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1255 m_stgLVariables[STG::S22][IBC] =
1257 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1259 m_stgLVariables[STG::SIJSIJ][IBC] =
1261 + (preData[d + 1][var] - preData[d][var]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1262 m_stgLVariables[STG::AVG_W][IBC] = F0;
1263 m_stgLVariables[STG::S13][IBC] = F0;
1264 m_stgLVariables[STG::S23][IBC] = F0;
1265 m_stgLVariables[STG::S33][IBC] = F0;
1271 if(m_preliminary && !m_preliminaryRans2D) {
1274 MString prop_name =
"bc" + std::to_string(m_bcId);
1275 fn << prop_name <<
"preliminaryData.txt";
1279 if(m_stgMyRank == m_commStgRoot) cerr <<
"loading STG preliminary data from " << fname <<
"...";
1281 ifstream preliminaryData;
1282 preliminaryData.open(fname);
1284 vector<MFloat> data;
1287 while(preliminaryData >> num) {
1288 data.push_back(num);
1292 MInt preliminaryDataVarCount = 1 + m_solver->noVariables() + 8;
1293 MInt dataCount = data.size() / preliminaryDataVarCount;
1295 vector<vector<MFloat>> preData(dataCount, vector<MFloat>(preliminaryDataVarCount, 0));
1298 for(
MInt d = 0; d < dataCount; d++) {
1299 for(
MInt dd = 0; dd < preliminaryDataVarCount; dd++) {
1300 index = preliminaryDataVarCount * d + dd;
1301 preData[d][dd] = data[index];
1305 preliminaryData.close();
1307 if(m_stgMyRank == m_commStgRoot) cerr <<
"ok" << endl;
1310 const MInt IBC =
a->getStgId(it);
1311 const MInt cellId =
a->m_stgToCellId[IBC];
1313 MFloat pos = m_solver->a_coordinate(cellId, m_wallDir);
1314 if(m_cylinderTransformation) {
1315 MFloat y = m_solver->a_coordinate(cellId, m_wallDir);
1316 MFloat z = m_solver->a_coordinate(cellId, m_periodicDir);
1317 pos = sqrt(
y *
y + z * z);
1320 for(
MInt d = 0; d < dataCount; d++) {
1321 if(abs(pos - preData[d][0]) / pos < 0.001) {
1323 for(
MInt var = 0; var < nDim + 2; var++) {
1324 m_stgLVariables[var][IBC] = preData[d][var + 1];
1326 m_stgLVariables[STG::AVG_UU[var]][IBC] = m_stgLVariables[var][IBC];
1330 for(
MInt fluc = STG::FLUC_UU; fluc < STG::FLUC_WW + 1; fluc++) {
1331 m_stgLVariables[fluc][IBC] = preData[d][v];
1334 MInt index_ = preliminaryDataVarCount - 1;
1335 m_stgLVariables[STG::SIJSIJ][IBC] = preData[d][index_];
1337 if(d == dataCount - 1)
continue;
1339 if(pos >= preData[d][0] && pos < preData[d + 1][0]) {
1340 for(
MInt var = 0; var < nDim + 2; var++) {
1341 m_stgLVariables[var][IBC] = preData[d][var + 1]
1342 + (preData[d + 1][var + 1] - preData[d][var + 1]) * (pos - preData[d][0])
1343 / (preData[d + 1][0] - preData[d][0]);
1346 m_stgLVariables[STG::AVG_UU[var]][IBC] = m_stgLVariables[var][IBC];
1350 for(
MInt fluc = STG::FLUC_UU; fluc < STG::FLUC_WW + 1; fluc++) {
1351 m_stgLVariables[fluc][IBC] =
1353 + (preData[d + 1][v] - preData[d][v]) * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1358 MInt index_ = preliminaryDataVarCount - 1;
1359 m_stgLVariables[STG::SIJSIJ][IBC] = preData[d][index_]
1360 + (preData[d + 1][index_] - preData[d][index_])
1361 * (pos - preData[d][0]) / (preData[d + 1][0] - preData[d][0]);
1374template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1375template <
class _, std::enable_if_t<SolverTypeR == MAIA_STRUCTURED, _*>,
1376 std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
1380 if(m_stgInitialStartup) {
1385 std::vector<std::vector<MFloat>> stgCoords(m_nDim);
1386 for(
MInt d = 0; d < m_nDim; ++d)
1387 stgCoords[d].resize(
a->sizeStg());
1391 const MInt stgId =
a->getStgId(it);
1392 const MInt cellId =
a->getCellId(it);
1393 stgCoords[0][stgId] = LES->a_coordinate(cellId, 0);
1394 stgCoords[1][stgId] = LES->a_coordinate(cellId, 1);
1395 stgCoords[2][stgId] = LES->a_coordinate(cellId, 2);
1400 std::vector<MFloat*> stgCoords_ptr(m_nDim);
1401 for(
auto& s_ptr : stgCoords) {
1402 stgCoords_ptr[c++] = s_ptr.data();
1405 MInt temp2[] = {
a->sizeStg(), 1, 1};
1410 structuredInterpolation->prepareInterpolationField(&temp2[0], stgCoords_ptr.data());
1411 std::array<MString, m_nDim + 2> pvariableNames;
1418 pvariableNames[STG::AVG_U] =
"u";
1419 pvariableNames[STG::AVG_V] =
"v";
1420 IF_CONSTEXPR(nDim == 3) { pvariableNames[STG::AVG_W] =
"w"; }
1421 pvariableNames[STG::AVG_P] =
"p";
1422 pvariableNames[STG::AVG_RHO] =
"rho";
1423 const MInt noVars = nDim + 2;
1424 for(
MInt var = 0; var < noVars; var++) {
1426 structuredInterpolation->interpolateField(pvariableNames[var], m_stgLVariables[var]);
1429 structuredInterpolation->interpolateField(
"nu_t", m_stgLVariables[STG::NU_T]);
1433 for(
MInt var = 0; var < noVars; var++) {
1434 MFloat minVar = std::numeric_limits<MFloat>::max();
1435 MFloat maxVar = -std::numeric_limits<MFloat>::max();
1438 const MInt stgId =
a->getStgId(it);
1439 MFloat variable = m_stgLVariables[var][stgId];
1440 if(std::isnan(variable)) TERMM(1,
"NAN");
1441 if(variable > maxVar) maxVar = variable;
1442 if(variable < minVar) minVar = variable;
1446 MPI_Reduce(&minVar, &minVarGlobal, 1, MPI_DOUBLE, MPI_MIN, m_commStgRoot, m_commStg, AT_,
"MPI_IN_PLACE",
1448 MPI_Reduce(&maxVar, &maxVarGlobal, 1, MPI_DOUBLE, MPI_MAX, m_commStgRoot, m_commStg, AT_,
"MPI_IN_PLACE",
1450 if(m_stgMyRank == m_commStgRoot)
1451 std::cout <<
" CHECK after readRANSProfileStg of rank=" << m_solver->domainId() <<
":var=" << var
1452 << std::scientific <<
": minVar=" << minVarGlobal <<
"; maxVar=" << maxVarGlobal <<
"; " << cnt
1461 const MInt IBC =
a->getStgId(it);
1462 for(
int var = 0; var < PV->noVariables; var++) {
1463 LES->a_pvariable(cellId, var) = m_stgLVariables[var][IBC];
1470template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1471template <
class _, std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
1475 if(!m_preliminary) {
1477 const MInt cellId =
a->getCellId(it);
1478 const MInt recData = m_solver->a_reconstructionData(cellId);
1479 MFloat du[nDim][nDim]{{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}};
1480 const MFloat u[nDim] = {m_stgLVariables[STG::AVG_U][
a->getStgId(it)],
1481 m_stgLVariables[STG::AVG_V][
a->getStgId(it)],
1482 m_stgLVariables[STG::AVG_W][
a->getStgId(it)]};
1484 for(
MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
1485 const MInt recNghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
1486 const MInt nghbrStgId =
a->getNghbrMapping(
a->getStgId(it), nghbr);
1488 const MFloat recConst_x = m_solver->m_reconstructionConstants[nDim * (recData + nghbr) + 0];
1489 const MFloat recConst_y = m_solver->m_reconstructionConstants[nDim * (recData + nghbr) + 1];
1490 const MFloat recConst_z = m_solver->m_reconstructionConstants[nDim * (recData + nghbr) + 2];
1493 for(
MInt d = 0; d < nDim; ++d) {
1495 if(recNghbrId > 0 && recNghbrId < m_solver->c_noCells()) {
1496 delta_u = m_solver->m_RANSValues[d][recNghbrId] - u[d];
1499 if(nghbrStgId > 0) delta_u = m_stgLVariables[STG::AVG_UU[d]][nghbrStgId] - u[d];
1501 du[d][0] += recConst_x * delta_u;
1502 du[d][1] += recConst_y * delta_u;
1503 du[d][2] += recConst_z * delta_u;
1506 if(m_solver->m_reConstSVDWeightMode == 3) {
1510 std::array<MBool, nDim> dirsJmp = {};
1511 for(
MInt d = 0; d < nDim; ++d) {
1512 if(m_solver->m_cells.nghbrInterface(cellId, 2 * d) == 3
1513 || m_solver->m_cells.nghbrInterface(cellId, 2 * d + 1) == 3) {
1520 for(
MUint d = 0; d < nDim; ++d) {
1521 for(
MInt dd = 0; dd < nDim; ++dd) {
1528 for(
MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
1529 const MInt nghbrStgId =
a->getNghbrMapping(
a->getStgId(it), nghbr);
1530 const MInt nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
1532 for(
MUint d = 0; d < nDim; ++d) {
1533 MFloat tmp = m_stgLVariables[STG::AVG_UU[d]][nghbrStgId] - u[d];
1534 for(
MInt dd = 0; dd < nDim; ++dd) {
1536 const MFloat dx = LES->a_coordinate(nghbrId, dd) - LES->a_coordinate(cellId, dd);
1537 tmp -= du[d][dd] * dx;
1540 for(
MInt dd = 0; dd < nDim; ++dd) {
1542 du[d][dd] += m_solver->m_reconstructionConstants[nDim * (recData + nghbr) + dd] * tmp;
1549 const MFloat s11 = 2.0 * du[0][0];
1550 const MFloat s22 = 2.0 * du[1][1];
1551 const MFloat s33 = 2.0 * du[2][2];
1553 const MFloat s12 = du[1][0] + du[0][1];
1554 const MFloat s13 = du[2][0] + du[0][2];
1555 const MFloat s23 = du[2][1] + du[1][2];
1564 * (s11 * s11 + s12 * s12 + s13 * s13 + s21 * s21 + s22 * s22 + s23 * s23 + s31 * s31 + s32 * s32 + s33 * s33);
1566 m_stgLVariables[STG::S11][
a->getStgId(it)] = s11;
1567 m_stgLVariables[STG::S22][
a->getStgId(it)] = s22;
1568 m_stgLVariables[STG::S33][
a->getStgId(it)] = s33;
1570 m_stgLVariables[STG::S12][
a->getStgId(it)] = s12;
1571 m_stgLVariables[STG::S13][
a->getStgId(it)] = s13;
1572 m_stgLVariables[STG::S23][
a->getStgId(it)] = s23;
1574 m_stgLVariables[STG::SIJSIJ][
a->getStgId(it)] = SijSij;
1581template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1582template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
1587 for(
MInt k = start[2]+1; k < end[2]-1; k++) {
1588 for(
MInt j = start[1]+1; j < end[1]-1; j++) {
1593 MInt IPJK, IMJK, IJPK, IJMK, IJKP, IJKM;
1595 I = cellIndex(ii,j,k);
1596 IPJK = cellIndex(ii+1,j,k);
1597 IMJK = cellIndex(ii-1,j,k);
1598 IJPK = cellIndex(ii,j+1,k);
1599 IJMK = cellIndex(ii,j-1,k);
1600 IJKP = cellIndex(ii,j,k+1);
1601 IJKM = cellIndex(ii,j,k-1);
1604 const MFloat dxdi = F1B2 * (m_cells->coordinates[0][IPJK] - m_cells->coordinates[0][IMJK]);
1605 const MFloat dxdj = F1B2 * (m_cells->coordinates[0][IJPK] - m_cells->coordinates[0][IJMK]);
1606 const MFloat dxdk = F1B2 * (m_cells->coordinates[0][IJKP] - m_cells->coordinates[0][IJKM]);
1607 const MFloat dydi = F1B2 * (m_cells->coordinates[1][IPJK] - m_cells->coordinates[1][IMJK]);
1608 const MFloat dydj = F1B2 * (m_cells->coordinates[1][IJPK] - m_cells->coordinates[1][IJMK]);
1609 const MFloat dydk = F1B2 * (m_cells->coordinates[1][IJKP] - m_cells->coordinates[1][IJKM]);
1610 const MFloat dzdi = F1B2 * (m_cells->coordinates[2][IPJK] - m_cells->coordinates[2][IMJK]);
1611 const MFloat dzdj = F1B2 * (m_cells->coordinates[2][IJPK] - m_cells->coordinates[2][IJMK]);
1612 const MFloat dzdk = F1B2 * (m_cells->coordinates[2][IJKP] - m_cells->coordinates[2][IJKM]);
1614 const MFloat dxl = sqrt(dxdi*dxdi + dydi*dydi + dzdi*dzdi);
1615 const MFloat dyl = sqrt(dxdj*dxdj + dydj*dydj + dzdj*dzdj);
1616 const MFloat dzl = sqrt(dxdk*dxdk + dydk*dydk + dzdk*dzdk);
1618 const MFloat dxidx = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][0];
1619 const MFloat dxidy = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][1];
1620 const MFloat dxidz = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][2];
1622 const MFloat detadx = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][3 + 0];
1623 const MFloat detady = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][3 + 1];
1624 const MFloat detadz = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][3 + 2];
1626 const MFloat dzetadx = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][6 + 0];
1627 const MFloat dzetady = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][6 + 1];
1628 const MFloat dzetadz = (1./std::max(m_cells->cellJac[I], epss))*m_cells->cellMetrics[I][6 + 2];
1630 IBC = cellIndexBC(ii,j,k);
1631 IPJK = cellIndexBC(ii+1,j,k);
1632 IMJK = cellIndexBC(ii-1,j,k);
1633 IJPK = cellIndexBC(ii,j+1,k);
1634 IJMK = cellIndexBC(ii,j-1,k);
1635 IJKP = cellIndexBC(ii,j,k+1);
1636 IJKM = cellIndexBC(ii,j,k-1);
1638 const MFloat frho = 1.0 / m_stgVariables[STG::AVG_RHO][IBC];
1641 const MFloat dudxi = F1B2*(m_stgVariables[STG::AVG_U][IPJK] - m_stgVariables[STG::AVG_U][IMJK]);
1642 const MFloat dudeta = F1B2*(m_stgVariables[STG::AVG_U][IJPK] - m_stgVariables[STG::AVG_U][IJMK]);
1643 const MFloat dudzeta = F1B2*(m_stgVariables[STG::AVG_U][IJKP] - m_stgVariables[STG::AVG_U][IJKM]);
1646 const MFloat dvdxi = F1B2*(m_stgVariables[STG::AVG_V][IPJK] - m_stgVariables[STG::AVG_V][IMJK]);
1647 const MFloat dvdeta = F1B2*(m_stgVariables[STG::AVG_V][IJPK] - m_stgVariables[STG::AVG_V][IJMK]);
1648 const MFloat dvdzeta = F1B2*(m_stgVariables[STG::AVG_V][IJKP] - m_stgVariables[STG::AVG_V][IJKM]);
1651 const MFloat dwdxi = F1B2*(m_stgVariables[STG::AVG_W][IPJK] - m_stgVariables[STG::AVG_W][IMJK]);
1652 const MFloat dwdeta = F1B2*(m_stgVariables[STG::AVG_W][IJPK] - m_stgVariables[STG::AVG_W][IJMK]);
1653 const MFloat dwdzeta = F1B2*(m_stgVariables[STG::AVG_W][IJKP] - m_stgVariables[STG::AVG_W][IJKM]);
1655 const MFloat dudx = dudxi*dxidx + dudeta*detadx + dudzeta*dzetadx;
1656 const MFloat dudy = dudxi*dxidy + dudeta*detady + dudzeta*dzetady;
1657 const MFloat dudz = dudxi*dxidz + dudeta*detadz + dudzeta*dzetadz;
1659 const MFloat dvdx = dvdxi*dxidx + dvdeta*detadx + dvdzeta*dzetadx;
1660 const MFloat dvdy = dvdxi*dxidy + dvdeta*detady + dvdzeta*dzetady;
1661 const MFloat dvdz = dvdxi*dxidz + dvdeta*detadz + dvdzeta*dzetadz;
1663 const MFloat dwdx = dwdxi*dxidx + dwdeta*detadx + dwdzeta*dzetadx;
1664 const MFloat dwdy = dwdxi*dxidy + dwdeta*detady + dwdzeta*dzetady;
1665 const MFloat dwdz = dwdxi*dxidz + dwdeta*detadz + dwdzeta*dzetadz;
1668 m_stgVariables[STG::S11][cellIndexBC(ii,j,k)] = 2.0*dudx;
1669 m_stgVariables[STG::S22][cellIndexBC(ii,j,k)] = 2.0*dvdy;
1670 m_stgVariables[STG::S33][cellIndexBC(ii,j,k)] = 2.0*dwdz;
1672 m_stgVariables[STG::S12][cellIndexBC(ii,j,k)] = dvdx+dudy;
1673 m_stgVariables[STG::S13][cellIndexBC(ii,j,k)] = dwdx+dudz;
1674 m_stgVariables[STG::S23][cellIndexBC(ii,j,k)] = dwdy+dvdz;
1681template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1686 MPI_Comm_size(m_commStg, &size);
1688 maxValsLocal.
fill(F0);
1689 maxValsGlobal.
fill(F0);
1691 const MFloat fre = 1.0 / m_solver->sysEqn().m_Re0;
1693 const MFloat delta_in = m_stgDelta99Inflow;
1696 MFloat utaumax = F0, umax = F0, vmax = F0, wmax = F0, minLengthLocal = F0;
1699 const MInt id =
a->getStgId(it);
1700 const MInt cellId =
a->getCellId(it);
1702 const MFloat frho = 1.0 / m_stgLVariables[STG::AVG_RHO][
id];
1704 MFloat SijSij = m_stgLVariables[STG::SIJSIJ][
id];
1706 if(!m_preliminary || m_preliminaryRans2D) {
1711 const MFloat s12 = m_stgLVariables[STG::S12][
id];
1712 const MFloat s23 = m_stgLVariables[STG::S23][
id];
1713 const MFloat s13 = m_stgLVariables[STG::S13][
id];
1718 if(m_freeStreamTurbulence) {
1720 MFloat tmp = LES->a_coordinate(cellId, m_wallDir);
1721 if(m_cylinderTransformation) {
1722 MFloat y = LES->a_coordinate(cellId, m_wallDir);
1723 MFloat z = LES->a_coordinate(cellId, m_periodicDir);
1724 tmp = sqrt(
y *
y + z * z);
1726 if(tmp > m_stgWallEnd) {
1727 SijSij_ = m_SijSijFS;
1730 m_stgLVariables[STG::SIJSIJ][
id] = SijSij;
1740 MFloat nu_t = m_stgLVariables[STG::NU_T][
id];
1742 const MFloat sr1 = (s12 + s21) * (s12 + s21);
1743 const MFloat sr2 = (s23 + s32) * (s23 + s32);
1744 const MFloat sr3 = (s13 + s31) * (s13 + s31);
1745 const MFloat srt = std::max(sqrt(sr1 + sr2 + sr3), epsl);
1747 const MFloat rr1 = sqrt(sr1) / srt;
1748 const MFloat rr2 = sqrt(sr2) / srt;
1749 const MFloat rr3 = sqrt(sr3) / srt;
1751 const MFloat uv = -sqrt(2.0 * SijSij) * rr1 * nu_t * fre;
1752 const MFloat vw = -sqrt(2.0 * SijSij) * rr2 * nu_t * fre;
1753 const MFloat uw = -sqrt(2.0 * SijSij) * rr3 * nu_t * fre;
1754 const MFloat uu = a1 * std::abs(uv) * m_stgRSTFactors[0];
1755 const MFloat vv = a1 * std::abs(uv) * m_stgRSTFactors[1];
1756 const MFloat ww = a1 * std::abs(uv) * m_stgRSTFactors[2];
1758 m_stgLVariables[STG::FLUC_UU][
id] = uu;
1759 m_stgLVariables[STG::FLUC_UV][
id] = uv;
1760 m_stgLVariables[STG::FLUC_VV][
id] = vv;
1761 m_stgLVariables[STG::FLUC_WW][
id] = ww;
1762 m_stgLVariables[STG::FLUC_VW][
id] = vw;
1763 m_stgLVariables[STG::FLUC_UW][
id] = uw;
1766 MFloat uv = m_stgLVariables[STG::FLUC_UV][
id];
1767 m_stgLVariables[STG::FLUC_UU][
id] = a1 * std::abs(uv) * m_stgRSTFactors[0];
1768 m_stgLVariables[STG::FLUC_VV][
id] = a1 * std::abs(uv) * m_stgRSTFactors[1];
1769 m_stgLVariables[STG::FLUC_WW][
id] = a1 * std::abs(uv) * m_stgRSTFactors[2];
1770 m_stgLVariables[STG::FLUC_VW][
id] = 0;
1771 m_stgLVariables[STG::FLUC_UW][
id] = 0;
1774 if(m_freeStreamTurbulence) {
1775 m_stgLVariables[STG::FLUC_UU][
id] = m_uuFS;
1776 m_stgLVariables[STG::FLUC_UV][
id] = 0;
1777 m_stgLVariables[STG::FLUC_VV][
id] = m_vvFS;
1778 m_stgLVariables[STG::FLUC_WW][
id] = m_wwFS;
1779 m_stgLVariables[STG::FLUC_VW][
id] = 0;
1780 m_stgLVariables[STG::FLUC_UW][
id] = 0;
1784 MFloat rhoRANSI1 = m_stgLVariables[PV->RHO][
id];
1785 MFloat pressure1 = m_stgLVariables[PV->P][
id];
1787 const MFloat temp = m_solver->m_gamma * pressure1 / rhoRANSI1;
1788 const MFloat xmu = SUTHERLANDLAW(temp);
1791 MFloat utau2_ = sqrt(fre * sqrt(2.0 * SijSij) * xmu * frho);
1793 const MFloat utau2 = utau2_;
1796 const MFloat dV = getCellSize(it);
1799 if(utau2 >= utaumax) {
1800 minLengthLocal = pow(dV, 0.33);
1801 utaumax = std::max(utau2, utaumax);
1806 const MFloat u = m_stgLVariables[STG::AVG_U][
id];
1807 const MFloat v = m_stgLVariables[STG::AVG_V][
id];
1808 const MFloat w = m_stgLVariables[STG::AVG_W][
id];
1811 umax = (fabs(u) > fabs(umax)) ? u : umax;
1812 vmax = (fabs(v) > fabs(vmax)) ? v : vmax;
1813 wmax = (fabs(w) > fabs(wmax)) ? w : wmax;
1816 m_stgLVariables[STG::LENGTH_SCALE][
id] = pow(sqrt(std::max(2.0 * SijSij, epss)), -m_stgExple);
1823 maxValsLocal[0] = umax;
1824 maxValsLocal[1] = vmax;
1825 maxValsLocal[2] = wmax;
1827 if(std::isnan(utaumax) || std::isinf(utaumax)) utaumax = F0;
1831 MFloat minLengthGlobal = 0.0;
1834 "maxValsLocal.begin()",
"maxValsGlobal.begin()");
1835 MPI_Allreduce(&utaumax, &utaux, 1, MPI_DOUBLE, MPI_MAX, m_commStg, AT_,
"utaumax",
"utaux");
1837 MPI_Allreduce(&minLengthLocal, &minLengthGlobal, 1, MPI_DOUBLE, MPI_MIN, m_commStg, AT_,
"minLengthLocal",
1841 std::fill_n(&m_stgMaxVel[0], 3, 0.0);
1842 for(
MInt d = 0; d < size; ++d) {
1843 m_stgMaxVel[0] = (fabs(m_stgMaxVel[0]) > fabs(maxValsGlobal[3 * d])) ? m_stgMaxVel[0] : maxValsGlobal[3 * d];
1845 (fabs(m_stgMaxVel[1]) > fabs(maxValsGlobal[3 * d + 1])) ? m_stgMaxVel[1] : maxValsGlobal[3 * d + 1];
1847 (fabs(m_stgMaxVel[2]) > fabs(maxValsGlobal[3 * d + 2])) ? m_stgMaxVel[2] : maxValsGlobal[3 * d + 2];
1851 if(m_stgMyRank == m_commStgRoot) {
1852 cerr <<
"m_stgMaxVel: " << utaux <<
" " << m_stgMaxVel[0] <<
" " << m_stgMaxVel[1] <<
" " << m_stgMaxVel[2] << endl;
1857 const MInt IBC = it.getStgId();
1860 MFloat maxLength = delta_in;
1863 const MFloat xlength = std::max(
1865 m_stgLengthFactors[0]
1866 * std::max(m_stgLVariables[STG::LENGTH_SCALE][IBC] * delta_in * pow(utaux / delta_in, m_stgExple), eps),
1871 const MFloat ylength = std::max(
1873 m_stgLengthFactors[1]
1874 * std::max(m_stgLVariables[STG::LENGTH_SCALE][IBC] * delta_in * pow(utaux / delta_in, m_stgExple), eps),
1879 const MFloat zlength = std::max(
1881 m_stgLengthFactors[2]
1882 * std::max(m_stgLVariables[STG::LENGTH_SCALE][IBC] * delta_in * pow(utaux / delta_in, m_stgExple), eps),
1886 m_stgLVariables[STG::LENGTH_X][IBC] = xlength;
1887 m_stgLVariables[STG::LENGTH_Y][IBC] = ylength;
1888 m_stgLVariables[STG::LENGTH_Z][IBC] = zlength;
1893template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1894template <
class _, std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
1896 return m_solver->a_cellVolume(
a->getCellId(it));
1900template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1901template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
1903 const MInt IPJK =
a->getNghbr(it, 1);
1904 const MInt IMJK =
a->getNghbr(it, 0);
1905 const MInt IJPK =
a->getNghbr(it, 3);
1906 const MInt IJMK =
a->getNghbr(it, 2);
1907 const MInt IJKP =
a->getNghbr(it, 5);
1908 const MInt IJKM =
a->getNghbr(it, 4);
1910 const MFloat dxdi = F1B2 * (LES->a_coordinate(IPJK, 0) - LES->a_coordinate(IMJK, 0));
1911 const MFloat dxdj = F1B2 * (LES->a_coordinate(IJPK, 0) - LES->a_coordinate(IJMK, 0));
1912 const MFloat dxdk = F1B2 * (LES->a_coordinate(IJKP, 0) - LES->a_coordinate(IJKM, 0));
1913 const MFloat dydi = F1B2 * (LES->a_coordinate(IPJK, 1) - LES->a_coordinate(IMJK, 1));
1914 const MFloat dydj = F1B2 * (LES->a_coordinate(IJPK, 1) - LES->a_coordinate(IJMK, 1));
1915 const MFloat dydk = F1B2 * (LES->a_coordinate(IJKP, 1) - LES->a_coordinate(IJKM, 1));
1916 const MFloat dzdi = F1B2 * (LES->a_coordinate(IPJK, 2) - LES->a_coordinate(IMJK, 2));
1917 const MFloat dzdj = F1B2 * (LES->a_coordinate(IJPK, 2) - LES->a_coordinate(IJMK, 2));
1918 const MFloat dzdk = F1B2 * (LES->a_coordinate(IJKP, 2) - LES->a_coordinate(IJKM, 2));
1920 const MFloat dxl = sqrt(dxdi * dxdi + dydi * dydi + dzdi * dzdi);
1921 const MFloat dyl = sqrt(dxdj * dxdj + dydj * dydj + dzdj * dzdj);
1922 const MFloat dzl = sqrt(dxdk * dxdk + dydk * dydk + dzdk * dzdk);
1924 return dxl * dyl * dzl;
1928template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1930 xk[m_stgDir] = m_stgVbStart[m_stgDir] + generate_rand() * (m_stgVbEnd[m_stgDir] - m_stgVbStart[m_stgDir]);
1932 m_stgVbStart[m_periodicDir] + generate_rand() * (m_stgVbEnd[m_periodicDir] - m_stgVbStart[m_periodicDir]);
1934 m_stgVbStart[m_wallDir] + generate_rand_weighted() * (m_stgVbEnd[m_wallDir] - m_stgVbStart[m_wallDir]);
1936 if(m_isotropicTurbulence) {
1937 xk[m_wallDir] = m_stgVbStart[m_wallDir] + generate_rand() * (m_stgVbEnd[m_wallDir] - m_stgVbStart[m_wallDir]);
1940 if(m_cylinderTransformation) {
1941 xk[m_wallDir] = m_stgVbStart[m_wallDir] + generate_rand() * (m_stgVbEnd[m_wallDir] - m_stgVbStart[m_wallDir]);
1944 if(m_freeStreamTurbulence) {
1945 if(generate_rand() < m_BLEddieFraction) {
1947 xk[m_wallDir] = m_stgVbStart[m_wallDir] + generate_rand_weighted() * (m_stgWallEnd - m_stgVbStart[m_wallDir]);
1950 xk[m_wallDir] = m_stgWallEnd + generate_rand() * (m_stgVbEnd[m_wallDir] - m_stgWallEnd);
1954 epsi[m_stgDir] = 2.0 * generate_rand() - 1.0;
1955 epsi[m_stgDir] = epsi[m_stgDir] / std::max(std::abs(epsi[m_stgDir]), eps);
1956 epsi[m_wallDir] = 2.0 * generate_rand() - 1.0;
1957 epsi[m_wallDir] = epsi[m_wallDir] / std::max(std::abs(epsi[m_wallDir]), eps);
1958 epsi[m_periodicDir] = 2.0 * generate_rand() - 1.0;
1959 epsi[m_periodicDir] = epsi[m_periodicDir] / std::max(std::abs(epsi[m_periodicDir]), eps);
1963template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
1966 MFloatScratchSpace eddyBcastBuffer(m_stgMaxNoEddies * m_stgNoEddieProperties, AT_,
"eddyBcastBuffer");
1967 eddyBcastBuffer.
fill(F0);
1970 eddyBcastStrength.
fill(F0);
1975 if(m_stgMyRank == m_commStgRoot) {
1976 for(
MInt n = 0; n < m_stgMaxNoEddies; n++) {
1977 xk[0] = m_stgEddies[n][0];
1978 xk[1] = m_stgEddies[n][1];
1979 xk[2] = m_stgEddies[n][2];
1981 eddyBcastStrength[n] = m_stgEddyStrength[n];
1984 if(xk[0] > m_stgVbEnd[0] || xk[0] < m_stgVbStart[0] || xk[1] > m_stgVbEnd[1] || xk[1] < m_stgVbStart[1]
1985 || xk[2] > m_stgVbEnd[2] || xk[2] < m_stgVbStart[2]) {
1986 generateNewEddies(xk, epsi);
1988 eddyBcastStrength[n] = F1;
1989 if(m_newStgMethod) {
1990 eddyBcastStrength[n] = generate_rand_normalDist();
1994 xk[0] = m_stgMaxVel[0] * m_solver->m_timeStep + m_stgEddies[n][0];
1995 xk[1] = m_stgMaxVel[1] * m_solver->m_timeStep + m_stgEddies[n][1];
1996 xk[2] = m_stgMaxVel[2] * m_solver->m_timeStep + m_stgEddies[n][2];
1998 epsi[0] = m_stgEddies[n][3];
1999 epsi[1] = m_stgEddies[n][4];
2000 epsi[2] = m_stgEddies[n][5];
2003 eddyBcastBuffer[n + m_stgMaxNoEddies * 0] = xk[0];
2004 eddyBcastBuffer[n + m_stgMaxNoEddies * 1] = xk[1];
2005 eddyBcastBuffer[n + m_stgMaxNoEddies * 2] = xk[2];
2006 eddyBcastBuffer[n + m_stgMaxNoEddies * 3] = epsi[0];
2007 eddyBcastBuffer[n + m_stgMaxNoEddies * 4] = epsi[1];
2008 eddyBcastBuffer[n + m_stgMaxNoEddies * 5] = epsi[2];
2013 MPI_Bcast(eddyBcastBuffer.
begin(), m_stgMaxNoEddies * m_stgNoEddieProperties, MPI_DOUBLE, m_commStgRoot, m_commStg,
2014 AT_,
"eddyBcastBuffer.begin()");
2016 MPI_Bcast(eddyBcastStrength.
begin(), m_stgMaxNoEddies, MPI_DOUBLE, m_commStgRoot, m_commStg, AT_,
2017 "eddyBcastStrength.begin()");
2020 for(
MInt n = 0; n < m_stgMaxNoEddies; n++) {
2021 for(
MInt p = 0; p < m_stgNoEddieProperties; p++) {
2022 m_stgEddies[n][p] = eddyBcastBuffer[n + m_stgMaxNoEddies * p];
2024 m_stgEddyStrength[n] = eddyBcastStrength[n];
2028template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2030 const MFloat BLT3 = std::abs(m_stgVbEnd[m_periodicDir] - m_stgVbStart[m_periodicDir]);
2031 const MFloat Vb = m_stgBLT2 * BLT3 * m_stgBLT1 *
POW2(m_stgDelta99Inflow);
2034 if(m_stgMyRank == m_commStgRoot &&
globalTimeStep == m_solver->m_restartTimeStep) {
2035 std::cout <<
"**************************" << std::endl
2036 <<
"Synthetic turbulence (bcId=" << m_bcId <<
"):" << std::endl
2037 <<
"zones: 1" << std::endl
2038 <<
"Dir: " << m_stgFaceNormalDir <<
" / " << m_stgWallNormalDir <<
" / " << m_stgDir <<
" / " << m_wallDir
2040 <<
"nr. eddies: " << m_stgMaxNoEddies << std::endl
2041 <<
"conv. vel: " << sqrt(
POW2(m_stgMaxVel[0]) +
POW2(m_stgMaxVel[1]) +
POW2(m_stgMaxVel[2])) << std::endl
2042 <<
"umax = " << m_stgMaxVel[0] << std::endl
2043 <<
"vmax = " << m_stgMaxVel[1] << std::endl
2044 <<
"wmax = " << m_stgMaxVel[2] << std::endl
2045 <<
"virtual box volume: " << Vb << std::endl
2046 <<
"Vb/stgMaxNoEddies = " << Vb / m_stgMaxNoEddies << std::endl
2047 <<
"**************************" << std::endl;
2052template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2056 const MFloat BLT3 = std::abs(m_stgVbEnd[m_periodicDir] - m_stgVbStart[m_periodicDir]);
2057 MFloat Vb = m_stgBLT1 * m_stgBLT2 *
POW2(m_stgDelta99Inflow) * BLT3;
2058 if(m_freeStreamTurbulence || m_isotropicTurbulence) {
2059 const MFloat BLT2 = std::abs(m_stgVbEnd[m_wallDir] - m_stgVbStart[m_wallDir]);
2060 Vb = m_stgBLT1 * m_stgDelta99Inflow * BLT2 * BLT3;
2063 const MFloat vbFactor = sqrt(Vb / m_stgMaxNoEddies);
2065 const MFloat umax = m_stgMaxVel[0];
2066 const MFloat vmax = m_stgMaxVel[1];
2067 const MFloat wmax = m_stgMaxVel[2];
2070 const MInt cellIdBC =
a->getStgId(it);
2071 const MInt cellIdBCFirst = cellIdBC;
2072 const MInt cellId =
a->getCellId(it);
2074 MFloat help1 = F0, help2 = F0, help3 = F0, help4 = F0, help5 = F0, help6 = F0;
2076 const MFloat uu = m_stgLVariables[STG::FLUC_UU][cellIdBCFirst];
2077 const MFloat vv = m_stgLVariables[STG::FLUC_VV][cellIdBCFirst];
2078 const MFloat ww = m_stgLVariables[STG::FLUC_WW][cellIdBCFirst];
2079 const MFloat uv = m_stgLVariables[STG::FLUC_UV][cellIdBCFirst];
2080 const MFloat vw = m_stgLVariables[STG::FLUC_VW][cellIdBCFirst];
2081 const MFloat uw = m_stgLVariables[STG::FLUC_UW][cellIdBCFirst];
2084 const MFloat a11 = sqrt(std::max(uu, epsl));
2085 const MFloat a21 = uv / a11;
2086 const MFloat a31 = uw / a11;
2087 const MFloat a22 = sqrt(std::max((vv - a21 * a21), epsl));
2088 const MFloat a32 = (vw - a21 * a31) / a22;
2089 const MFloat a33 = sqrt(std::max((ww - a31 * a31 - a32 * a32), epsl));
2091 for(
MInt n = 0; n < m_stgMaxNoEddies; n++) {
2094 const MFloat xk1t = m_stgEddies[n][0];
2095 const MFloat xk2t = m_stgEddies[n][1];
2096 const MFloat xk3t = m_stgEddies[n][2];
2098 MFloat distX = LES->a_coordinate(cellId, 0) - xk1t;
2099 MFloat distY = LES->a_coordinate(cellId, 1) - xk2t;
2100 MFloat distZ = LES->a_coordinate(cellId, 2) - xk3t;
2102 if(m_cylinderTransformation) {
2103 MFloat y = LES->a_coordinate(cellId, m_wallDir);
2104 MFloat z = LES->a_coordinate(cellId, m_periodicDir);
2106 MFloat alpha = get_angle(
y, z);
2108 distZ = std::fmod(r * (alpha - xk3t), 2 * r * PI);
2112 const MFloat xLb1 = m_stgLVariables[STG::LENGTH_X][cellIdBCFirst] * m_stgEddyStrength[n];
2113 const MFloat xLb2 = m_stgLVariables[STG::LENGTH_Y][cellIdBCFirst] * m_stgEddyStrength[n];
2114 const MFloat xLb3 = m_stgLVariables[STG::LENGTH_Z][cellIdBCFirst] * m_stgEddyStrength[n];
2117 const MFloat fxLb1 = 1.0 / xLb1;
2118 const MFloat fxLb2 = 1.0 / xLb2;
2119 const MFloat fxLb3 = 1.0 / xLb3;
2121 const MFloat fsqrtxLb1 = 1.0 / sqrt(xLb1);
2122 const MFloat fsqrtxLb2 = 1.0 / sqrt(xLb2);
2123 const MFloat fsqrtxLb3 = 1.0 / sqrt(xLb3);
2125 const MFloat fsqrtPixLb1 = 1.0 / sqrt(3.141 * xLb1);
2126 const MFloat fsqrtPixLb2 = 1.0 / sqrt(3.141 * xLb2);
2127 const MFloat fsqrtPixLb3 = 1.0 / sqrt(3.141 * xLb3);
2129 const MFloat aDistX = fabs(distX);
2130 const MFloat aDistY = fabs(distY);
2131 const MFloat aDistZ = fabs(distZ);
2135 if(aDistX < 4.0 * xLb1 && aDistY < 4.0 * xLb2 && aDistZ < 4.0 * xLb3) {
2136 const MFloat zacfq1 = distX / aDistX;
2137 const MFloat rol1H = zacfq1 * std::min(aDistX * fxLb1, 1.0);
2139 const MFloat zacfq2 = distY / aDistY;
2140 const MFloat rol2H = zacfq2 * std::min(aDistY * fxLb2, 1.0);
2142 const MFloat zacfq3 = distZ / aDistZ;
2143 const MFloat rol3H = zacfq3 * std::min(aDistZ * fxLb3, 1.0);
2145 const MFloat fl1 = 2.0 * fsqrtPixLb1 * exp(-((distX)*2 * fxLb1) * ((distX)*2 * fxLb1));
2146 const MFloat fl2 = 2.0 * fsqrtPixLb2 * exp(-((distY)*2 * fxLb2) * ((distY)*2 * fxLb2));
2147 const MFloat fl3 = 2.0 * fsqrtPixLb3 * exp(-((distZ)*2 * fxLb3) * ((distZ)*2 * fxLb3));
2150 MFloat fH1 = (F1 - cos(2.0 * 3.141 * rol1H)) / (2.0 * 3.141 * rol1H * 0.44);
2151 MFloat fH2 = (F1 - cos(2.0 * 3.141 * rol2H)) / (2.0 * 3.141 * rol2H * 0.44);
2152 MFloat fH3 = (F1 - cos(2.0 * 3.141 * rol3H)) / (2.0 * 3.141 * rol3H * 0.44);
2154 fH1 = aniso * fH1 * fsqrtxLb1 + fabs(aniso - 1.0) * fl1;
2155 fH2 = aniso * fH2 * fsqrtxLb2 + fabs(aniso - 1.0) * fl2;
2156 fH3 = aniso * fH3 * fsqrtxLb3 + fabs(aniso - 1.0) * fl3;
2158 const MFloat epsik1 = m_stgEddies[n][3];
2159 const MFloat epsik2 = m_stgEddies[n][4];
2160 const MFloat epsik3 = m_stgEddies[n][5];
2162 help4 += vbFactor * epsik1 * fl1 * fl2 * fH3;
2163 help5 += vbFactor * epsik2 * fl1 * fl2 * fH3;
2164 help6 += vbFactor * epsik3 * fl1 * fH2 * fl3;
2178 help1 = help4 * a11;
2179 help2 = help4 * a21 + help5 * a22;
2180 help3 = help4 * a31 + help5 * a32 + help6 * a33;
2182 const MFloat velmax = sqrt(umax * umax + vmax * vmax + wmax * wmax);
2184 MFloat ufluc = std::min(std::max(help1, -0.3 * velmax), 0.3 * velmax);
2185 MFloat vfluc = std::min(std::max(help2, -0.3 * velmax), 0.3 * velmax);
2186 MFloat wfluc = std::min(std::max(help3, -0.3 * velmax), 0.3 * velmax);
2188 if(m_cylinderTransformation) {
2189 MFloat y = m_solver->a_coordinate(cellId, m_wallDir);
2190 MFloat z = m_solver->a_coordinate(cellId, m_periodicDir);
2191 MFloat alpha = get_angle(
y, z);
2194 vfluc = vtemp * cos(alpha) + wtemp * sin(alpha);
2195 wfluc = vtemp * sin(alpha) - wtemp * cos(alpha);
2198 m_stgLVariables[STG::FLUC_U][cellIdBC] += timsm * (ufluc - m_stgLVariables[STG::FLUC_U][cellIdBC]);
2199 m_stgLVariables[STG::FLUC_V][cellIdBC] += timsm * (vfluc - m_stgLVariables[STG::FLUC_V][cellIdBC]);
2200 m_stgLVariables[STG::FLUC_W][cellIdBC] += timsm * (wfluc - m_stgLVariables[STG::FLUC_W][cellIdBC]);
2205template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2210 const MInt IBC =
a->getStgId(it);
2212 m_stgEddieCoverage[1][IBC] = F0;
2215 std::vector<MFloat> eddieCoverage(m_stgGlobalNoWallNormalLocations, F0);
2217 for(
MInt i = 0; i < m_stgGlobalNoWallNormalLocations; i++) {
2218 for(
MInt p = 0; p < (
MInt)m_stgPeriodicCellId[i].size(); p++) {
2219 MInt id = m_stgPeriodicCellId[i][p];
2220 eddieCoverage[i] += m_stgEddieCoverage[0][
id] / m_stgGlobalNoPeriodicLocations[i];
2224 MPI_Allreduce(MPI_IN_PLACE, &eddieCoverage[0], m_stgGlobalNoWallNormalLocations, MPI_DOUBLE, MPI_SUM, m_commStg, AT_,
2225 "MPI_IN_PLACE",
"m_LESPeriodicAverage");
2228 const MInt IBC =
a->getStgId(it);
2229 const MInt cellId =
a->getCellId(it);
2231 MFloat index = m_stgPeriodicIndex[IBC];
2232 m_stgEddieCoverage[1][IBC] = eddieCoverage[index];
2234 m_solver->m_stgEddieCoverage[1][cellId] = m_stgEddieCoverage[1][IBC];
2235 m_solver->m_stgEddieCoverage[2][cellId] = m_stgEddieCoverage[1][IBC] - m_stgEddieCoverage[0][IBC];
2240template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2241template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
2243 const MInt noSTGVariables = STG::noSTGVars - PV->noVariables;
2245 const MInt k = it.getijk(2);
2246 if(k ==
a->start(2) + 1) {
2248 for(
MInt var = PV->noVariables; var < noSTGVariables; ++var) {
2249 m_stgLVariables[var][it.getNghbrStg(4)] = m_stgLVariables[var][it.
getStgId()];
2251 }
else if(k ==
a->end(2) -
a->m_noGhostLayers) {
2253 for(
MInt var = PV->noVariables; var < noSTGVariables; ++var) {
2254 m_stgLVariables[var][it.getNghbrStg(5)] = m_stgLVariables[var][it.
getStgId()];
2258 const MInt j = it.getijk(1);
2259 if(j ==
a->start(1) + 1) {
2260 for(
MInt var = PV->noVariables; var < noSTGVariables; ++var) {
2261 m_stgLVariables[var][it.getNghbrStg(2)] = m_stgLVariables[var][it.
getStgId()];
2263 }
else if(j ==
a->end(1) -
a->m_noGhostLayers) {
2264 for(
MInt var = PV->noVariables; var < noSTGVariables; ++var) {
2265 m_stgLVariables[var][it.getNghbrStg(3)] = m_stgLVariables[var][it.
getStgId()];
2271template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2272template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
2274 const MInt cellIdG1 =
a->getCellId(it);
2275 const MInt cellIdA1 =
a->getNghbr(it, 1);
2276 const MInt cellIdG2 =
a->getNghbr(it, 0);
2279 for(
MInt var = 0; var < PV->noVariables; var++) {
2280 LES->a_pvariable(cellIdG2, var) = F2 * LES->a_pvariable(cellIdG1, var) - LES->a_pvariable(cellIdA1, var);
2285template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2286template <
class _, std::enable_if_t<SolverTypeL == MAIA_FINITE_VOLUME, _*>>
2290 const MFloat gamma = m_solver->m_gamma;
2291 const MFloat gammaMinusOne = gamma - 1.0;
2293 if(m_initialRange || globalTimeStep < m_solver->m_stgStartTimeStep) {
2295 const MInt cellIdG1 =
a->getCellId(it);
2296 const MInt IBC =
a->getStgId(it);
2299 LES->a_pvariable(cellIdG1, PV->RHO) = m_stgLVariables[STG::AVG_RHO][IBC];
2300 LES->a_pvariable(cellIdG1, PV->U) = m_stgLVariables[STG::AVG_U][IBC];
2301 LES->a_pvariable(cellIdG1, PV->V) = m_stgLVariables[STG::AVG_V][IBC];
2302 LES->a_pvariable(cellIdG1, PV->W) = m_stgLVariables[STG::AVG_W][IBC];
2304 const MInt ghostCellId =
a->getGhostIdFromStgId(IBC);
2306 LES->a_pvariable(ghostCellId, PV->RHO) =
2307 2.0 * m_stgLVariables[STG::AVG_RHO][IBC] - LES->a_pvariable(cellIdG1, PV->RHO);
2309 LES->a_pvariable(ghostCellId, PV->U) =
2310 2.0 * m_stgLVariables[STG::AVG_U][IBC] - LES->a_pvariable(cellIdG1, PV->U);
2311 LES->a_pvariable(ghostCellId, PV->V) =
2312 2.0 * m_stgLVariables[STG::AVG_V][IBC] - LES->a_pvariable(cellIdG1, PV->V);
2313 LES->a_pvariable(ghostCellId, PV->W) =
2314 2.0 * m_stgLVariables[STG::AVG_W][IBC] - LES->a_pvariable(cellIdG1, PV->W);
2316 LES->a_pvariable(ghostCellId, PV->P) =
2317 2.0 * m_stgLVariables[STG::AVG_P][IBC] - LES->a_pvariable(cellIdG1, PV->P);
2323 const MInt cellIdG1 =
a->getCellId(it);
2324 const MInt IBC =
a->getStgId(it);
2326 const MInt cellIdA1 = cellIdG1;
2336 MFloat gradxi = -F1 / sqrt(dxidx * dxidx + dxidy * dxidy + dxidz * dxidz);
2338 MFloat dxHelp = dxidx * gradxi;
2339 MFloat dyHelp = dxidy * gradxi;
2340 MFloat dzHelp = dxidz * gradxi;
2343 const MFloat rhoBC = LES->a_pvariable(cellIdG1, PV->RHO);
2344 const MFloat pBC = LES->a_pvariable(cellIdG1, PV->P);
2345 const MFloat fRhoBC = F1 / rhoBC;
2346 const MFloat aBC = sqrt(gamma * pBC * fRhoBC);
2347 const MFloat uBC = LES->a_pvariable(cellIdG1, PV->U);
2348 const MFloat vBC = LES->a_pvariable(cellIdG1, PV->V);
2349 const MFloat wBC = LES->a_pvariable(cellIdG1, PV->W);
2351 const MFloat maBC = (dxHelp * uBC + dyHelp * vBC + dzHelp * wBC) / aBC;
2357 const MFloat rhoRANS = m_stgLVariables[STG::AVG_RHO][IBC];
2358 const MFloat uRANS = m_stgLVariables[STG::AVG_U][IBC];
2359 const MFloat vRANS = m_stgLVariables[STG::AVG_V][IBC];
2360 const MFloat wRANS = m_stgLVariables[STG::AVG_W][IBC];
2361 const MFloat pRANS = m_stgLVariables[STG::AVG_P][IBC];
2364 const MFloat u_prime = m_stgLVariables[STG::FLUC_U][IBC];
2365 const MFloat v_prime = m_stgLVariables[STG::FLUC_V][IBC];
2366 const MFloat w_prime = m_stgLVariables[STG::FLUC_W][IBC];
2369 const MFloat uSTG = std::max(uRANS + u_prime, epsl);
2370 const MFloat vSTG = vRANS + v_prime;
2371 const MFloat wSTG = wRANS + w_prime;
2374 const MFloat u9a = LES->UInfinity();
2375 const MFloat u9ff = u_prime;
2376 const MFloat alok = sqrt(gamma * LES->PInfinity() / LES->rhoInfinity());
2378 u9ff / u9a *
POW2((LES->UInfinity() / alok)) * gammaMinusOne * m_stgLVariables[STG::AVG_RHO][IBC];
2379 const MFloat zdir = flucc / std::max(fabs(flucc), 0.0000001);
2380 const MFloat rhoSTG = rhoRANS + zdir * std::min(fabs(flucc), 0.1 * rhoRANS);
2383 const MFloat pField = LES->a_pvariable(cellIdA1, PV->P);
2384 const MFloat rhoField = LES->a_pvariable(cellIdA1, PV->RHO);
2385 const MFloat uField = LES->a_pvariable(cellIdA1, PV->U);
2386 const MFloat vField = LES->a_pvariable(cellIdA1, PV->V);
2387 const MFloat wField = LES->a_pvariable(cellIdA1, PV->W);
2388 const MFloat aField = sqrt(gamma * pField / rhoField);
2396 + rhoField * aField * (+dxHelp * (uField - uSTG) + dyHelp * (vField - vSTG) + dzHelp * (wField - wSTG)));
2397 const MFloat rhoSub = rhoSTG + (pSub - pRANS) / (
POW2(aField));
2398 const MFloat rhoSubHelp = (pSub - pRANS) / (rhoField * aField);
2401 const MFloat uSub = uSTG + dxHelp * rhoSubHelp;
2402 const MFloat vSub = vSTG + dyHelp * rhoSubHelp;
2403 const MFloat wSub = wSTG + dzHelp * rhoSubHelp;
2408 const MFloat rhoSup = rhoSTG;
2409 const MFloat uSup = uSTG;
2410 const MFloat vSup = vSTG;
2411 const MFloat wSup = wSTG;
2412 const MFloat pSup = pRANS;
2425 const MFloat maBCAbs = fabs(maBC);
2426 const MFloat alpha = 14.0;
2428 const MFloat count = alpha * (maBCAbs -
b);
2429 const MFloat denom = (F1 - 0.99 *
b) * maBCAbs +
b;
2430 const MFloat ratio = count / denom;
2431 const MFloat wfun = F1B2 * (F1 + tanh(ratio) / tanh(alpha));
2433 xSub = fabs(wfun - F1);
2435 }
else if(m_stgSupersonic) {
2440 const MFloat rho_target = rhoSub * xSub + rhoSup * xSup;
2441 const MFloat u_target = uSub * xSub + uSup * xSup;
2442 const MFloat v_target = vSub * xSub + vSup * xSup;
2443 const MFloat w_target = wSub * xSub + wSup * xSup;
2444 const MFloat p_target = pSub * xSub + pSup * xSup;
2447 LES->a_pvariable(cellIdG1, PV->RHO) = rho_target;
2448 LES->a_pvariable(cellIdG1, PV->U) = u_target;
2449 LES->a_pvariable(cellIdG1, PV->V) = v_target;
2450 LES->a_pvariable(cellIdG1, PV->W) = w_target;
2452 const MInt ghostCellId =
a->getGhostIdFromStgId(IBC);
2453 LES->a_pvariable(ghostCellId, PV->RHO) = 2.0 * rho_target - LES->a_pvariable(cellIdG1, PV->RHO);
2454 LES->a_pvariable(ghostCellId, PV->U) = 2.0 * u_target - LES->a_pvariable(cellIdG1, PV->U);
2455 LES->a_pvariable(ghostCellId, PV->V) = 2.0 * v_target - LES->a_pvariable(cellIdG1, PV->V);
2456 LES->a_pvariable(ghostCellId, PV->W) = 2.0 * w_target - LES->a_pvariable(cellIdG1, PV->W);
2457 LES->a_pvariable(ghostCellId, PV->P) = 2.0 * p_target - LES->a_pvariable(cellIdG1, PV->P);
2464template <MInt nDim, SolverType SolverTypeR, SolverType SolverTypeL>
2465template <
class _, std::enable_if_t<SolverTypeL == MAIA_STRUCTURED, _*>>
2467 const MFloat gamma = m_solver->m_gamma;
2468 const MFloat gammaMinusOne = gamma - 1.0;
2471 const MInt cellIdG1 =
a->getCellId(it);
2472 const MInt IBC =
a->getStgId(it);
2473 const MInt cellIdA1 =
a->getNghbr(it, 1);
2476 MFloat dxidx = m_solver->m_cells->cellMetrics[cellIdA1][0];
2477 MFloat dxidy = m_solver->m_cells->cellMetrics[cellIdA1][1];
2478 MFloat dxidz = m_solver->m_cells->cellMetrics[cellIdA1][2];
2480 MFloat gradxi = -F1 / sqrt(dxidx * dxidx + dxidy * dxidy + dxidz * dxidz);
2482 MFloat dxHelp = dxidx * gradxi;
2483 MFloat dyHelp = dxidy * gradxi;
2484 MFloat dzHelp = dxidz * gradxi;
2487 const MFloat rhoBC = LES->a_pvariable(cellIdG1, PV->RHO);
2488 const MFloat pBC = LES->a_pvariable(cellIdG1, PV->P);
2489 const MFloat fRhoBC = F1 / rhoBC;
2490 const MFloat aBC = sqrt(gamma * pBC * fRhoBC);
2491 const MFloat uBC = LES->a_pvariable(cellIdG1, PV->U);
2492 const MFloat vBC = LES->a_pvariable(cellIdG1, PV->V);
2493 const MFloat wBC = LES->a_pvariable(cellIdG1, PV->W);
2495 const MFloat maBC = (dxHelp * uBC + dyHelp * vBC + dzHelp * wBC) / aBC;
2501 const MFloat rhoRANS = m_stgLVariables[STG::AVG_RHO][IBC];
2502 const MFloat uRANS = m_stgLVariables[STG::AVG_U][IBC];
2503 const MFloat vRANS = m_stgLVariables[STG::AVG_V][IBC];
2504 const MFloat wRANS = m_stgLVariables[STG::AVG_W][IBC];
2505 const MFloat pRANS = m_stgLVariables[STG::AVG_P][IBC];
2508 const MFloat u_prime = m_stgLVariables[STG::FLUC_U][IBC];
2509 const MFloat v_prime = m_stgLVariables[STG::FLUC_V][IBC];
2510 const MFloat w_prime = m_stgLVariables[STG::FLUC_W][IBC];
2513 const MFloat uSTG = std::max(uRANS + u_prime, epsl);
2514 const MFloat vSTG = vRANS + v_prime;
2515 const MFloat wSTG = wRANS + w_prime;
2518 const MFloat u9a = LES->UInfinity();
2519 const MFloat u9ff = u_prime;
2520 const MFloat alok = sqrt(gamma * LES->PInfinity() / LES->rhoInfinity());
2522 u9ff / u9a *
POW2((LES->UInfinity() / alok)) * gammaMinusOne * m_stgLVariables[STG::AVG_RHO][IBC];
2523 const MFloat zdir = flucc / std::max(fabs(flucc), 0.0000001);
2524 const MFloat rhoSTG = rhoRANS + zdir * std::min(fabs(flucc), 0.1 * rhoRANS);
2527 const MFloat pField = LES->a_pvariable(cellIdA1, PV->P);
2528 const MFloat rhoField = LES->a_pvariable(cellIdA1, PV->RHO);
2529 const MFloat uField = LES->a_pvariable(cellIdA1, PV->U);
2530 const MFloat vField = LES->a_pvariable(cellIdA1, PV->V);
2531 const MFloat wField = LES->a_pvariable(cellIdA1, PV->W);
2532 const MFloat aField = sqrt(gamma * pField / rhoField);
2540 + rhoField * aField * (+dxHelp * (uField - uSTG) + dyHelp * (vField - vSTG) + dzHelp * (wField - wSTG)));
2541 const MFloat rhoSub = rhoSTG + (pSub - pRANS) / (
POW2(aField));
2542 const MFloat rhoSubHelp = (pSub - pRANS) / (rhoField * aField);
2545 const MFloat uSub = uSTG + dxHelp * rhoSubHelp;
2546 const MFloat vSub = vSTG + dyHelp * rhoSubHelp;
2547 const MFloat wSub = wSTG + dzHelp * rhoSubHelp;
2552 const MFloat rhoSup = rhoSTG;
2553 const MFloat uSup = uSTG;
2554 const MFloat vSup = vSTG;
2555 const MFloat wSup = wSTG;
2556 const MFloat pSup = pRANS;
2569 const MFloat maBCAbs = fabs(maBC);
2570 const MFloat alpha = 14.0;
2572 const MFloat count = alpha * (maBCAbs -
b);
2573 const MFloat denom = (F1 - 0.99 *
b) * maBCAbs +
b;
2574 const MFloat ratio = count / denom;
2575 const MFloat wfun = F1B2 * (F1 + tanh(ratio) / tanh(alpha));
2577 xSub = fabs(wfun - F1);
2579 }
else if(m_stgSupersonic) {
2584 LES->a_pvariable(cellIdG1, PV->RHO) = rhoSub * xSub + rhoSup * xSup;
2585 LES->a_pvariable(cellIdG1, PV->U) = uSub * xSub + uSup * xSup;
2586 LES->a_pvariable(cellIdG1, PV->V) = vSub * xSub + vSup * xSup;
2587 LES->a_pvariable(cellIdG1, PV->W) = wSub * xSub + wSup * xSup;
2588 LES->a_pvariable(cellIdG1, PV->P) = pSub * xSub + pSup * xSup;
2594 extrapolateToGX(it);
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void getInflowStartEnd(MFloat *, MFloat *)
MFloat ** m_stgEddieCoverage
MFloat getCellSize(typename Accessor::nDim_citerator it)
void setVb(MFloat *, MFloat *)
void extrapolateToGX(typename Accessor::nDim_citerator)
void calcTotalFluctuationCholesky()
void bc7909()
Reformulated Synthetic Turbulence Generation Synthetic Turbulence Generation Method Computes fluctuat...
MFloat ** m_stgLVariables
void calcReynoldsStressConvVelLengthScale()
MFloat generate_rand_normalDist()
MFloat get_angle(MFloat y, MFloat z)
MFloat generate_rand_weighted()
void getBoundaryLayerThickness()
void determinePeriodicCells()
friend void saveStg(std::map< MInt, self * >, SolverTypeL_ *)
MSTG(FvCartesianSolverXD< nDim, FvSysEqnNS< nDim > > *solver, MInt bcId, const MPI_Comm commStg, MInt *sortedBndryCellIds, MInt noStgLCells, MInt stgFaceNormalDir, MInt stgDir, MInt stgWallNormalDir, MInt wallDir, MBool cutOff)
void readRANSProfileStg()
write RANSValues from solver to stgLVariables (fully coupled) /author Jannik Borgelt
void generateNewEddies(MFloat *, MFloat *)
void init(MInt commStgRoot)
void extrapolateToBoundary(typename Accessor::nDim_citerator)
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
value_type getStgId() const
typename base_iterator::value_type value_type
value_type getCellId() const
value_type getNghbr(MInt dir) const
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW2(const Real x)
@ HasCoarseNghbr
cell has a coarse nghbr (only set for cells with IsNotGradient==false)
void saveStg(std::map< MInt, MSTG< nDim, SolverTypeR, SolverTypeL > * > stgBC, typename SolverTraits< nDim, SolverTypeL >::SolverType *solver)
std::basic_string< char > MString
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_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_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather
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
PARALLELIO_DEFAULT_BACKEND ParallelIo
static constexpr const MInt noStgVars