23template <MInt nDim,
class SysEqn>
37template <MInt nDim,
class SysEqn>
42 m_fvSolverId = fvMbSolver().m_solverId;
43 m_lsSolverId = lsSolver().m_solverId;
45 if(lsSolver().m_closeGaps) {
46 mAlloc(m_hadGapCells, lsSolver().m_noGapRegions,
"m_hadGapCells", 0, AT_);
47 mAlloc(m_hasGapCells, lsSolver().m_noGapRegions,
"m_hasGapCells", 0, AT_);
51 for(
MInt set = 0; set < lsSolver().m_noSets; set++) {
52 const MInt levelDif = fvMbSolver().m_lsCutCellLevel[set] - lsSolver().a_maxGCellLevel(set);
53 m_noRfJumps =
mMax(m_noRfJumps, levelDif);
56 const MInt maxlevelDif = fvMbSolver().maxRefinementLevel() - lsSolver().maxRefinementLevel();
57 m_noRfJumps =
mMax(m_noRfJumps, maxlevelDif);
59 if(lsSolver().m_maxLevelChange) m_noRfJumps = 0;
61 m_log <<
" Ls - FvMb Coupler detected " << m_noRfJumps <<
" level-jumps" << endl;
64 fvMbSolver().m_maxLsValue = lsSolver().m_outsideGValue;
66 if(fvMbSolver().m_levelSetRans) {
67 mAlloc(fvMbSolver().m_levelSetValues, lsSolver().m_noSets,
"fvMbSolver().m_levelSetValues", AT_);
74template <MInt nDim,
class SysEqn>
78 ASSERT(lsSolver().m_noEmbeddedBodies == fvMbSolver().m_noEmbeddedBodies,
"");
79 ASSERT(lsSolver().m_constructGField == fvMbSolver().m_constructGField,
"");
80 ASSERT(lsSolver().m_noGapRegions == fvMbSolver().m_noGapRegions,
"");
82 if(!m_allowLsInterpolation) {
83 ASSERT(lsSolver().a_maxGCellLevel(0) == fvMbSolver().maxRefinementLevel() || lsSolver().m_maxLevelChange,
"");
84 ASSERT(m_noRfJumps == 0,
85 to_string(lsSolver().a_maxGCellLevel(0)) +
" " + to_string(fvMbSolver().maxRefinementLevel()));
87 ASSERT(m_noRfJumps > 0,
"");
88 if(lsSolver().domainId() == 0) {
89 cerr <<
"Allowing ls interpolation with " << m_noRfJumps <<
" level jumps!" << endl;
91 ASSERT(lsSolver().m_gShadowWidth <= fvMbSolver().m_bandWidth[fvMbSolver().maxRefinementLevel() - 1],
"");
94 if(!lsSolver().m_maxLevelChange) {
95 ASSERT(lsSolver().a_maxGCellLevel(0) == fvMbSolver().m_lsCutCellBaseLevel,
"");
98 ASSERT(lsSolver().m_closeGaps == fvMbSolver().m_closeGaps,
"");
99 ASSERT(lsSolver().m_noBodiesInSet == fvMbSolver().m_noBodiesInSet,
"");
100 ASSERT(lsSolver().m_bodyToSetTable == fvMbSolver().m_bodyToSetTable,
"");
101 ASSERT(lsSolver().m_setToBodiesTable == fvMbSolver().m_setToBodiesTable,
"");
102 ASSERT(lsSolver().m_startSet == fvMbSolver().m_startSet,
"");
103 ASSERT(lsSolver().m_maxNoSets == fvMbSolver().m_noLevelSetsUsedForMb,
"");
104 ASSERT(lsSolver().m_noSets == fvMbSolver().m_noSets,
"");
107 if(fvMbSolver().isActive()) {
109 ASSERT(fvMbSolver().a_noCells(),
"");
114 ASSERT(lsSolver().m_engineSetup == fvMbSolver().m_engineSetup,
"");
115 if(lsSolver().m_engineSetup && lsSolver().isActive() && fvMbSolver().isActive()) {
116 ASSERT(fabs(lsSolver().crankAngle(lsSolver().m_time, 0) - fvMbSolver().crankAngle(fvMbSolver().m_physicalTime, 0))
117 < fvMbSolver().m_eps,
126template <MInt nDim,
class SysEqn>
144 m_outsideDefault =
true;
146 m_outsideDefault = Context::getSolverProperty<MBool>(
"outsideDefault", m_fvSolverId, AT_, &m_outsideDefault);
162 m_allowLsInterpolation =
false;
163 m_allowLsInterpolation =
164 Context::getSolverProperty<MBool>(
"allowLsInterpolation", m_fvSolverId, AT_, &m_allowLsInterpolation);
172template <MInt nDim,
class SysEqn>
176 if(fvMbSolver().m_constructGField)
return;
178 for(
MInt fc = 0; fc < a_noFvGridCells(); fc++) {
179 ASSERT(fvMbSolver().grid().tree().solver2grid(fc) >= 0,
"");
180 ASSERT(fvMbSolver().grid().solverFlag(fvMbSolver().grid().tree().solver2grid(fc), m_fvSolverId),
"");
181#ifdef COUPLING_DEBUG_
182 if(lsSolver().grid().solverFlag(fvMbSolver().grid().tree().solver2grid(fc), m_lsSolverId)) {
183 ASSERT(ls2fvId(fv2lsId(fc)) == fc,
184 to_string(fc) +
" " + to_string(fv2lsId(fc)) +
" " + to_string(ls2fvId(fv2lsId(fc))));
188 for(
MInt cellId = 0; cellId < a_noLsCells(); cellId++) {
189 ASSERT(lsSolver().grid().tree().solver2grid(cellId) >= 0,
"");
190 ASSERT(lsSolver().grid().solverFlag(lsSolver().grid().tree().solver2grid(cellId), m_lsSolverId),
"");
191#ifdef COUPLING_DEBUG_
192 if(fvMbSolver().grid().solverFlag(lsSolver().grid().tree().solver2grid(cellId), m_fvSolverId)) {
193 ASSERT(fv2lsId(ls2fvId(cellId)) == cellId,
194 to_string(cellId) +
" " + to_string(ls2fvId(cellId)) +
" " + to_string(fv2lsId(ls2fvId(cellId))));
199 if(!lsSolver().m_levelSetMb)
return;
202#ifdef COUPLING_DEBUG_
203 for(
MInt fc = 0; fc < a_noFvGridCells(); fc++) {
204 for(
MInt dir = 0; dir < nDim; dir++) {
205 if(lsSolver().grid().solverFlag(fvMbSolver().grid().tree().solver2grid(fc), m_lsSolverId)) {
206 ASSERT(abs(fvMbSolver().c_coordinate(fc, dir) - lsSolver().c_coordinate(fv2lsId(fc), dir)) < 0.00000001,
"");
217template <MInt nDim,
class SysEqn>
221 if(fvMbSolver().m_constructGField)
return;
223 if(!fvMbSolver().m_levelSetMb)
return;
225#ifdef COUPLING_DEBUG_
226 for(
MInt fc = 0; fc < a_noFvGridCells(); fc++) {
227 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
228 if(lsSolver().grid().solverFlag(fvMbSolver().grid().tree().solver2grid(fc), m_lsSolverId)) {
229 ASSERT(abs(a_levelSetFunctionG(fv2lsId(fc), set) - fvMbSolver().a_levelSetValuesMb(fc, set)) < 0.00000001,
"");
240template <MInt nDim,
class SysEqn>
244 if(!lsSolver().m_closeGaps)
return;
245 if(lsSolver().m_levelSetMb && fvMbSolver().m_constructGField)
return;
247#ifdef COUPLING_DEBUG_
248 for(
MInt fc = 0; fc < a_noFvGridCells(); fc++) {
249 if(fvMbSolver().a_isGapCell(fc) || fvMbSolver().a_wasGapCell(fc)) {
250 MInt gc = lsSolver().grid().tree().grid2solver(fvMbSolver().grid().tree().solver2grid(fc));
252 ASSERT(lsSolver().a_potentialGapCellClose(gc) > 0
253 && lsSolver().a_potentialGapCellClose(gc) <= fvMbSolver().m_noEmbeddedBodies,
264template <MInt nDim,
class SysEqn>
268 for(
MInt s = 0; s < lsSolver().m_noSets; s++) {
269 fvMbSolver().m_levelSetValues[s].resize(fvMbSolver().a_noCells());
272 for(
MInt s = 0; s < lsSolver().m_noSets; s++) {
273 for(
MInt fc = 0; fc < a_noFvCells(); fc++) {
274 MInt lsId = fv2lsIdParent(fc);
275 fvMbSolver().a_levelSetFunction(fc, s) = a_outsideGValue();
280 MFloat point[3] = {fvMbSolver().a_coordinate(fc, 0), fvMbSolver().a_coordinate(fc, 1),
281 fvMbSolver().a_coordinate(fc, 2)};
282 fvMbSolver().a_levelSetFunction(fc, s) = interpolateLevelSet(lsId, point, s);
284 fvMbSolver().a_levelSetFunction(fc, s) = lsSolver().a_levelSetFunctionG(fv2lsIdParent(fc), s);
296template <MInt nDim,
class SysEqn>
300 if(!fvMbSolver().isActive())
return;
308#ifdef COUPLING_DEBUG_
312 std::map<MInt, MInt> interpolationParents;
313 interpolationParents.clear();
316 if(lsSolver().isActive()) {
318#pragma omp parallel for
320 for(
MInt cellId = 0; cellId < a_noFvCells(); cellId++) {
322 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
323 if(m_outsideDefault) {
324 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_outsideGValue();
326 fvMbSolver().a_levelSetValuesMb(cellId, set) = -a_outsideGValue();
328 fvMbSolver().a_associatedBodyIds(cellId, set) = -1;
330 const MInt gCellId = fv2lsId(cellId);
333 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
334 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellId, set);
335 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellId, set);
341 ASSERT(cellId >= a_noFvGridCells(),
"");
343 if(cellId <= a_noFvGridCells()) {
344 const MInt gCellParent = fv2lsIdParent(cellId);
346 if(gCellParent > -1) {
348 if(m_noRfJumps == 0) {
350 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
351 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
353 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellParent, set);
357 ASSERT(m_allowLsInterpolation,
"");
358 if(fvMbSolver().a_isHalo(cellId) || lsSolver().a_isHalo(gCellParent))
continue;
361 if(lsSolver().m_buildCollectedLevelSetFunction && !lsSolver().a_inBandG(gCellParent, 0)
362 && lsSolver().a_level(gCellParent) <= lsSolver().a_maxGCellLevel(0)) {
363 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
364 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
365 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellParent, set);
370 const MInt levelDifference = fvMbSolver().c_level(cellId) - lsSolver().a_level(gCellParent);
371 if(levelDifference == 1) {
373 MFloat point[3] = {fvMbSolver().c_coordinate(cellId, 0), fvMbSolver().c_coordinate(cellId, 1),
374 fvMbSolver().c_coordinate(cellId, 2)};
375 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
376 MInt position = lsSolver().setUpLevelSetInterpolationStencil(gCellParent, interpolationCells, point);
379 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
380 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
383 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellParent, set);
385 const MFloat phi = lsSolver().interpolateLevelSet(interpolationCells, point, set);
386 fvMbSolver().a_levelSetValuesMb(cellId, set) = phi;
390 buildCollectedLevelSet(cellId);
395 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
396 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
399 MInt parent = cellId;
400 for(
MInt i = 0; i < levelDifference - 1; i++) {
401 parent = fvMbSolver().c_parentId(parent);
403 ASSERT(parent > -1,
"");
406 ASSERT(fv2lsId(fvMbSolver().c_parentId(parent)) == gCellParent,
"");
407 interpolationParents.insert(make_pair(parent, fvMbSolver().a_level(parent)));
418#pragma omp parallel for collapse(2)
420 for(
MInt cellId = 0; cellId < a_noFvCells(); cellId++) {
421 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
422 if(m_outsideDefault) {
423 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_outsideGValue();
425 fvMbSolver().a_levelSetValuesMb(cellId, set) = -a_outsideGValue();
427 fvMbSolver().a_associatedBodyIds(cellId, set) = -1;
434 if(m_allowLsInterpolation) {
435 std::list<MInt> newInterpolationParents;
437 for(
MInt lvl = lsSolver().maxUniformRefinementLevel() + 1; lvl < fvMbSolver().maxRefinementLevel(); lvl++) {
438 fvMbSolver().exchangeLevelSetData();
440 MInt noInterpolationCells = (
MInt)interpolationParents.size();
441 MPI_Allreduce(MPI_IN_PLACE, &noInterpolationCells, 1, MPI_INT, MPI_MAX, fvMbSolver().mpiComm(), AT_,
"INPLACE",
442 "noInterpolationCells");
443 if(noInterpolationCells == 0)
break;
445 if(interpolationParents.empty())
continue;
447 ASSERT(m_noRfJumps > 1,
"");
449 newInterpolationParents.clear();
451 for(
auto it = interpolationParents.begin(); it != interpolationParents.end(); it++) {
452 const MInt parent = it->first;
453 const MInt level = it->second;
455 newInterpolationParents.push_back(parent);
457 for(
MInt c = 0; c < fvMbSolver().grid().m_maxNoChilds; c++) {
458 const MInt childId = fvMbSolver().c_childId(parent, c);
462 interpolateLsFV(parent, childId);
463 if(!fvMbSolver().c_isLeafCell(childId)) {
464 newInterpolationParents.push_back(childId);
469 interpolationParents.clear();
470 for(
auto it = newInterpolationParents.begin(); it != newInterpolationParents.end(); it++) {
471 const MInt cellId = (*it);
472 interpolationParents.insert(make_pair(cellId, fvMbSolver().a_level(cellId)));
477 if(exchangeLVS) fvMbSolver().exchangeLevelSetData();
479 for(
MUint sc = 0; sc < fvMbSolver().m_splitCells.size(); sc++) {
480 const MInt cellId = fvMbSolver().m_splitCells[sc];
481 for(
MUint ssc = 0; ssc < fvMbSolver().m_splitChilds[sc].size(); ssc++) {
482 const MInt splitChildId = fvMbSolver().m_splitChilds[sc][ssc];
483 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
484 fvMbSolver().a_associatedBodyIds(splitChildId, set) = fvMbSolver().a_associatedBodyIds(cellId, set);
485 fvMbSolver().a_levelSetValuesMb(splitChildId, set) = fvMbSolver().a_levelSetValuesMb(cellId, set);
498template <MInt nDim,
class SysEqn>
502 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
503 MFloat point[3] = {fvMbSolver().c_coordinate(to, 0), fvMbSolver().c_coordinate(to, 1),
504 fvMbSolver().c_coordinate(to, 2)};
506 std::function<
MBool(
const MInt,
const MInt)> alwaysTrue = [&](
const MInt,
const MInt) {
return true; };
508 MBool backup = fvMbSolver().m_deleteNeighbour;
509 fvMbSolver().m_deleteNeighbour =
false;
510 const MInt position = fvMbSolver().setUpInterpolationStencil(from, interpolationCells, point, alwaysTrue,
false);
511 fvMbSolver().m_deleteNeighbour = backup;
513 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
515 fvMbSolver().a_levelSetValuesMb(to, set) = fvMbSolver().a_levelSetValuesMb(from, set);
517 MFloat phi = interpolateLevelSetMb(interpolationCells, point, set);
518 fvMbSolver().a_levelSetValuesMb(to, set) = phi;
521 buildCollectedLevelSet(to);
527template <MInt nDim,
class SysEqn>
529 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
532 position = lsSolver().setUpLevelSetInterpolationStencil(cellId, interpolationCells, point);
536 return lsSolver().interpolateLevelSet(interpolationCells, point, set);
538 return lsSolver().a_levelSetFunctionG(cellId, set);
545template <MInt nDim,
class SysEqn>
550 return static_cast<MFloat>(fvMbSolver().a_levelSetValuesMb(cellId, refSet));
554 return static_cast<MFloat>(fvMbSolver().c_coordinate(cellId,
id));
557 return fvMbSolver().template interpolateFieldData<true>(&interpolationCells[0], &point[0], set, scalarField,
568template <MInt nDim,
class SysEqn>
579 if(!lsSolver().m_closeGaps)
return;
580 if(lsSolver().m_noGapRegions <= 0)
return;
581 if(lsSolver().m_levelSetMb && fvMbSolver().m_constructGField)
return;
583#ifdef COUPLING_DEBUG_
588 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
589 m_hadGapCells[region] = 0;
590 m_hasGapCells[region] = 0;
594 for(
MInt fc = 0; fc < fvMbSolver().noInternalCells(); fc++) {
595 if(fvMbSolver().a_isGapCell(fc)) {
596 MInt lsId = fv2lsId(fc);
598 if(fc > fvMbSolver().c_noCells())
continue;
599 lsId = fv2lsIdParent(fc);
601 ASSERT(lsId > -1,
"");
603 if(lsSolver().m_G0regionId > -1 && a_potentialGapCellClose(lsId) == lsSolver().m_G0regionId)
continue;
604 MInt regionId = a_potentialGapCellClose(lsId) - 2;
605 ASSERT(a_potentialGapCellClose(lsId) > 0 && a_potentialGapCellClose(lsId) <= lsSolver().m_noEmbeddedBodies,
"");
606 if(regionId > -1 && regionId < lsSolver().m_noGapRegions &&
globalTimeStep > 0) {
609 m_hadGapCells[regionId]++;
613 fvMbSolver().a_wasGapCell(fc) = fvMbSolver().a_isGapCell(fc);
615 fvMbSolver().a_wasGapCell(fc) =
false;
617 fvMbSolver().a_isGapCell(fc) =
false;
621 for(
MInt fc = a_noFvGridCells(); fc < fvMbSolver().noInternalCells(); fc++) {
623 fvMbSolver().a_wasGapCell(fc) = fvMbSolver().a_isGapCell(fc);
625 fvMbSolver().a_wasGapCell(fc) =
false;
627 fvMbSolver().a_isGapCell(fc) =
false;
631 if(lsSolver().isActive()) {
632 for(
MInt gCellId = 0; gCellId < lsSolver().a_noCells(); gCellId++) {
633 if(a_nearGapG(gCellId)) {
634 const MInt fvId = ls2fvId(gCellId);
636 ASSERT(abs(abs(a_levelSetFunctionG(gCellId, 0)) - a_outsideGValue()) < 0.000001,
637 "ERROR, no fv-Cell found for relevant Gap-Cells!");
639 if(a_potentialGapCellClose(gCellId) > 0 && a_potentialGapCellClose(gCellId) <= lsSolver().m_noEmbeddedBodies) {
640 if(fvMbSolver().c_isLeafCell(fvId)) {
641 fvMbSolver().a_isGapCell(fvId) =
true;
642 const MInt regionId = a_potentialGapCellClose(gCellId) - 2;
643 if(regionId > -1 && regionId < lsSolver().m_noGapRegions) {
644 m_hasGapCells[regionId]++;
646 }
else if(!fvMbSolver().c_isLeafCell(fvId) && !fvMbSolver().a_isHalo(fvId) && !lsSolver().a_isHalo(gCellId)) {
647 ASSERT((m_allowLsInterpolation && m_noRfJumps == 1) || fvMbSolver().m_maxLevelChange,
"");
650 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
651 const MInt child = fvMbSolver().c_childId(fvId, childId);
652 if(child < 0)
continue;
653 fvMbSolver().a_isGapCell(child) =
true;
654 const MInt regionId = a_potentialGapCellClose(gCellId) - 2;
655 if(regionId > -1 && regionId < lsSolver().m_noGapRegions) {
656 m_hasGapCells[regionId]++;
668 if(lsSolver().m_G0regionId > -1) {
669 MInt noG0regionCells = 0;
670 for(
MInt gCellId = 0; gCellId < lsSolver().a_noCells(); gCellId++) {
671 if(lsSolver().a_potentialGapCellClose(gCellId) == lsSolver().m_G0regionId && lsSolver().a_gapWidth(gCellId) > 0) {
672 MInt fvId = ls2fvId(gCellId);
674 ASSERT(abs(abs(a_levelSetFunctionG(gCellId, 0)) - a_outsideGValue()) < 0.000001,
675 "ERROR, no fv-Cell found for relevant Gap-Cells!");
678 fvMbSolver().a_isGapCell(fvId) =
true;
679 ASSERT(!lsSolver().a_nearGapG(gCellId),
"");
682#if defined COUPLING_DEBUG_ || !defined NDEBUG
683 MPI_Allreduce(MPI_IN_PLACE, &noG0regionCells, 1, MPI_INT, MPI_SUM, lsSolver().mpiComm(), AT_,
"INPLACE",
685 if(lsSolver().domainId() == 0) {
686 cerr <<
" No of g0-region Cells " << noG0regionCells << endl;
693 if(lsSolver().m_restart &&
globalTimeStep == fvMbSolver().m_restartTimeStep) {
694 for(
MInt fc = a_noFvGridCells(); fc < a_noFvCells(); fc++) {
695 fvMbSolver().a_wasGapCell(fc) = fvMbSolver().a_isGapCell(fc);
697 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
698 m_hadGapCells[region] = m_hasGapCells[region];
703 MPI_Allreduce(MPI_IN_PLACE, &m_hadGapCells[0], lsSolver().m_noGapRegions, MPI_INT, MPI_SUM, fvMbSolver().mpiComm(),
704 AT_,
"INPLACE",
"m_hadGapCells");
706 MPI_Allreduce(MPI_IN_PLACE, &m_hasGapCells[0], lsSolver().m_noGapRegions, MPI_INT, MPI_SUM, fvMbSolver().mpiComm(),
707 AT_,
"INPLACE",
"m_hasGapCells");
709 fvMbSolver().exchangeGapInfo();
711#if defined COUPLING_DEBUG_ || !defined NDEBUG
712 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
713 if(lsSolver().domainId() == 0) {
714 cerr <<
globalTimeStep <<
" region " << region <<
" has " << m_hasGapCells[region] <<
" had "
715 << m_hadGapCells[region] << endl;
735template <MInt nDim,
class SysEqn>
740 lsSolver().computeBodyPropertiesForced(returnMode, &bodyData[0], body, time);
747template <MInt nDim,
class SysEqn>
751 if(fvMbSolver().m_constructGField)
return;
753 fvMbSolver().m_structureStep = 0;
755 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
756 fvMbSolver().m_gapState[region] = 0;
759 MBool& firstRun = m_static_updateLevelSetFlowSolver_firstRun;
762 || (fvMbSolver().m_trackMovingBndry &&
globalTimeStep >= fvMbSolver().m_trackMbStart
767 if(fvMbSolver().m_levelSetRans) {
768 transferLevelSetValues();
770 transferGapCellProperty(1);
773 transferLevelSetFieldValues(
true);
782 transferBodyProperties();
801template <MInt nDim,
class SysEqn>
805 if(!lsSolver().m_closeGaps || lsSolver().m_gapInitMethod == 0)
return;
807 MBool(&earlyOpened)[m_maxNoGapRegions] = m_static_setGapState_earlyOpened;
808 MBool& first = m_static_setGapState_first;
812 for(
MInt region = 0; region < m_maxNoGapRegions; region++) {
813 earlyOpened[region] =
false;
818 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
819 forceNoGaps[region] =
false;
820 if(lsSolver().m_forceNoGaps > 0) {
821 const MFloat cad = lsSolver().crankAngle(lsSolver().m_time, 0);
822 if(lsSolver().m_forceNoGaps == 1
823 && ((lsSolver().m_gapSign[region] > F0 && cad > lsSolver().m_gapAngleOpen[region]
824 && cad < lsSolver().m_gapAngleClose[region])
825 || (lsSolver().m_gapSign[region] < F0
826 && (cad > lsSolver().m_gapAngleOpen[region] || cad < lsSolver().m_gapAngleClose[region])))) {
827 forceNoGaps[region] =
true;
828 }
else if(lsSolver().m_forceNoGaps == 2
829 && ((cad > lsSolver().m_gapAngleOpen[region] && cad < lsSolver().m_gapAngleClose[region])
830 || (cad > lsSolver().m_gapAngleOpen[region + 1] && cad < lsSolver().m_gapAngleClose[region + 1]))) {
831 forceNoGaps[region] =
true;
836 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
837 if(forceNoGaps[region]) {
839 fvMbSolver().m_gapState[region] = 2;
840 earlyOpened[region] =
true;
841 if(fvMbSolver().domainId() == 0) {
842 cerr <<
"--> Ls Gap Forced Opening Initialized for region " << region <<
" at timestep " <<
globalTimeStep
847 fvMbSolver().m_gapState[region] = 1;
848 earlyOpened[region] =
true;
849 if(fvMbSolver().domainId() == 0) {
850 cerr <<
"--> Ls Gap Forced open for region " << region <<
" at timestep " <<
globalTimeStep << endl;
854 if(!forceNoGaps[region] && earlyOpened[region]) {
855 lsSolver().m_minGapWidthDt1[region] = 11 * lsSolver().m_outsideGValue;
856 earlyOpened[region] =
false;
860 for(
MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
861 if(forceNoGaps[region])
continue;
863 if(earlyOpened[region]) {
865 lsSolver().c_cellLengthAtLevel(lsSolver().a_maxGCellLevel(0)) * sqrt(nDim) * lsSolver().m_gapDeltaMin;
866 MFloat deviation = (fabs(lsSolver().m_minGapWidth[region] - eps2) / eps2) * 100;
867 if(fvMbSolver().domainId() == 0) {
868 cerr <<
"--> Ls Gap is Open early for region " << region <<
" at timestep " <<
globalTimeStep
869 <<
" with deviation " << deviation << endl;
871 fvMbSolver().m_gapState[region] = 1;
872 ASSERT(!m_hasGapCells[region] && !m_hadGapCells[region],
"");
873 if(lsSolver().m_minGapWidthDt1[region] < lsSolver().m_minGapWidth[region]
874 && lsSolver().m_minGapWidth[region] > (10 * lsSolver().m_outsideGValue)) {
875 earlyOpened[region] =
false;
880 if(lsSolver().m_minGapWidthDt1[region] > (10 * lsSolver().m_outsideGValue)
881 && lsSolver().m_minGapWidth[region] < lsSolver().m_minGapWidthDt1[region]) {
882 if(fvMbSolver().domainId() == 0) {
883 cerr <<
"--> Ls Gap Closure Initialized for region " << region <<
" at timestep " <<
globalTimeStep <<
" "
886 ASSERT(m_hasGapCells[region] && !m_hadGapCells[region],
887 to_string(m_hasGapCells[region]) +
" " + to_string(m_hadGapCells[region]));
889 fvMbSolver().m_gapState[region] = -2;
891 }
else if(lsSolver().m_minGapWidthDt1[region] < lsSolver().m_minGapWidth[region]
892 && lsSolver().m_minGapWidth[region] > (10 * lsSolver().m_outsideGValue)) {
893 if(fvMbSolver().domainId() == 0) {
894 cerr <<
"--> Ls Gap Opening Initialized for region " << region <<
" at timestep " <<
globalTimeStep << endl;
896 fvMbSolver().m_gapState[region] = 2;
897 ASSERT(m_hadGapCells[region] && !m_hasGapCells[region],
"");
899 }
else if(lsSolver().m_minGapWidth[region] < (10 * lsSolver().m_outsideGValue)
900 && lsSolver().m_minGapWidthDt1[region] < (10 * lsSolver().m_outsideGValue)) {
901 if(lsSolver().m_minGapWidthDt1[region] >= lsSolver().m_minGapWidth[region]) {
903 if(fvMbSolver().domainId() == 0) {
904 cerr <<
"--> Ls Gap is Shrinking for region " << region <<
" at timestep " <<
globalTimeStep << endl;
906 fvMbSolver().m_gapState[region] = -1;
907 ASSERT(m_hasGapCells[region] && m_hadGapCells[region],
908 to_string(m_hasGapCells[region]) +
" " + to_string(m_hadGapCells[region]));
912 lsSolver().c_cellLengthAtLevel(lsSolver().a_maxGCellLevel(0)) * sqrt(nDim) * lsSolver().m_gapDeltaMin;
913 MFloat deviation = (fabs(lsSolver().m_minGapWidth[region] - eps2) / eps2) * 100;
916 if(deviation < 1.0) {
917 if(m_hasGapCells[region] == 0 && m_hadGapCells[region] > 0) {
918 if(fvMbSolver().domainId() == 0) {
919 cerr <<
"--> Ls Gap Opening Initialized early for region " << region <<
" at timestep " <<
globalTimeStep
920 <<
" with deviation " << deviation << endl;
922 fvMbSolver().m_gapState[region] = 2;
923 ASSERT(m_hadGapCells[region] && !m_hasGapCells[region],
"");
924 earlyOpened[region] =
true;
929 if(fvMbSolver().domainId() == 0) {
930 cerr <<
"--> Ls Gap is Widening for region " << region <<
" at timestep " <<
globalTimeStep << endl;
932 fvMbSolver().m_gapState[region] = 3;
933 ASSERT(lsSolver().m_minGapWidthDt1[region] < lsSolver().m_minGapWidth[region],
"");
934 ASSERT(m_hasGapCells[region] && m_hadGapCells[region],
935 to_string(m_hasGapCells[region]) +
" " + to_string(m_hadGapCells[region]));
938 }
else if(lsSolver().m_minGapWidthDt1[region] > (10 * lsSolver().m_outsideGValue)
939 && lsSolver().m_minGapWidth[region] > (10 * lsSolver().m_outsideGValue)) {
940 if(fvMbSolver().domainId() == 0) {
941 cerr <<
"--> Ls Gap is Open for region " << region <<
" at timestep " <<
globalTimeStep << endl;
943 fvMbSolver().m_gapState[region] = 1;
944 ASSERT(!m_hasGapCells[region] && !m_hadGapCells[region],
"");
979template <MInt nDim,
class SysEqn>
981 fvMbSolver().m_gapCells.clear();
984 if(!lsSolver().m_closeGaps)
return;
988 if(lsSolver().m_gapInitMethod > 0) {
989 fvMbSolver().m_noneGapRegions =
true;
990 for(
MInt region = 0; region < fvMbSolver().m_noGapRegions; region++) {
991 if(fvMbSolver().m_gapState[region] != 1) fvMbSolver().m_noneGapRegions =
false;
992 ASSERT(fvMbSolver().m_gapState[region] != 0 && fvMbSolver().m_gapState[region] >= -2
993 && fvMbSolver().m_gapState[region] <= 3,
997 if(lsSolver().m_G0regionId > -1) fvMbSolver().m_noneGapRegions =
false;
998 if(fvMbSolver().m_noneGapRegions)
return;
1008 for(
MInt cellId = 0; cellId < fvMbSolver().noInternalCells(); cellId++) {
1010 fvMbSolver().assertValidGridCellId(cellId);
1011 if(fvMbSolver().a_isGapCell(cellId)) {
1012 lsGapInfo(cellId, &lsInfo(cellId, 0));
1013 const MInt status = fvMbSolver().a_wasGapCell(cellId) ? -1 : 0;
1014 fvMbSolver().m_gapCells.emplace_back(cellId, lsInfo(cellId, 0), status, lsInfo(cellId, 1), lsInfo(cellId, 2));
1015 }
else if(fvMbSolver().a_wasGapCell(cellId)) {
1016 lsGapInfo(cellId, &lsInfo(cellId, 0));
1017 fvMbSolver().m_gapCells.emplace_back(cellId, lsInfo(cellId, 0), 1, lsInfo(cellId, 1), lsInfo(cellId, 2));
1021 fvMbSolver().exchangeData(&lsInfo[0], 3);
1023 for(
MInt cellId = fvMbSolver().noInternalCells(); cellId < fvMbSolver().c_noCells(); cellId++) {
1025 if(fvMbSolver().a_isBndryGhostCell(cellId))
continue;
1027 if(fvMbSolver().a_isGapCell(cellId)) {
1028 const MInt status = fvMbSolver().a_wasGapCell(cellId) ? -1 : 0;
1029 fvMbSolver().m_gapCells.emplace_back(cellId, lsInfo(cellId, 0), status, lsInfo(cellId, 1), lsInfo(cellId, 2));
1030 }
else if(fvMbSolver().a_wasGapCell(cellId)) {
1031 fvMbSolver().m_gapCells.emplace_back(cellId, lsInfo(cellId, 0), 1, lsInfo(cellId, 1), lsInfo(cellId, 2));
1035 fvMbSolver().m_initGapCell =
true;
1041template <MInt nDim,
class SysEqn>
1046 if(recepiStep == 0) {
1048 if(fvMbSolver().isActive() && lsSolver().isActive()) {
1049 ASSERT(fabs(lsSolver().m_time - (fvMbSolver().m_physicalTime + lsSolver().m_timeStep)) < fvMbSolver().m_eps,
1050 "Different times in lSolver and fv-Solver! Expected times: " + to_string(lsSolver().m_time) +
" "
1051 + to_string(fvMbSolver().m_physicalTime) +
" "
1052 + to_string(fvMbSolver().m_physicalTime + lsSolver().m_timeStep));
1056 if(fvMbSolver().grid().wasAdapted()) {
1057 if(fvMbSolver().m_levelSetRans) {
1058 transferLevelSetValues();
1066template <MInt nDim,
class SysEqn>
1071 if(recepiStep == 0) {
1079 fvMbSolver().m_initGapCell =
false;
1087template <MInt nDim,
class SysEqn>
1094 if(fvMbSolver().m_levelSetRans) {
1095 transferLevelSetValues();
1097 transferGapCellProperty(0);
1100 transferLevelSetFieldValues(
true);
1112template <MInt nDim,
class SysEqn>
1116 if(solverId > 0)
return;
1124 transferLevelSetFieldValues(
true);
1125 if(fvMbSolver().m_levelSetRans) {
1126 transferLevelSetValues();
1138 if(fvMbSolver().maxLevel() != fvMbSolver().m_maxLevelBeforeAdaptation) {
1139 ASSERT(fvMbSolver().isActive(), to_string(fvMbSolver().m_solverId) +
" " + to_string(fvMbSolver().domainId()));
1140 const MFloat oldTimeStep = fvMbSolver().timeStep(
true);
1141 if(fvMbSolver().domainId() == 0) {
1142 cerr <<
"Max-Level change from " << fvMbSolver().m_maxLevelBeforeAdaptation <<
" to " << fvMbSolver().maxLevel()
1143 <<
" during adaptation => timeStep ";
1146 fvMbSolver().setTimeStep();
1150 const MFloat newTimeStep = fvMbSolver().timeStep(
true);
1151 if(fvMbSolver().domainId() == 0) {
1152 cerr <<
"change from " << oldTimeStep <<
" to " << newTimeStep << endl;
1156 lsSolver().m_time = lsSolver().m_time - oldTimeStep;
1159 fvMbSolver().m_time = fvMbSolver().m_time - oldTimeStep * fvMbSolver().m_timeRef;
1160 fvMbSolver().m_physicalTime = fvMbSolver().m_physicalTime - oldTimeStep;
1161 fvMbSolver().m_physicalTimeDt1 = fvMbSolver().m_physicalTimeDt1 - oldTimeStep;
1164 lsSolver().m_time = lsSolver().m_time + newTimeStep;
1166 fvMbSolver().advanceTimeStep();
1169 lsSolver().solutionStep();
1170 lsSolver().postTimeStep();
1173 transferLevelSetFieldValues(
true);
1174 if(fvMbSolver().m_levelSetRans) {
1175 transferLevelSetValues();
1180 }
else if(
globalTimeStep < 0 && fvMbSolver().m_geometryChange !=
nullptr) {
1183 transferLevelSetFieldValues(
true);
1184 if(fvMbSolver().m_levelSetRans) {
1185 transferLevelSetValues();
1189 fvMbSolver().initBndryLayer();
1206template <MInt nDim,
class SysEqn>
1216 transferLevelSetFieldValues(
true);
1217 if(fvMbSolver().m_levelSetRans) {
1218 transferLevelSetValues();
1228template <MInt nDim,
class SysEqn>
1239template <MInt nDim,
class SysEqn>
1241 ASSERT(!fvMbSolver().m_constructGField,
"ERROR: invalid function call!");
1243 switch(fvMbSolver().m_levelSetAdaptationScheme) {
1245 updateLevelSetOutsideBandPar();
1252 fvMbSolver().updateLevelSetOutsideBand();
1263template <MInt nDim,
class SysEqn>
1270 for(
MInt id = 0;
id < lsSolver().a_noG0Cells(0);
id++) {
1271 MInt cellId = lsSolver().a_G0CellId(
id, 0);
1272 pointsLVS[tempCnt] = a_levelSetFunctionG(cellId, 0);
1273 for(
MInt d = 0; d < nDim; d++) {
1274 points(tempCnt, d) = a_coordinateG(cellId, d);
1281 MIntScratchSpace globalNoPoints(fvMbSolver().noDomains(), AT_,
"globalNoPoints");
1282 noPoints[0] = a_noG0Cells(0);
1284 "noPoints.getPointer()",
"globalNoPoints.getPointer()");
1288 MInt dataBlockSize = nDim + 1;
1290 for(
MInt i = 0; i < fvMbSolver().noDomains(); i++) {
1291 displs[i] = noPoints[0] * dataBlockSize;
1292 recCounts[i] = globalNoPoints[i] * dataBlockSize;
1293 noPoints[0] += globalNoPoints[i];
1299 MFloatScratchSpace tmpsend(globalNoPoints[fvMbSolver().domainId()] * dataBlockSize, AT_,
"tmpsend");
1301 for(
MInt p = 0; p < globalNoPoints[fvMbSolver().domainId()]; p++) {
1302 for(
MInt d = 0; d < nDim; d++)
1303 tmpsend[p * dataBlockSize + d] = points(p, d);
1304 tmpsend[p * dataBlockSize + dataBlockSize - 1] = pointsLVS[p];
1309 fvMbSolver().mpiComm(), AT_,
"tmpsend.getPointer()",
"tmpreceive.getPointer()");
1311 for(
MInt p = 0; p < noPoints[0]; p++) {
1312 for(
MInt d = 0; d < nDim; d++)
1313 globalPoints(p, d) = tmpreceive[p * dataBlockSize + d];
1314 globalPointsLVS[p] = tmpreceive[p * dataBlockSize + dataBlockSize - 1];
1317 for(
MInt cell = 0; cell < fvMbSolver().a_noCells(); cell++) {
1318 const MInt gCellId = fv2lsId(cell);
1319 if(gCellId > -1 && a_inBandG(gCellId, 0))
continue;
1320 if(fvMbSolver().a_levelSetValuesMb(cell, 0) > F0) {
1321 fvMbSolver().a_levelSetValuesMb(cell, 0) = fvMbSolver().c_cellLengthAtLevel(0);
1323 fvMbSolver().a_levelSetValuesMb(cell, 0) = -fvMbSolver().c_cellLengthAtLevel(0);
1325 for(
MInt p = 0; p < noPoints[0]; p++) {
1327 MFloat lvsValTmp = globalPointsLVS[p];
1328 for(
MInt d = 0; d < nDim; d++) {
1329 distTmp += (fvMbSolver().a_coordinate(cell, d) - globalPoints(p, d))
1330 * (fvMbSolver().a_coordinate(cell, d) - globalPoints(p, d));
1332 distTmp = sqrt(distTmp);
1333 if(fvMbSolver().a_levelSetValuesMb(cell, 0) >= F0) {
1334 lvsValTmp += distTmp;
1336 lvsValTmp -= distTmp;
1338 if(abs(lvsValTmp) < abs(fvMbSolver().a_levelSetValuesMb(cell, 0))) {
1339 fvMbSolver().a_levelSetValuesMb(cell, 0) = lvsValTmp;
1350template <MInt nDim,
class SysEqn>
1356 MFloat physicalTime = -std::numeric_limits<MFloat>::max();
1358 if(fvMbSolver().isActive() && fvMbSolver().m_restart) {
1359 stringstream varFileName;
1361 varFileName << fvMbSolver().restartDir() <<
"restartVariables";
1362 if(!fvMbSolver().m_useNonSpecifiedRestartFile) {
1363 if(!fvMbSolver().m_multipleFvSolver) {
1364 varFileName <<
"_" << fvMbSolver().m_restartTimeStep;
1366 varFileName << fvMbSolver().solverId() <<
"_" << fvMbSolver().m_restartTimeStep;
1369 varFileName << ParallelIo::fileExt();
1371 if(fvMbSolver().domainId() == 0) {
1372 fvMbSolver().loadRestartTime((varFileName.str()).c_str(), timeStep, time, physicalTime);
1376 }
else if(fvMbSolver().isActive()) {
1380 if(fvMbSolver().isActive()) {
1381 MPI_Allreduce(MPI_IN_PLACE, &physicalTime, 1, MPI_DOUBLE, MPI_MAX, fvMbSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
1385 if(fvMbSolver().grid().hasInactiveRanks()) {
1386 if(lsSolver().isActive()) {
1387 MPI_Allreduce(MPI_IN_PLACE, &physicalTime, 1, MPI_DOUBLE, MPI_MAX, lsSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
1392 ASSERT(physicalTime > -fvMbSolver().m_eps,
"");
1393 return physicalTime;
1401template <MInt nDim,
class SysEqn>
1405 MInt gCellId = fv2lsId(fvCellId);
1408 ASSERT(m_allowLsInterpolation,
"");
1409 gCellId = fv2lsIdParent(fvCellId);
1411 ASSERT(gCellId > -1,
"");
1412 MInt regionId = a_potentialGapCellClose(gCellId) - 2;
1413 ASSERT(regionId < fvMbSolver().m_noGapRegions,
"");
1415 if(lsSolver().m_G0regionId > -1 && a_potentialGapCellClose(gCellId) == lsSolver().m_G0regionId) {
1416 regionId = fvMbSolver().m_noGapRegions;
1418 if(lsSolver().m_gapInitMethod > 0) {
1419 ASSERT(regionId > -1,
"");
1423 info[1] = lsSolver().a_bodyIdG(gCellId, 0);
1424 info[2] = lsSolver().a_secondBodyId(gCellId);
1430template <MInt nDim,
class SysEqn>
1435 fvMbSolver().m_startSet = lsSolver().m_startSet;
1436 fvMbSolver().m_noSets = lsSolver().m_noSets;
1437 fvMbSolver().m_bodyToSetTable = lsSolver().m_bodyToSetTable;
1438 fvMbSolver().m_noBodiesInSet = lsSolver().m_noBodiesInSet;
1439 fvMbSolver().m_setToBodiesTable = lsSolver().m_setToBodiesTable;
1441 fvMbSolver().updateGeometry();
1444 lsSolver().m_time = -99;
1445 lsSolver().m_time = restartTime();
1447 if(lsSolver().isActive() && fvMbSolver().isActive()) {
1448 ASSERT(fabs(lsSolver().m_time - fvMbSolver().m_physicalTime) < fvMbSolver().m_eps,
"");
1454 MInt noInactiveFv = 0;
1455 MInt noInactiveLs = 0;
1456 if(!fvMbSolver().isActive()) {
1459 if(!lsSolver().isActive()) {
1463 MPI_Allreduce(MPI_IN_PLACE, &noInactiveFv, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD, AT_,
"MPI_IN_PLACE",
"noInactiveFv");
1464 MPI_Allreduce(MPI_IN_PLACE, &noInactiveLs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD, AT_,
"MPI_IN_PLACE",
"noInactiveLs");
1465 if(noInactiveFv > 0) {
1466 cerr0 <<
"FvMb solver has " << noInactiveFv <<
" inactive ranks!" << endl;
1468 if(noInactiveLs > 0) {
1469 cerr0 <<
"Ls solver has " << noInactiveLs <<
" inactive ranks!" << endl;
1473 transferLevelSetFieldValues(
true);
1474 if(fvMbSolver().m_levelSetRans) {
1475 transferLevelSetValues();
1479 fvMbSolver().initBndryLayer();
1484 if(fvMbSolver().m_LsMovement) {
1485 initBodyProperties();
1492template <MInt nDim,
class SysEqn>
1499 if(fvMbSolver().m_levelSetRans) {
1500 transferLevelSetValues();
1503 fvMbSolver().rhsBnd();
1504 fvMbSolver().advanceSolution();
1505 fvMbSolver().advanceBodies();
1512template <MInt nDim,
class SysEqn>
1516 if(lsSolver().isActive() && fvMbSolver().isActive()) {
1517 ASSERT(fabs(lsSolver().m_time - fvMbSolver().m_physicalTime) < fvMbSolver().m_eps,
"");
1520 if(currentSolver == m_lsSolverId) {
1522 if(lsSolver().m_LsRotate) {
1523 transferBodyRadius();
1534template <MInt nDim,
class SysEqn>
1539 MFloat fvTimeStep = std::numeric_limits<MFloat>::max();
1542 if(fvMbSolver().isActive()) {
1543 fvTimeStep = fvMbSolver().timeStep(
true);
1547 if(fvMbSolver().grid().hasInactiveRanks()) {
1548 if(lsSolver().isActive()) {
1549 MPI_Allreduce(MPI_IN_PLACE, &fvTimeStep, 1, MPI_DOUBLE, MPI_MIN, lsSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
1554 if(lsSolver().isActive() && fvMbSolver().isActive()
1555 && fabs(lsSolver().m_time - fvMbSolver().m_physicalTime) > fvMbSolver().m_eps) {
1556 cerr <<
"Fv-Solver " << fvMbSolver().isActive() <<
" ls-Solver " << lsSolver().isActive() << endl;
1557 cerr <<
"Fv-Time " << setprecision(12) << fvMbSolver().m_physicalTime <<
" ls-Time " << lsSolver().m_time << endl;
1558 cerr <<
"Fv-TS " << setprecision(12) << fvTimeStep <<
" ls-TS " << lsSolver().m_timeStep << endl;
1559 mTerm(1, AT_,
"Time in Solvers differs!.");
1561 lsSolver().m_timeStep = fvTimeStep;
1567template <MInt nDim,
class SysEqn>
1571 const MInt noBodies = lsSolver().m_noEmbeddedBodies;
1572 for(
MInt b = 0;
b < noBodies;
b++) {
1573 fvMbSolver().m_bodyRadius[
b] = lsSolver().m_bodyRadius[
b];
1585template <MInt nDim,
class SysEqn>
1589 if(!fvMbSolver().m_LsMovement)
return;
1592 const MFloat nextFvTime = fvMbSolver().m_physicalTime + fvMbSolver().timeStep();
1594 for(
MInt body = 0; body < fvMbSolver().m_noEmbeddedBodies; body++) {
1595 computeBodyProperties(1, &fvMbSolver().m_bodyCenter[body * nDim], body, nextFvTime);
1596 computeBodyProperties(2, &fvMbSolver().m_bodyVelocity[body * nDim], body, nextFvTime);
1597 computeBodyProperties(3, &fvMbSolver().m_bodyAcceleration[body * nDim], body, nextFvTime);
1599 if(fvMbSolver().m_movingBndryCndId == 3008 || fvMbSolver().m_movingBndryCndId == 3010) {
1600 computeBodyProperties(4, &fvMbSolver().m_bodyTemperature[body], body, nextFvTime);
1604 if(lsSolver().m_LsRotate) {
1605 transferAngularVelocity();
1614template <MInt nDim,
class SysEqn>
1618 for(
MInt b = 0;
b < lsSolver().m_noEmbeddedBodies;
b++) {
1619 for(
MInt i = 0; i < nDim; i++) {
1620 if(lsSolver().isActive()) {
1621 fvMbSolver().m_bodyAngularVelocity[
b * nDim + i] = lsSolver().m_bodyAngularVelocity[
b * nDim + i];
1622 fvMbSolver().m_bodyAngularAcceleration[
b * nDim + i] = lsSolver().m_bodyAngularAcceleration[
b * nDim + i];
1624 fvMbSolver().m_bodyAngularVelocity[
b * nDim + i] = NAN;
1625 fvMbSolver().m_bodyAngularAcceleration[
b * nDim + i] = NAN;
1634template <MInt nDim,
class SysEqn>
1638 if(!fvMbSolver().a_isGapCell(cellId)) {
1639 fvMbSolver().a_levelSetValuesMb(cellId, 0) = fvMbSolver().a_levelSetValuesMb(cellId, 1);
1640 fvMbSolver().a_associatedBodyIds(cellId, 0) = fvMbSolver().a_associatedBodyIds(cellId, 1);
1641 for(
MInt set = 2; set < a_noLevelSetsMb(); set++) {
1642 MFloat phi0 = fvMbSolver().a_levelSetValuesMb(cellId, 0);
1643 MFloat phi1 = fvMbSolver().a_levelSetValuesMb(cellId, set);
1644 MInt body0 = fvMbSolver().a_associatedBodyIds(cellId, 0);
1645 MInt body1 = fvMbSolver().a_associatedBodyIds(cellId, set);
1648 if(phi0 >= F0 && phi1 >= F0) {
1652 phi0 =
mMin(phi0, phi1);
1653 }
else if(phi0 <= F0 && phi1 <= F0) {
1654 if(abs(phi1) > abs(phi0)) {
1657 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
1658 }
else if(phi0 * phi1 <= F0) {
1667 fvMbSolver().a_levelSetValuesMb(cellId, 0) = phi0;
1668 fvMbSolver().a_associatedBodyIds(cellId, 0) = body0;
1676template <MInt nDim,
class SysEqn>
1680 const MFloat time = fvMbSolver().m_physicalTime;
1682 for(
MInt body = 0; body < fvMbSolver().m_noEmbeddedBodies; body++) {
1683 computeBodyProperties(1, &fvMbSolver().m_bodyCenter[body * nDim], body, time);
1684 computeBodyProperties(2, &fvMbSolver().m_bodyVelocity[body * nDim], body, time);
1685 computeBodyProperties(3, &fvMbSolver().m_bodyAcceleration[body * nDim], body, time);
1687 if(fvMbSolver().m_movingBndryCndId == 3008 || fvMbSolver().m_movingBndryCndId == 3010) {
1688 computeBodyProperties(4, &fvMbSolver().m_bodyTemperature[body], body, time);
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 lsGapInfo(const MInt, MInt *)
returns the gap region for a given fvCell
LsFvMb(const MInt couplingId, LsSolver *ls, FvMbSolver *fvMb)
void init() override
performs the coupling after solver initialization
void updateLevelSet()
update the levelset outside of the band default should be case 2 -> don't do anything!
void testGapProperty()
transfers the LevelSetValues from the levelset to the moving boundary Part
MFloat interpolateLevelSet(MInt cellId, MFloat *point, MInt set)
void transferTimeStep()
transfers the gcell time step from the fvMbSolver! time should already be matching!
void initData()
Initialize coupling-class-specific Data.
void transferBodyProperties()
transfer current body properties from the ls-Solver to the fv-Solver bodyPosition bodyVelocity bodyAc...
void readProperties()
reads lsfvmb-coupling-specific data
MFloat interpolateLevelSetMb(MInt *interpolationCells, MFloat *point, const MInt set)
void finalizeAdaptation(const MInt) override
finalizeAdaptation
void preCouple(MInt recepiStep) override
preCoupler
void transferLevelSetFieldValues(MBool)
transfers the LevelSetValues for all cells from the levelset to the moving boundary Part
void transferBodyRadius()
Copies the bodyRadius from the LS-solver into the FV-solver.
void computeBodyProperties(MInt returnMode, MFloat *bodyData, MInt body, MFloat time)
returns a specific property of the specifuec body used to provide a unique function for both level-se...
MFloat restartTime()
return restart time for lsSolver, when the fvSolver is not initialised yet!
void setGapState()
Sets the Gap-State in the fvmb-solver (stati are the same for all domains!) possible Gap-States:
void postCouple(MInt recipeStep=0) override
postCoupler
void transferLevelSetValues()
Sets the Levelset-Values in fvSolver.
void updateFlowSolver()
Updates the fv-mb-solver flow solver (after a completed levelSet TimeStep and finalizeLevelSet() )
void updateLevelSetOutsideBandPar()
computes an approximate level set value for cells outside the level-set computing band should not be ...
void finalizeCouplerInit() override
performs the final coupling after finalization
void testLsValues()
transfers the LevelSetValues from the levelset to the moving boundary Part
void finalizeBalance(const MInt) override
called after each solver-balance
void buildCollectedLevelSet(const MInt)
build the combined levelSet for the given cellId
void transferAngularVelocity()
Writes the angular velocity and the angular acceleration from the LS-solver into the FV-solver.
void interpolateLsFV(const MInt, const MInt)
interpolate levelset values on the fv-grid
void postAdaptation() override
finalizeAdaptation
void initFvGapCells()
Initialises fv-Gap Cells for gapHandling (must be called each timeStep before the gapHandling call in...
void initBodyProperties()
initialise the body properties in the fvmb-solver based
void transferGapCellProperty(MInt mode)
Sets the gap-cell-property mode 1 : regular call each timeStep (advance is/was-GapCell) mode 0 : init...
void testCoupling()
transfers the LevelSetValues from the levelset to the moving boundary Part
void prepareAdaptation() override
finalizeAdaptation
void finalizeSubCoupleInit(MInt) override
performs the coupling in solver finalization
void checkProperties()
Checks property-data which is read in by both ls-and Fv-Solver.
This class is a ScratchSpace.
T * getPointer() const
Deprecated: use begin() instead!
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
@ IsSplitChild
cell is a split child
@ IsMovingBnd
cell at moving boundary
constexpr MLong IPOW2(MInt x)
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_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