22template <MInt nDim, MInt nDist,
class SysEqn>
36template <MInt nDim, MInt nDist,
class SysEqn>
41 m_lbSolverId = lbSolver().solverId();
42 m_lsSolverId = lsSolver().solverId();
54 mAlloc(m_transferBoundingBox, 2 * nDim,
"m_transferBoundingBox", AT_);
55 for(
MInt d = 0; d < 2 * nDim; d++) {
56 m_transferBoundingBox[d] = Context::getSolverProperty<MFloat>(
"transferRegion", m_lbSolverId, AT_, d);
59 stringstream errorMessage;
60 errorMessage <<
"ERROR: Wrong number of array entries in transferRegion. Must be 2 * nDim!!";
61 mTerm(1, AT_, errorMessage.str());
69template <MInt nDim, MInt nDist,
class SysEqn>
73 lbSolver().m_noEmbeddedBodies = lsSolver().m_noEmbeddedBodies;
75 if(lsSolver().m_maxNoSets > 0) lbSolver().m_noLevelSetsUsedForMb = lsSolver().m_maxNoSets;
76 if(lbSolver().m_useOnlyCollectedLS) lbSolver().m_noLevelSetsUsedForMb = 1;
78 lbSolver().m_maxNoSets = lbSolver().m_noLevelSetsUsedForMb;
80 lbSolver().m_constructGField = lsSolver().m_constructGField;
86template <MInt nDim, MInt nDist,
class SysEqn>
104 m_outsideDefault =
true;
106 m_outsideDefault = Context::getSolverProperty<MBool>(
"outsideDefault", m_lbSolverId, AT_, &m_outsideDefault);
113template <MInt nDim, MInt nDist,
class SysEqn>
117 if(lsSolver().m_constructGField)
return;
119 for(
MInt lbCellId = 0; lbCellId < a_noLbCells(); lbCellId++) {
120 ASSERT(lbSolver().grid().tree().solver2grid(lbCellId) >= 0,
"");
121 ASSERT(lbSolver().grid().solverFlag(lbSolver().grid().tree().solver2grid(lbCellId), m_lbSolverId),
"");
122#ifdef COUPLING_DEBUG_
123 if(lsSolver().grid().solverFlag(lbSolver().grid().tree().solver2grid(lbCellId), m_lsSolverId)) {
124 ASSERT(ls2lbId(lb2lsId(lbCellId)) == lbCellId,
125 to_string(lbCellId) +
" " + to_string(lb2lsId(lbCellId)) +
" " + to_string(ls2lbId(lb2lsId(lbCellId))));
130 for(
MInt cellId = 0; cellId < a_noLsCells(); cellId++) {
131 ASSERT(lsSolver().grid().tree().solver2grid(cellId) >= 0,
"");
132 ASSERT(lsSolver().grid().solverFlag(lsSolver().grid().tree().solver2grid(cellId), m_lsSolverId),
"");
133#ifdef COUPLING_DEBUG_
134 if(lbSolver().grid().solverFlag(lsSolver().grid().tree().solver2grid(cellId), m_lbSolverId)) {
135 ASSERT(lb2lsId(ls2lbId(cellId)) == cellId,
136 to_string(cellId) +
" " + to_string(ls2lbId(cellId)) +
" " + to_string(lb2lsId(ls2lbId(cellId))));
141 if(!lsSolver().m_levelSetLb)
return;
143#ifdef COUPLING_DEBUG_
144 for(
MInt lbCellId = 0; lbCellId < a_noLbCells(); lbCellId++) {
145 for(
MInt dir = 0; dir < nDim; dir++) {
146 if(lsSolver().grid().solverFlag(lbSolver().grid().tree().solver2grid(lbCellId), m_lsSolverId)) {
147 ASSERT(abs(lbSolver().c_coordinate(lbCellId, dir) - a_coordinateG(lb2lsId(lbCellId), dir)) < 0.00000001,
"");
158template <MInt nDim, MInt nDist,
class SysEqn>
162 const MInt noRfJumps =
mMax(0, lbSolver().maxLevel() - lsSolver().maxRefinementLevel());
165 if(!lbSolver().isActive())
return;
168 if(lsSolver().isActive()) {
169 lsSolver().exchangeAllLevelSetData();
170 lsSolver().checkHaloCells();
174 if(lsSolver().isActive()) {
175 std::list<MInt> interpolationParents;
176 interpolationParents.clear();
178 for(
MInt cellId = 0; cellId < a_noLbCells(); cellId++) {
180 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
181 if(m_outsideDefault) {
182 lbSolver().a_levelSetFunctionMB(cellId, set) = a_outsideGValue();
184 lbSolver().a_levelSetFunctionMB(cellId, set) = -a_outsideGValue();
186 lbSolver().a_associatedBodyIds(cellId, set) = -2;
188 if(m_transferBoundingBox !=
nullptr) {
189 if(m_transferBoundingBox[0] > lbSolver().c_coordinate(cellId, 0)
190 || m_transferBoundingBox[0 + nDim] < lbSolver().c_coordinate(cellId, 0)) {
193 if(m_transferBoundingBox[1] > lbSolver().c_coordinate(cellId, 1)
194 || m_transferBoundingBox[1 + nDim] < lbSolver().c_coordinate(cellId, 1)) {
197 IF_CONSTEXPR(nDim == 3) {
198 if(m_transferBoundingBox[2] > lbSolver().c_coordinate(cellId, 2)
199 || m_transferBoundingBox[2 + nDim] < lbSolver().c_coordinate(cellId, 2)) {
204 const MInt gCellId = lb2lsId(cellId);
207 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
208 lbSolver().a_levelSetFunctionMB(cellId, set) = a_levelSetFunctionG(gCellId, set);
209 lbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellId, set);
213 ASSERT(cellId >= a_noLbCells(),
"");
216 if(cellId <= a_noLbCells()) {
217 const MInt gCellParent = lb2lsIdParent(cellId);
219 if(gCellParent > -1) {
223 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
224 lbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
226 lbSolver().a_levelSetFunctionMB(cellId, set) = a_levelSetFunctionG(gCellParent, set);
230 if(lbSolver().a_isHalo(cellId) || lsSolver().a_isHalo(gCellParent))
continue;
232 if(lsSolver().m_buildCollectedLevelSetFunction && !lsSolver().a_inBandG(gCellParent, 0)) {
233 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
234 lbSolver().a_levelSetFunctionMB(cellId, set) = a_levelSetFunctionG(gCellParent, set);
235 lbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
239 const MInt levelDifference = lbSolver().c_level(cellId) - lsSolver().a_level(gCellParent);
240 if(levelDifference == 1) {
242 MFloat point[3] = {lbSolver().a_coordinate(cellId, 0), lbSolver().a_coordinate(cellId, 1),
243 lbSolver().a_coordinate(cellId, 2)};
244 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
245 MInt position = lsSolver().setUpLevelSetInterpolationStencil(gCellParent, interpolationCells, point);
247 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
248 lbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
251 lbSolver().a_levelSetFunctionMB(cellId, set) = a_levelSetFunctionG(gCellParent, set);
253 const MFloat phi = lsSolver().interpolateLevelSet(interpolationCells, point, set);
255 lbSolver().a_levelSetFunctionMB(cellId, set) = phi;
259 buildCollectedLevelSet(cellId);
264 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
265 lbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
267 MInt parent = cellId;
268 for(
MInt i = 0; i < levelDifference - 1; i++) {
269 parent = lbSolver().c_parentId(parent);
271 ASSERT(parent > -1,
"");
274 ASSERT(lb2lsId(lbSolver().c_parentId(parent)) == gCellParent,
"");
275 interpolationParents.push_back(parent);
286 if(!interpolationParents.empty()) {
287 cerr <<
"This part is not tested yet!!!" << endl;
288 std::list<MInt> newInterpolationParents;
290 for(
MInt lvl = lsSolver().maxUniformRefinementLevel(); lvl < lbSolver().maxRefinementLevel(); lvl++) {
291 lbSolver().exchangeData(&(lbSolver().a_levelSetFunctionMB(0, 0)), lbSolver().m_maxNoSets);
292 lbSolver().exchangeData(&(lbSolver().a_associatedBodyIds(0, 0)), lbSolver().m_maxNoSets);
294 MInt noInterpolationCells = (
MInt)interpolationParents.size();
295 MPI_Allreduce(MPI_IN_PLACE, &noInterpolationCells, 1, MPI_INT, MPI_MAX, lbSolver().mpiComm(), AT_,
"INPLACE",
296 "noInterpolationCells");
297 if(noInterpolationCells == 0)
break;
299 if(interpolationParents.empty())
continue;
301 ASSERT(noRfJumps > 1,
"");
303 interpolationParents.sort();
304 interpolationParents.unique();
305 newInterpolationParents.clear();
307 for(
auto it = interpolationParents.begin(); it != interpolationParents.end(); it++) {
308 const MInt parent = (*it);
309 for(
MInt c = 0; c < lbSolver().grid().m_maxNoChilds; c++) {
310 const MInt childId = lbSolver().c_childId(parent, c);
311 if(childId < 0)
continue;
313 if(!lbSolver().c_isLeafCell(childId)) {
314 newInterpolationParents.push_back(childId);
318 interpolationParents.clear();
319 for(
auto it = newInterpolationParents.begin(); it != newInterpolationParents.end(); it++) {
320 const MInt cellId = (*it);
321 interpolationParents.push_back(cellId);
326 for(
MInt cellId = 0; cellId < a_noLbCells(); cellId++) {
327 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
328 if(m_outsideDefault) {
329 lbSolver().a_levelSetFunctionMB(cellId, set) = a_outsideGValue();
331 lbSolver().a_levelSetFunctionMB(cellId, set) = -a_outsideGValue();
333 lbSolver().a_associatedBodyIds(cellId, set) = -2;
343template <MInt nDim, MInt nDist,
class SysEqn>
346 IF_CONSTEXPR(nDim == 3) { updateGeometry(); }
351template <MInt nDim, MInt nDist,
class SysEqn>
353 MInt noLevelSetFieldData = 0;
355 if(lsSolver().m_writeOutAllLevelSetFunctions) {
356 noLevelSetFieldData += noLevelSetFieldData + 2 * a_noSets();
358 noLevelSetFieldData += 1;
360 if(lsSolver().m_writeOutAllCurvatures) {
361 noLevelSetFieldData += a_noSets();
363 noLevelSetFieldData += 1;
366 return noLevelSetFieldData;
373template <MInt nDim, MInt nDist,
class SysEqn>
377 lbSolver().m_geometryIntersection->m_noEmbeddedBodies = lbSolver().m_noEmbeddedBodies;
378 lbSolver().m_geometryIntersection->m_noLevelSetsUsedForMb = lbSolver().m_noLevelSetsUsedForMb;
379 lbSolver().m_geometryIntersection->m_bodyToSetTable = lsSolver().m_bodyToSetTable;
380 lbSolver().m_geometryIntersection->m_setToBodiesTable = lsSolver().m_setToBodiesTable;
381 lbSolver().m_geometryIntersection->m_noBodiesInSet = lsSolver().m_noBodiesInSet;
388template <MInt nDim, MInt nDist,
class SysEqn>
392 if(lbSolver().m_constructGField)
return;
394 MBool& firstRun = m_static_updateLevelSetFlowSolver_firstRun;
397 || (lbSolver().m_trackMovingBndry &&
globalTimeStep >= lbSolver().m_trackMbStart
402 transferLevelSetFieldValues(
true);
410template <MInt nDim, MInt nDist,
class SysEqn>
414 if(lbSolver().isActive()) {
415 lbSolver().initializeMovingBoundaries();
416 lbBndCnd().initializeBndMovingBoundaries();
418 updateLevelSetFlowSolver();
421template <MInt nDim, MInt nDist,
class SysEqn>
424 lsSolver().m_timeStep = F1;
427template <MInt nDim, MInt nDist,
class SysEqn>
430 std::ignore = couplingStep;
433template <MInt nDim, MInt nDist,
class SysEqn>
442 updateLevelSetFlowSolver();
443 std::vector<MInt> maxGCellLevels(lsSolver().m_maxNoSets);
444 for(
MInt set = 0; set < lsSolver().m_maxNoSets; set++) {
445 maxGCellLevels[set] = lsSolver().a_maxGCellLevel(set);
448 lbSolver().preCoupleLs(maxGCellLevels);
450 lbSolver().createBndryToBodyMapping(bndryToBodyMapping, bodyToBndryMapping);
452 lbBndCnd().createMBComm();
454 initializeSolidDomain();
456 MFloatScratchSpace bodyVelocities(m_maxNoEmbeddedBodies, nDim, AT_,
"bodyVelocities");
457 for(
MInt body = 0; body < m_maxNoEmbeddedBodies; body++) {
458 lsSolver().computeBodyPropertiesForced(2, &bodyVelocities(body, 0), body,
globalTimeStep);
461 for(
MInt mbCell = 0; mbCell < a_mbCell().size(); mbCell++) {
462 for(
auto body : bndryToBodyMapping[mbCell]) {
463 for(
MInt n = 0; n < nDim; n++) {
464 a_mbCell().velocity(mbCell, n) = bodyVelocities(body, n);
477template <MInt nDim, MInt nDist,
class SysEqn>
486 lbBndCnd().postCouple();
487 lsSolver().m_timeStep = F1;
499template <MInt nDim, MInt nDist,
class SysEqn>
504template <MInt nDim, MInt nDist,
class SysEqn>
509 if(lbSolver().isActive()) {
510 lbSolver().initializeMovingBoundaries();
511 lbBndCnd().initializeBndMovingBoundaries();
513 updateLevelSetFlowSolver();
518template <MInt nDim, MInt nDist,
class SysEqn>
522 if(!lbSolver().isActive()) {
529 for(
MInt body = 0; body < a_noEmbeddedBodies(); body++) {
530 lsSolver().computeBodyPropertiesForced(2, &bodyVelocities(body, 0), body,
globalTimeStep);
533 for(
MInt i = 0; i < lbSolver().a_noCells(); i++) {
535 if(a_isActive(i) && a_wasActive(i)) {
549 for(
MInt set = lbSolver().m_levelSetId; set < lbSolver().m_maxNoSets; set++) {
550 if(a_associatedBodyIdsMb(i, set) >= 0) {
551 bodyId = a_associatedBodyIdsMb(i, set);
559 if((bodyId >= 0) && (bodyId < a_noEmbeddedBodies()) && (a_levelSetFunctionMb(i, setOfBody) < 0)) {
560 for(
MInt j = 0; j < nDim; j++) {
561 a_variable(i, j) = bodyVelocities(bodyId, j);
562 a_oldVariable(i, j) = bodyVelocities(bodyId, j);
564 MFloat squaredVelocity = 0.0;
565 for(
MInt n = 0; n < nDim; n++) {
566 squaredVelocity += bodyVelocities(bodyId, n) * bodyVelocities(bodyId, n);
568 lbSolver().setEqDists(i, 1.0, &bodyVelocities(bodyId, 0));
570 a_variable(i, a_pvt()) = a_initTemperatureKelvin();
571 lbSolver().setEqDistsThermal(i, a_initTemperatureKelvin(), F1, squaredVelocity, &bodyVelocities(bodyId, 0));
574 for(
MInt j = 0; j < a_noVariables(); j++) {
575 a_variable(i, j) = F0;
576 a_oldVariable(i, j) = F0;
578 MFloat squaredVelocity = 0.0;
579 MFloat bodyVelocitiesOutsideLs[nDim] = {F0};
580 lbSolver().setEqDists(i, 1.0, bodyVelocitiesOutsideLs);
582 a_variable(i, a_pvt()) = a_initTemperatureKelvin();
583 lbSolver().setEqDistsThermal(i, a_initTemperatureKelvin(), F1, squaredVelocity, bodyVelocitiesOutsideLs);
586 a_variable(i, a_pvrho()) = 1.0;
587 a_oldVariable(i, a_pvrho()) = 1.0;
589 lbBndCnd().refillEmergedCell(i);
597template <MInt nDim, MInt nDist,
class SysEqn>
601 lbSolver().a_levelSetFunctionMB(cellId, 0) = lbSolver().a_levelSetFunctionMB(cellId, 1);
602 lbSolver().a_associatedBodyIds(cellId, 0) = lbSolver().a_associatedBodyIds(cellId, 1);
603 for(
MInt set = 2; set < a_noLevelSetsMb(); set++) {
604 MFloat phi0 = lbSolver().a_levelSetFunctionMB(cellId, 0);
605 MFloat phi1 = lbSolver().a_levelSetFunctionMB(cellId, set);
606 MInt body0 = lbSolver().a_associatedBodyIds(cellId, 0);
607 MInt body1 = lbSolver().a_associatedBodyIds(cellId, set);
610 if(phi0 >= F0 && phi1 >= F0) {
614 phi0 =
mMin(phi0, phi1);
615 }
else if(phi0 <= F0 && phi1 <= F0) {
616 if(abs(phi1) > abs(phi0)) {
619 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
620 }
else if(phi0 * phi1 <= F0) {
629 lbSolver().a_levelSetFunctionMB(cellId, 0) = phi0;
630 lbSolver().a_associatedBodyIds(cellId, 0) = body0;
639template <MInt nDim, MInt nDist,
class SysEqn>
643 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
644 MFloat point[3] = {lbSolver().a_coordinate(to, 0), lbSolver().a_coordinate(to, 1), lbSolver().a_coordinate(to, 2)};
646 const MInt position = lbSolver().setUpLbInterpolationStencil(from, interpolationCells, point);
648 for(
MInt set = 0; set < a_noLevelSetsMb(); set++) {
650 lbSolver().a_levelSetFunctionMB(to, set) = lbSolver().a_levelSetFunctionMB(from, set);
652 MFloat phi = interpolateLevelSet(interpolationCells, point, set);
653 lbSolver().a_levelSetFunctionMB(to, set) = phi;
656 buildCollectedLevelSet(to);
662template <MInt nDim, MInt nDist,
class SysEqn>
667 return static_cast<MFloat>(lbSolver().a_levelSetFunctionMB(cellId, refSet));
671 return static_cast<MFloat>(lbSolver().a_coordinate(cellId,
id));
674 return lbSolver().interpolateFieldDataLb(&interpolationCells[0], &point[0], set, scalarField, coordinate);
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
This class represents all LB models.
void interpolateLsLb(const MInt from, const MInt to)
interpolate levelset values on the lb-grid
void initializeSolidDomain()
void transferLevelSetFieldValues(MBool)
transfers the LevelSetValues for all cells from the levelset to the moving boundary Part
LsLb(MInt couplingId, LsSolver *ls, LbSolver *lb)
void finalizeSubCoupleInit(MInt couplingStep) override
void updateGeometry()
Updates the member-variables in the geometry-intersection class.
void preCouple(MInt step) override
void finalizeAdaptation(const MInt solverId) override
void finalizeCouplerInit() override
void buildCollectedLevelSet(const MInt cellId)
build the combined levelSet for the given cellId
MFloat interpolateLevelSet(MInt *interpolationCells, MFloat *point, const MInt set)
void testCoupling()
transfers the LevelSetValues from the levelset to the moving boundary Part
void postAdaptation() override
finalizeAdaptation
void checkProperties()
Checks property-data which is read in by both ls-and Lb-Solver.
void postCouple(MInt step) override
void updateLevelSetFlowSolver()
Updates the fv-mb-solver flow solver (after a completed levelSet TimeStep and finalizeLevelSet() )
MInt noLevelSetFieldData()
void createBodyTree()
transfers the LevelSetValues from the levelset to the moving boundary Part
This class is a ScratchSpace.
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)
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