MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
lsfvmb.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7//#define COUPLING_DEBUG_
8
9#include "lsfvmb.h"
10
11#include <algorithm>
12#include <stack>
13#include <vector>
14#include "MEMORY/alloc.h"
15#include "UTIL/functions.h"
16#include "UTIL/kdtree.h"
17#include "coupling.h"
18#include "globals.h"
19#include "globalvariables.h"
20
21using namespace std;
22
23template <MInt nDim, class SysEqn>
25 : Coupling(couplingId), CouplingLS<nDim>(couplingId, ls), CouplingFvMb<nDim, SysEqn>(couplingId, fvMb) {
26 TRACE();
27
28 initData();
29
31}
32
33
37template <MInt nDim, class SysEqn>
39 TRACE();
40
41 // solver-specific data:
42 m_fvSolverId = fvMbSolver().m_solverId;
43 m_lsSolverId = lsSolver().m_solverId;
44
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_);
48 }
49
50 m_noRfJumps = 0;
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);
54 }
55
56 const MInt maxlevelDif = fvMbSolver().maxRefinementLevel() - lsSolver().maxRefinementLevel();
57 m_noRfJumps = mMax(m_noRfJumps, maxlevelDif);
58
59 if(lsSolver().m_maxLevelChange) m_noRfJumps = 0;
60
61 m_log << " Ls - FvMb Coupler detected " << m_noRfJumps << " level-jumps" << endl;
62
63
64 fvMbSolver().m_maxLsValue = lsSolver().m_outsideGValue;
65
66 if(fvMbSolver().m_levelSetRans) {
67 mAlloc(fvMbSolver().m_levelSetValues, lsSolver().m_noSets, "fvMbSolver().m_levelSetValues", AT_);
68 }
69}
70
74template <MInt nDim, class SysEqn>
76 TRACE();
77
78 ASSERT(lsSolver().m_noEmbeddedBodies == fvMbSolver().m_noEmbeddedBodies, "");
79 ASSERT(lsSolver().m_constructGField == fvMbSolver().m_constructGField, "");
80 ASSERT(lsSolver().m_noGapRegions == fvMbSolver().m_noGapRegions, "");
81
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()));
86 } else {
87 ASSERT(m_noRfJumps > 0, "");
88 if(lsSolver().domainId() == 0) {
89 cerr << "Allowing ls interpolation with " << m_noRfJumps << " level jumps!" << endl;
90 }
91 ASSERT(lsSolver().m_gShadowWidth <= fvMbSolver().m_bandWidth[fvMbSolver().maxRefinementLevel() - 1], "");
92 }
93
94 if(!lsSolver().m_maxLevelChange) {
95 ASSERT(lsSolver().a_maxGCellLevel(0) == fvMbSolver().m_lsCutCellBaseLevel, "");
96 }
97
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, "");
105
106 // If fvMbSolver is inactive it does not have any cells
107 if(fvMbSolver().isActive()) {
108 // Check that the fv-solver-cell-count is correct!
109 ASSERT(fvMbSolver().a_noCells(), "");
110 }
111
112 if(!fvMbSolver().m_constructGField) ASSERT(g_multiSolverGrid, "");
113
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,
118 "");
119 }
120}
121
126template <MInt nDim, class SysEqn>
128 TRACE();
129
144 m_outsideDefault = true;
145 if(Context::propertyExists("outsideDefault", m_fvSolverId)) {
146 m_outsideDefault = Context::getSolverProperty<MBool>("outsideDefault", m_fvSolverId, AT_, &m_outsideDefault);
147 }
148
162 m_allowLsInterpolation = false;
163 m_allowLsInterpolation =
164 Context::getSolverProperty<MBool>("allowLsInterpolation", m_fvSolverId, AT_, &m_allowLsInterpolation);
165}
166
167
172template <MInt nDim, class SysEqn>
174 TRACE();
175
176 if(fvMbSolver().m_constructGField) return;
177
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))));
185 }
186#endif
187 }
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))));
195 }
196#endif
197 }
198
199 if(!lsSolver().m_levelSetMb) return;
200
201
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, "");
207 }
208 }
209 }
210#endif
211}
212
217template <MInt nDim, class SysEqn>
219 TRACE();
220
221 if(fvMbSolver().m_constructGField) return;
222
223 if(!fvMbSolver().m_levelSetMb) return;
224
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, "");
230 }
231 }
232 }
233#endif
234}
235
240template <MInt nDim, class SysEqn>
242 TRACE();
243
244 if(!lsSolver().m_closeGaps) return;
245 if(lsSolver().m_levelSetMb && fvMbSolver().m_constructGField) return;
246
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));
251 ASSERT(gc > -1, "");
252 ASSERT(lsSolver().a_potentialGapCellClose(gc) > 0
253 && lsSolver().a_potentialGapCellClose(gc) <= fvMbSolver().m_noEmbeddedBodies,
254 "");
255 }
256 }
257#endif
258}
259
260
264template <MInt nDim, class SysEqn>
266 TRACE();
267
268 for(MInt s = 0; s < lsSolver().m_noSets; s++) {
269 fvMbSolver().m_levelSetValues[s].resize(fvMbSolver().a_noCells());
270 }
271
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();
276 if(lsId > -1) {
277 if(fvMbSolver().a_hasProperty(fc, FvCell::IsMovingBnd)) {
278 // Interplate levelset for cut-cells
279 // direct interpolation from ls to fv for only 1 level difference
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);
283 } else {
284 fvMbSolver().a_levelSetFunction(fc, s) = lsSolver().a_levelSetFunctionG(fv2lsIdParent(fc), s);
285 }
286 }
287 }
288 }
289}
290
291
296template <MInt nDim, class SysEqn>
298 TRACE();
299 // Nothing to transfer if fvMb is inactive!
300 if(!fvMbSolver().isActive()) return;
301
302 if(exchangeLVS) {
303 // lsSolver().startLoadTimer(AT_);
304 // lsSolver().checkHaloCells();
305 // lsSolver().stopLoadTimer(AT_);
306 }
307
308#ifdef COUPLING_DEBUG_
309 testCoupling();
310#endif
311
312 std::map<MInt, MInt> interpolationParents;
313 interpolationParents.clear();
314
315 // Set outside default if lssolver is not active otherwise map
316 if(lsSolver().isActive()) {
317#ifdef _OPENMP
318#pragma omp parallel for
319#endif
320 for(MInt cellId = 0; cellId < a_noFvCells(); cellId++) {
321 // reset values with invalid/defaults
322 for(MInt set = 0; set < a_noLevelSetsMb(); set++) {
323 if(m_outsideDefault) {
324 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_outsideGValue();
325 } else {
326 fvMbSolver().a_levelSetValuesMb(cellId, set) = -a_outsideGValue();
327 }
328 fvMbSolver().a_associatedBodyIds(cellId, set) = -1;
329 }
330 const MInt gCellId = fv2lsId(cellId);
331 // direct transfer of matching cells
332 if(gCellId > -1) {
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);
336 }
337 } else {
338 // ls and fv grid differs
339
340 if(!g_multiSolverGrid) {
341 ASSERT(cellId >= a_noFvGridCells(), "");
342 } else { // multiSolverGrid, where the level and the grid-extension might differ!
343 if(cellId <= a_noFvGridCells()) { // grid-cell!
344 const MInt gCellParent = fv2lsIdParent(cellId);
345
346 if(gCellParent > -1) { // just level difference
347
348 if(m_noRfJumps == 0) {
349 // same maxRefinementLevel, meaning just a difference due to different refinement-widths
350 for(MInt set = 0; set < a_noLevelSetsMb(); set++) {
351 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
352 // ASSERT(!lsSolver().a_inBandG( gCellParent , set ), "");
353 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellParent, set);
354 }
355 } else {
356 // ls-interpolation towards higher fv-level
357 ASSERT(m_allowLsInterpolation, "");
358 if(fvMbSolver().a_isHalo(cellId) || lsSolver().a_isHalo(gCellParent)) continue;
359
360 // simple transfer if not a band-cell
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);
366 }
367 continue;
368 }
369
370 const MInt levelDifference = fvMbSolver().c_level(cellId) - lsSolver().a_level(gCellParent);
371 if(levelDifference == 1) {
372 // direct interpolation from ls to fv for only 1 level difference
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);
377
378 // interpolate levelset data
379 for(MInt set = 0; set < a_noLevelSetsMb(); set++) {
380 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
381 if(position < 0) {
382 // no valid interpolation stencil found
383 fvMbSolver().a_levelSetValuesMb(cellId, set) = a_levelSetFunctionG(gCellParent, set);
384 } else { // interpolation for all sets
385 const MFloat phi = lsSolver().interpolateLevelSet(interpolationCells, point, set);
386 fvMbSolver().a_levelSetValuesMb(cellId, set) = phi;
387 }
388 }
389 // build collected levelset data
390 buildCollectedLevelSet(cellId);
391
392 } else {
393 // add cells based on which the fv-interpolation needs to start
394 // that is cells for which the level difference is above 1
395 for(MInt set = 0; set < a_noLevelSetsMb(); set++) {
396 fvMbSolver().a_associatedBodyIds(cellId, set) = a_bodyIdG(gCellParent, set);
397 }
398
399 MInt parent = cellId;
400 for(MInt i = 0; i < levelDifference - 1; i++) {
401 parent = fvMbSolver().c_parentId(parent);
402 }
403 ASSERT(parent > -1, "");
404 // parent of this parent has a direct link, meaning that the values for the parent
405 // are set above!
406 ASSERT(fv2lsId(fvMbSolver().c_parentId(parent)) == gCellParent, "");
407 interpolationParents.insert(make_pair(parent, fvMbSolver().a_level(parent)));
408 }
409 }
410 }
411 }
412 }
413 }
414 }
415 } else {
416// lssolver is inactive
417#ifdef _OPENMP
418#pragma omp parallel for collapse(2)
419#endif
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();
424 } else {
425 fvMbSolver().a_levelSetValuesMb(cellId, set) = -a_outsideGValue();
426 }
427 fvMbSolver().a_associatedBodyIds(cellId, set) = -1;
428 }
429 }
430 }
431
432 // now interpolate through all childs
433 // iterate downwards level by level and exchange values in between!
434 if(m_allowLsInterpolation) {
435 std::list<MInt> newInterpolationParents;
436
437 for(MInt lvl = lsSolver().maxUniformRefinementLevel() + 1; lvl < fvMbSolver().maxRefinementLevel(); lvl++) {
438 fvMbSolver().exchangeLevelSetData();
439
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;
444
445 if(interpolationParents.empty()) continue;
446
447 ASSERT(m_noRfJumps > 1, "");
448
449 newInterpolationParents.clear();
450
451 for(auto it = interpolationParents.begin(); it != interpolationParents.end(); it++) {
452 const MInt parent = it->first;
453 const MInt level = it->second;
454 if(level > lvl) {
455 newInterpolationParents.push_back(parent);
456 } else {
457 for(MInt c = 0; c < fvMbSolver().grid().m_maxNoChilds; c++) {
458 const MInt childId = fvMbSolver().c_childId(parent, c);
459 if(childId < 0) {
460 continue;
461 }
462 interpolateLsFV(parent, childId);
463 if(!fvMbSolver().c_isLeafCell(childId)) {
464 newInterpolationParents.push_back(childId);
465 }
466 }
467 }
468 }
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)));
473 }
474 }
475 }
476
477 if(exchangeLVS) fvMbSolver().exchangeLevelSetData();
478
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);
486 }
487 }
488 }
489
490 testLsValues();
491}
492
498template <MInt nDim, class SysEqn>
500 TRACE();
501
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)};
505
506 std::function<MBool(const MInt, const MInt)> alwaysTrue = [&](const MInt, const MInt) { return true; };
507
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;
512
513 for(MInt set = 0; set < a_noLevelSetsMb(); set++) {
514 if(position < 0) {
515 fvMbSolver().a_levelSetValuesMb(to, set) = fvMbSolver().a_levelSetValuesMb(from, set);
516 } else {
517 MFloat phi = interpolateLevelSetMb(interpolationCells, point, set);
518 fvMbSolver().a_levelSetValuesMb(to, set) = phi;
519 }
520 }
521 buildCollectedLevelSet(to);
522}
523
527template <MInt nDim, class SysEqn>
529 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
530 MInt position = 0;
531
532 position = lsSolver().setUpLevelSetInterpolationStencil(cellId, interpolationCells, point);
533
534 // Interpolate level set
535 if(position > -1) {
536 return lsSolver().interpolateLevelSet(interpolationCells, point, set);
537 } else {
538 return lsSolver().a_levelSetFunctionG(cellId, set);
539 }
540}
541
545template <MInt nDim, class SysEqn>
546MFloat LsFvMb<nDim, SysEqn>::interpolateLevelSetMb(MInt* interpolationCells, MFloat* point, const MInt set) {
547 TRACE();
548
549 std::function<MFloat(const MInt, const MInt)> scalarField = [&](const MInt cellId, const MInt refSet) {
550 return static_cast<MFloat>(fvMbSolver().a_levelSetValuesMb(cellId, refSet));
551 };
552
553 std::function<MFloat(const MInt, const MInt)> coordinate = [&](const MInt cellId, const MInt id) {
554 return static_cast<MFloat>(fvMbSolver().c_coordinate(cellId, id));
555 };
556
557 return fvMbSolver().template interpolateFieldData<true>(&interpolationCells[0], &point[0], set, scalarField,
558 coordinate);
559}
560
561//---------------------------------------------------------------------------
562
568template <MInt nDim, class SysEqn>
570 TRACE();
571
572 if(globalTimeStep < 0) {
573 mode = 0;
574 }
575
576 // return if lssolver is not active
577 // if(!(lsSolver().isActive())) return;
578
579 if(!lsSolver().m_closeGaps) return;
580 if(lsSolver().m_noGapRegions <= 0) return;
581 if(lsSolver().m_levelSetMb && fvMbSolver().m_constructGField) return;
582
583#ifdef COUPLING_DEBUG_
584 testCoupling();
585#endif
586
587 // 1) reset has/had Gap-Cells
588 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
589 m_hadGapCells[region] = 0;
590 m_hasGapCells[region] = 0;
591 }
592
593 // 2) set a_wasGapCell, m_hadGapCells and initialize a_isGapCell
594 for(MInt fc = 0; fc < fvMbSolver().noInternalCells(); fc++) {
595 if(fvMbSolver().a_isGapCell(fc)) {
596 MInt lsId = fv2lsId(fc);
597 if(lsId < 0) {
598 if(fc > fvMbSolver().c_noCells()) continue;
599 lsId = fv2lsIdParent(fc);
600 }
601 ASSERT(lsId > -1, "");
602 // skip G0-regions
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) {
607 // don't set hadGapCells during initialisation, so that initGapClosure is still called
608 // at the first timeStep!
609 m_hadGapCells[regionId]++;
610 }
611 }
612 if(mode == 1) {
613 fvMbSolver().a_wasGapCell(fc) = fvMbSolver().a_isGapCell(fc);
614 } else {
615 fvMbSolver().a_wasGapCell(fc) = false;
616 }
617 fvMbSolver().a_isGapCell(fc) = false;
618 }
619
620
621 for(MInt fc = a_noFvGridCells(); fc < fvMbSolver().noInternalCells(); fc++) {
622 if(mode == 1) {
623 fvMbSolver().a_wasGapCell(fc) = fvMbSolver().a_isGapCell(fc);
624 } else {
625 fvMbSolver().a_wasGapCell(fc) = false;
626 }
627 fvMbSolver().a_isGapCell(fc) = false;
628 }
629
630 // 4) set a_isGapCell and hasGapCells
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);
635 if(fvId < 0) {
636 ASSERT(abs(abs(a_levelSetFunctionG(gCellId, 0)) - a_outsideGValue()) < 0.000001,
637 "ERROR, no fv-Cell found for relevant Gap-Cells!");
638 }
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]++;
645 }
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, "");
648 // if the fv-cell is not a leaf cell, find leaf-cell parent
649 // and set property for all corresponding childs
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]++;
657 }
658 }
659 }
660 }
661 }
662 }
663 }
664
665 testGapProperty();
666
667 // set isGapCell for g0regionId:
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);
673 if(fvId < 0) {
674 ASSERT(abs(abs(a_levelSetFunctionG(gCellId, 0)) - a_outsideGValue()) < 0.000001,
675 "ERROR, no fv-Cell found for relevant Gap-Cells!");
676 }
677 noG0regionCells++;
678 fvMbSolver().a_isGapCell(fvId) = true;
679 ASSERT(!lsSolver().a_nearGapG(gCellId), "");
680 }
681 }
682#if defined COUPLING_DEBUG_ || !defined NDEBUG
683 MPI_Allreduce(MPI_IN_PLACE, &noG0regionCells, 1, MPI_INT, MPI_SUM, lsSolver().mpiComm(), AT_, "INPLACE",
684 "noG0regionCells");
685 if(lsSolver().domainId() == 0) {
686 cerr << " No of g0-region Cells " << noG0regionCells << endl;
687 }
688#endif
689 }
690
691
692 // at the beginning of the restart
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);
696 }
697 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
698 m_hadGapCells[region] = m_hasGapCells[region];
699 }
700 }
701
702 // 3) exchange hadGapCells and hasGapCells for all regions
703 MPI_Allreduce(MPI_IN_PLACE, &m_hadGapCells[0], lsSolver().m_noGapRegions, MPI_INT, MPI_SUM, fvMbSolver().mpiComm(),
704 AT_, "INPLACE", "m_hadGapCells");
705
706 MPI_Allreduce(MPI_IN_PLACE, &m_hasGapCells[0], lsSolver().m_noGapRegions, MPI_INT, MPI_SUM, fvMbSolver().mpiComm(),
707 AT_, "INPLACE", "m_hasGapCells");
708
709 fvMbSolver().exchangeGapInfo();
710
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;
716 }
717 }
718#endif
719}
720
721
735template <MInt nDim, class SysEqn>
736void LsFvMb<nDim, SysEqn>::computeBodyProperties(MInt returnMode, MFloat* bodyData, MInt body, MFloat time) {
737 TRACE();
738
739 // TODO labels:COUPLER,LS,toremove remove this pass through function!
740 lsSolver().computeBodyPropertiesForced(returnMode, &bodyData[0], body, time);
741}
742
747template <MInt nDim, class SysEqn>
749 TRACE();
750
751 if(fvMbSolver().m_constructGField) return;
752
753 fvMbSolver().m_structureStep = 0;
754
755 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
756 fvMbSolver().m_gapState[region] = 0;
757 }
758
759 MBool& firstRun = m_static_updateLevelSetFlowSolver_firstRun;
760
761 if(firstRun
762 || (fvMbSolver().m_trackMovingBndry && globalTimeStep >= fvMbSolver().m_trackMbStart
763 && globalTimeStep < fvMbSolver().m_trackMbEnd)) {
764 testCoupling();
765
766 // 1) transfer Gap-Cell property
767 if(fvMbSolver().m_levelSetRans) {
768 transferLevelSetValues();
769 }
770 transferGapCellProperty(1);
771
772 // 2) transfer the levelSet Data to the flow solver
773 transferLevelSetFieldValues(true);
774
775 // 3) check gap cell-status
776 setGapState();
777
778 // 4) mark gap cells with status and region
779 initFvGapCells();
780
781 // 5) transfer body position/velocity/acceleration
782 transferBodyProperties();
783 }
784
785 firstRun = false;
786}
787
801template <MInt nDim, class SysEqn>
803 TRACE();
804
805 if(!lsSolver().m_closeGaps || lsSolver().m_gapInitMethod == 0) return;
806
807 MBool(&earlyOpened)[m_maxNoGapRegions] = m_static_setGapState_earlyOpened;
808 MBool& first = m_static_setGapState_first;
809
810 if(first) {
811 first = false;
812 for(MInt region = 0; region < m_maxNoGapRegions; region++) {
813 earlyOpened[region] = false;
814 }
815 }
816
817 MBoolScratchSpace forceNoGaps(lsSolver().m_noGapRegions, AT_, "forceNoGaps");
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;
832 }
833 }
834 }
835
836 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
837 if(forceNoGaps[region]) {
838 if(!earlyOpened[region] && globalTimeStep > 0 && globalTimeStep != lsSolver().m_restartTimeStep) {
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
843 << endl;
844 }
845
846 } else if(earlyOpened[region] || globalTimeStep == 0 || globalTimeStep == lsSolver().m_restartTimeStep) {
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;
851 }
852 }
853 }
854 if(!forceNoGaps[region] && earlyOpened[region]) {
855 lsSolver().m_minGapWidthDt1[region] = 11 * lsSolver().m_outsideGValue;
856 earlyOpened[region] = false;
857 }
858 }
859
860 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
861 if(forceNoGaps[region]) continue;
862
863 if(earlyOpened[region]) {
864 MFloat eps2 =
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;
870 }
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;
876 }
877 continue;
878 }
879
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 << " "
884 << endl;
885 }
886 ASSERT(m_hasGapCells[region] && !m_hadGapCells[region],
887 to_string(m_hasGapCells[region]) + " " + to_string(m_hadGapCells[region]));
888
889 fvMbSolver().m_gapState[region] = -2;
890
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;
895 }
896 fvMbSolver().m_gapState[region] = 2;
897 ASSERT(m_hadGapCells[region] && !m_hasGapCells[region], "");
898
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]) {
902 // gap-shrinking at restart for >=
903 if(fvMbSolver().domainId() == 0) {
904 cerr << "--> Ls Gap is Shrinking for region " << region << " at timestep " << globalTimeStep << endl;
905 }
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]));
909
910 } else {
911 MFloat eps2 =
912 lsSolver().c_cellLengthAtLevel(lsSolver().a_maxGCellLevel(0)) * sqrt(nDim) * lsSolver().m_gapDeltaMin;
913 MFloat deviation = (fabs(lsSolver().m_minGapWidth[region] - eps2) / eps2) * 100;
914 // for small deviations from the gap-Closing distance, check if any gap-Cells are remaining!
915 // if non are remaining, initialize gap-Opening
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;
921 }
922 fvMbSolver().m_gapState[region] = 2;
923 ASSERT(m_hadGapCells[region] && !m_hasGapCells[region], "");
924 earlyOpened[region] = true;
925
926 continue;
927 }
928 }
929 if(fvMbSolver().domainId() == 0) {
930 cerr << "--> Ls Gap is Widening for region " << region << " at timestep " << globalTimeStep << endl;
931 }
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]));
936 }
937
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;
942 }
943 fvMbSolver().m_gapState[region] = 1;
944 ASSERT(!m_hasGapCells[region] && !m_hadGapCells[region], "");
945 }
946 }
947
948
949 // possible trigger adaptation due to gap Opening/shrinking
950 /*
951 if(globalTimeStep != lsSolver().m_restartTimeStep && lsSolver().m_engineSetup) {
952 for(MInt region = 0; region < lsSolver().m_noGapRegions; region++) {
953 const MInt state = fvMbSolver().m_gapState[region];
954 if(fvMbSolver().m_gapState[region] == 2) { // opening always forces adaptation!
955 if(fvMbSolver().domainId() == 0) {
956 cerr << "Forcing Adaptation due to gap-state " << state << " of region " << region << endl;
957 }
958 lsSolver().m_forceAdaptation = true;
959 } else if(fvMbSolver().m_gapState[region] == -1 && fvMbSolver().maxLevel() != fvMbSolver().maxRefinementLevel()
960 && lsSolver().m_minGapWidth[region]
961 < (lsSolver().c_cellLengthAtLevel(lsSolver().a_maxGCellLevel(0)) * lsSolver().m_gapDeltaMin)) {
962 if(fvMbSolver().domainId() == 0) {
963 cerr << "Forcing Adaptation due to gap-state " << state << " of region " << region << endl;
964 }
965 lsSolver().m_forceAdaptation = true;
966 }
967 }
968 }
969 */
970}
971
972
979template <MInt nDim, class SysEqn>
981 fvMbSolver().m_gapCells.clear();
982 // tuple of cellId, regionId, GapCell-Type (for isGapCell > 0, for wasGapCell < 0)
983
984 if(!lsSolver().m_closeGaps) return;
985
986 if(globalTimeStep < 0) return;
987
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,
994 "Invalid GapState");
995 }
996
997 if(lsSolver().m_G0regionId > -1) fvMbSolver().m_noneGapRegions = false;
998 if(fvMbSolver().m_noneGapRegions) return;
999 }
1000
1001 MIntScratchSpace lsInfo(fvMbSolver().c_noCells(), 3, AT_, "lsInfo");
1002
1003 // a) list all Gap-Cells and previous Gap-Cells
1004 // Gap-Cells have default Types:
1005 // 0: Gap-Cells that were not a Gap-Cell before
1006 // -1: Gap-Cells that were a Gap-Cell before
1007 // 1: Cells that are not a Gap-Cell anymore but used to be a GapCell
1008 for(MInt cellId = 0; cellId < fvMbSolver().noInternalCells(); cellId++) {
1009 if(fvMbSolver().a_hasProperty(cellId, FvCell::IsSplitChild)) continue;
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));
1018 }
1019 }
1020
1021 fvMbSolver().exchangeData(&lsInfo[0], 3);
1022
1023 for(MInt cellId = fvMbSolver().noInternalCells(); cellId < fvMbSolver().c_noCells(); cellId++) {
1024 if(fvMbSolver().a_hasProperty(cellId, FvCell::IsSplitChild)) continue;
1025 if(fvMbSolver().a_isBndryGhostCell(cellId)) continue;
1026
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));
1032 }
1033 }
1034
1035 fvMbSolver().m_initGapCell = true;
1036}
1037
1041template <MInt nDim, class SysEqn>
1043 TRACE();
1044
1045 // PRE LS
1046 if(recepiStep == 0) {
1047 // check that the timeStep matches!
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));
1053 }
1054 }
1055
1056 if(fvMbSolver().grid().wasAdapted()) {
1057 if(fvMbSolver().m_levelSetRans) {
1058 transferLevelSetValues();
1059 }
1060 }
1061}
1062
1066template <MInt nDim, class SysEqn>
1068 TRACE();
1069
1070 // POST LS
1071 if(recepiStep == 0) {
1072 updateFlowSolver();
1073 } else { // POST FVMB
1074
1075 // update time and timeStep in the levelSet-solver
1076 // the timeStep is then increased in preTimeStep by the individual solver!
1077 transferTimeStep();
1078
1079 fvMbSolver().m_initGapCell = false;
1080 }
1081}
1082
1083
1087template <MInt nDim, class SysEqn>
1089 TRACE();
1090
1091 // POST LS
1092 if(solverId == 0) {
1093 // 1) is/was Gap cell property is not exchanged in the fv-solver balance
1094 if(fvMbSolver().m_levelSetRans) {
1095 transferLevelSetValues();
1096 }
1097 transferGapCellProperty(0);
1098
1099 // 2) ls-values are not exchanged in the fv-solver balance
1100 transferLevelSetFieldValues(true);
1101
1102 // 3) gapState information is available on all ranks
1103
1104 // 4) set fv-gap cells again
1105 initFvGapCells();
1106 }
1107}
1108
1112template <MInt nDim, class SysEqn>
1114 TRACE();
1115
1116 if(solverId > 0) return; // call only once after the ls-solver!
1117
1118 if(globalTimeStep > -1) { // after the lsSolver!
1119
1120
1121 // 1) transfer levelset values again after
1122 // they have been set completely in the ls-solver!
1123 // they are not interpolated in the fv-solver interpolation!
1124 transferLevelSetFieldValues(true);
1125 if(fvMbSolver().m_levelSetRans) {
1126 transferLevelSetValues();
1127 }
1128
1129 // 2) is/was Gap cell property is handeled in the fv-solver during the adaptation
1130 // => transferGapCellProperty is not necessary!
1131
1132 // 3) gapState information does not change during adaptation!
1133
1134 // 4) set fv-gap cells again, as they are not swapped in the fv-solver-adaptation!
1135 initFvGapCells();
1136
1137 // 5) correct the time if the timeStep changes during adaptation!
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 ";
1144 }
1145
1146 fvMbSolver().setTimeStep();
1147 // NOTE: the sweptVolume is updated according to the timeStep change in setTimeStep!
1148
1149
1150 const MFloat newTimeStep = fvMbSolver().timeStep(true);
1151 if(fvMbSolver().domainId() == 0) {
1152 cerr << "change from " << oldTimeStep << " to " << newTimeStep << endl;
1153 }
1154
1155 // revert time and transfer the new timeStep!
1156 lsSolver().m_time = lsSolver().m_time - oldTimeStep;
1157
1158 // reverse time in the fvmb-solver!
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;
1162
1163 transferTimeStep();
1164 lsSolver().m_time = lsSolver().m_time + newTimeStep;
1165
1166 fvMbSolver().advanceTimeStep();
1167
1168 // compute the levelSet movement to the new TimeStep
1169 lsSolver().solutionStep();
1170 lsSolver().postTimeStep();
1171
1172 // update levelsetfield!
1173 transferLevelSetFieldValues(true);
1174 if(fvMbSolver().m_levelSetRans) {
1175 transferLevelSetValues();
1176 }
1177 }
1178
1179
1180 } else if(globalTimeStep < 0 && fvMbSolver().m_geometryChange != nullptr) {
1181 // caution: lsSolver().m_geometryChange has already been reset to default!
1182
1183 transferLevelSetFieldValues(true);
1184 if(fvMbSolver().m_levelSetRans) {
1185 transferLevelSetValues();
1186 }
1187
1188 // init BndryLayer again to set wasInactive again
1189 fvMbSolver().initBndryLayer();
1190
1191 // transfer oldG0 cells to the fv-block to apply possible damping in this area!
1192 /*
1193 if (!lsSolver().m_oldG0Cells.empty()) {
1194 for(auto it = lsSm_oldG0Cells.begin(); it != m_oldG0Cells.end(); it++) {
1195 const MInt cellId = it->first;
1196 const MInt set = it->second;
1197
1198 }
1199 */
1200 }
1201}
1202
1206template <MInt nDim, class SysEqn>
1208 TRACE();
1209
1210 // if(globalTimeStep < 0 || m_allowLsInterpolation) {
1211 // handels the transfer during the initial adaptation and
1212 // also the interpolation of the levelset if the fv-solver is refined further!
1213 // TODO labels:COUPLER,FVMB first simple interpolation approximation in the fvmb-solver refineCell function!
1214 // then this call will be unncessary!
1215 // the ls-value will be updated in finalizeAdaptation, this is just for the sensors!
1216 transferLevelSetFieldValues(true);
1217 if(fvMbSolver().m_levelSetRans) {
1218 transferLevelSetValues();
1219 }
1220 //}
1221
1222 updateLevelSet();
1223}
1224
1228template <MInt nDim, class SysEqn>
1230 TRACE();
1231
1232 updateLevelSet();
1233}
1234
1239template <MInt nDim, class SysEqn>
1241 ASSERT(!fvMbSolver().m_constructGField, "ERROR: invalid function call!");
1242
1243 switch(fvMbSolver().m_levelSetAdaptationScheme) {
1244 case 0:
1245 updateLevelSetOutsideBandPar();
1246 break;
1247 case 2:
1248 return; // don't update OutsideCells at all!
1249 break;
1250 case 1:
1251 default:
1252 fvMbSolver().updateLevelSetOutsideBand();
1253 break;
1254 }
1255}
1256
1257
1263template <MInt nDim, class SysEqn>
1265 MFloatScratchSpace points(lsSolver().a_noG0Cells(0), nDim, AT_, "points");
1266 MFloatScratchSpace pointsLVS(lsSolver().a_noG0Cells(0), AT_, "pointsLVS");
1267
1268 //--------------------
1269 MInt tempCnt = 0;
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);
1275 }
1276 tempCnt++;
1277 }
1278
1279 // exchange points with all other processors:
1280 MIntScratchSpace noPoints(1, AT_, "noPoints");
1281 MIntScratchSpace globalNoPoints(fvMbSolver().noDomains(), AT_, "globalNoPoints");
1282 noPoints[0] = a_noG0Cells(0);
1283 MPI_Allgather(noPoints.getPointer(), 1, MPI_INT, globalNoPoints.getPointer(), 1, MPI_INT, fvMbSolver().mpiComm(), AT_,
1284 "noPoints.getPointer()", "globalNoPoints.getPointer()");
1285
1286 MIntScratchSpace displs(fvMbSolver().noDomains(), AT_, "displs");
1287 MIntScratchSpace recCounts(fvMbSolver().noDomains(), AT_, "recCounts");
1288 MInt dataBlockSize = nDim + 1;
1289 noPoints[0] = 0;
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];
1294 }
1295
1296 // gather all points from all other processors:
1297 MFloatScratchSpace globalPoints(noPoints[0], nDim, AT_, "globalPoints");
1298 MFloatScratchSpace globalPointsLVS(noPoints[0], AT_, "globalPointsLVS");
1299 MFloatScratchSpace tmpsend(globalNoPoints[fvMbSolver().domainId()] * dataBlockSize, AT_, "tmpsend");
1300 MFloatScratchSpace tmpreceive(noPoints[0] * dataBlockSize, AT_, "tmpreceive");
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];
1305 }
1306
1307 MPI_Allgatherv(tmpsend.getPointer(), globalNoPoints[fvMbSolver().domainId()] * dataBlockSize, MPI_DOUBLE,
1308 tmpreceive.getPointer(), recCounts.getPointer(), displs.getPointer(), MPI_DOUBLE,
1309 fvMbSolver().mpiComm(), AT_, "tmpsend.getPointer()", "tmpreceive.getPointer()");
1310
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];
1315 }
1316
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);
1322 } else {
1323 fvMbSolver().a_levelSetValuesMb(cell, 0) = -fvMbSolver().c_cellLengthAtLevel(0);
1324 }
1325 for(MInt p = 0; p < noPoints[0]; p++) {
1326 MFloat distTmp = F0;
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));
1331 }
1332 distTmp = sqrt(distTmp);
1333 if(fvMbSolver().a_levelSetValuesMb(cell, 0) >= F0) {
1334 lvsValTmp += distTmp;
1335 } else {
1336 lvsValTmp -= distTmp;
1337 }
1338 if(abs(lvsValTmp) < abs(fvMbSolver().a_levelSetValuesMb(cell, 0))) {
1339 fvMbSolver().a_levelSetValuesMb(cell, 0) = lvsValTmp;
1340 }
1341 }
1342 }
1343}
1344
1345
1350template <MInt nDim, class SysEqn>
1352 TRACE();
1353
1354 MInt timeStep = 0;
1355 MFloat time = 0;
1356 MFloat physicalTime = -std::numeric_limits<MFloat>::max();
1357
1358 if(fvMbSolver().isActive() && fvMbSolver().m_restart) {
1359 stringstream varFileName;
1360
1361 varFileName << fvMbSolver().restartDir() << "restartVariables";
1362 if(!fvMbSolver().m_useNonSpecifiedRestartFile) {
1363 if(!fvMbSolver().m_multipleFvSolver) {
1364 varFileName << "_" << fvMbSolver().m_restartTimeStep;
1365 } else {
1366 varFileName << fvMbSolver().solverId() << "_" << fvMbSolver().m_restartTimeStep;
1367 }
1368 }
1369 varFileName << ParallelIo::fileExt();
1370
1371 if(fvMbSolver().domainId() == 0) {
1372 fvMbSolver().loadRestartTime((varFileName.str()).c_str(), timeStep, time, physicalTime);
1373 } else {
1374 physicalTime = 0;
1375 }
1376 } else if(fvMbSolver().isActive()) {
1377 physicalTime = 0;
1378 }
1379
1380 if(fvMbSolver().isActive()) {
1381 MPI_Allreduce(MPI_IN_PLACE, &physicalTime, 1, MPI_DOUBLE, MPI_MAX, fvMbSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1382 "physicalTime");
1383 }
1384
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",
1388 "physicalTime");
1389 }
1390 }
1391
1392 ASSERT(physicalTime > -fvMbSolver().m_eps, "");
1393 return physicalTime;
1394}
1395
1396
1401template <MInt nDim, class SysEqn>
1402void LsFvMb<nDim, SysEqn>::lsGapInfo(const MInt fvCellId, MInt* info) {
1403 TRACE();
1404
1405 MInt gCellId = fv2lsId(fvCellId);
1406
1407 if(gCellId < 0) {
1408 ASSERT(m_allowLsInterpolation, "");
1409 gCellId = fv2lsIdParent(fvCellId);
1410 }
1411 ASSERT(gCellId > -1, "");
1412 MInt regionId = a_potentialGapCellClose(gCellId) - 2;
1413 ASSERT(regionId < fvMbSolver().m_noGapRegions, "");
1414 // labels:COUPLER G0region-hack
1415 if(lsSolver().m_G0regionId > -1 && a_potentialGapCellClose(gCellId) == lsSolver().m_G0regionId) {
1416 regionId = fvMbSolver().m_noGapRegions;
1417 }
1418 if(lsSolver().m_gapInitMethod > 0) {
1419 ASSERT(regionId > -1, "");
1420 }
1421
1422 info[0] = regionId;
1423 info[1] = lsSolver().a_bodyIdG(gCellId, 0);
1424 info[2] = lsSolver().a_secondBodyId(gCellId);
1425}
1426
1430template <MInt nDim, class SysEqn>
1432 TRACE();
1433
1434 // copies the bodyToSet information from the levelset solver to the fvmb-solver
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;
1440
1441 fvMbSolver().updateGeometry();
1442
1443 // set the time in the lsSolver:
1444 lsSolver().m_time = -99;
1445 lsSolver().m_time = restartTime();
1446
1447 if(lsSolver().isActive() && fvMbSolver().isActive()) {
1448 ASSERT(fabs(lsSolver().m_time - fvMbSolver().m_physicalTime) < fvMbSolver().m_eps, "");
1449 }
1450
1451 checkProperties();
1452
1453 // check for any in-active ranks
1454 MInt noInactiveFv = 0;
1455 MInt noInactiveLs = 0;
1456 if(!fvMbSolver().isActive()) {
1457 noInactiveFv++;
1458 }
1459 if(!lsSolver().isActive()) {
1460 noInactiveLs++;
1461 }
1462
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;
1467 }
1468 if(noInactiveLs > 0) {
1469 cerr0 << "Ls solver has " << noInactiveLs << " inactive ranks!" << endl;
1470 }
1471
1472 // initialise the g-Field in the fv-solver!
1473 transferLevelSetFieldValues(true);
1474 if(fvMbSolver().m_levelSetRans) {
1475 transferLevelSetValues();
1476 }
1477
1478 // can only be called after the levelset values have been set!
1479 fvMbSolver().initBndryLayer();
1480
1481 // TODO labels:COUPLER,FVMB,LS extend own shorter/simplified/easier/better coupler initBodyProperties version!
1482 // don't call initBodyProperties() in the fvmb-solver at all for constructedGField with
1483 // levelset motion function!
1484 if(fvMbSolver().m_LsMovement) {
1485 initBodyProperties();
1486 }
1487}
1488
1492template <MInt nDim, class SysEqn>
1494 TRACE();
1495
1496 // ls-Solver time step is chosen corresponding to the fv-time step
1497 transferTimeStep();
1498
1499 if(fvMbSolver().m_levelSetRans) {
1500 transferLevelSetValues();
1501
1502 fvMbSolver().rhs();
1503 fvMbSolver().rhsBnd();
1504 fvMbSolver().advanceSolution();
1505 fvMbSolver().advanceBodies();
1506 }
1507}
1508
1512template <MInt nDim, class SysEqn>
1514 TRACE();
1515
1516 if(lsSolver().isActive() && fvMbSolver().isActive()) {
1517 ASSERT(fabs(lsSolver().m_time - fvMbSolver().m_physicalTime) < fvMbSolver().m_eps, "");
1518 }
1519
1520 if(currentSolver == m_lsSolverId) {
1521 updateFlowSolver();
1522 if(lsSolver().m_LsRotate) {
1523 transferBodyRadius();
1524 }
1525 }
1526}
1527
1534template <MInt nDim, class SysEqn>
1536 TRACE();
1537
1538 // If fvMbSolver is inactive on one rank we need to take the time step from another rank!
1539 MFloat fvTimeStep = std::numeric_limits<MFloat>::max();
1540
1541 // Get local fv time step
1542 if(fvMbSolver().isActive()) {
1543 fvTimeStep = fvMbSolver().timeStep(true);
1544 }
1545
1546 // Get minimum fv time step on all active ls ranks
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",
1550 "fvTimeStep");
1551 }
1552 }
1553
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!.");
1560 }
1561 lsSolver().m_timeStep = fvTimeStep;
1562}
1563
1567template <MInt nDim, class SysEqn>
1569 TRACE();
1570
1571 const MInt noBodies = lsSolver().m_noEmbeddedBodies;
1572 for(MInt b = 0; b < noBodies; b++) {
1573 fvMbSolver().m_bodyRadius[b] = lsSolver().m_bodyRadius[b];
1574 }
1575}
1576
1585template <MInt nDim, class SysEqn>
1587 TRACE();
1588
1589 if(!fvMbSolver().m_LsMovement) return;
1590
1591 // the fv-time has not been increased yet, but will be first thing in preTimeStep!
1592 const MFloat nextFvTime = fvMbSolver().m_physicalTime + fvMbSolver().timeStep();
1593
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);
1598
1599 if(fvMbSolver().m_movingBndryCndId == 3008 || fvMbSolver().m_movingBndryCndId == 3010) {
1600 computeBodyProperties(4, &fvMbSolver().m_bodyTemperature[body], body, nextFvTime);
1601 }
1602 }
1603
1604 if(lsSolver().m_LsRotate) {
1605 transferAngularVelocity();
1606 }
1607}
1608
1609
1614template <MInt nDim, class SysEqn>
1616 TRACE();
1617
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];
1623 } else {
1624 fvMbSolver().m_bodyAngularVelocity[b * nDim + i] = NAN;
1625 fvMbSolver().m_bodyAngularAcceleration[b * nDim + i] = NAN;
1626 }
1627 }
1628 }
1629}
1630
1634template <MInt nDim, class SysEqn>
1636 TRACE();
1637
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);
1646
1647 //
1648 if(phi0 >= F0 && phi1 >= F0) {
1649 if(phi1 < phi0) {
1650 body0 = body1;
1651 }
1652 phi0 = mMin(phi0, phi1);
1653 } else if(phi0 <= F0 && phi1 <= F0) {
1654 if(abs(phi1) > abs(phi0)) {
1655 body0 = body1;
1656 }
1657 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
1658 } else if(phi0 * phi1 <= F0) {
1659 if(phi0 < F0) {
1660 // phi0 = phi0;
1661 } else {
1662 phi0 = phi1;
1663 body0 = body1;
1664 }
1665 }
1666
1667 fvMbSolver().a_levelSetValuesMb(cellId, 0) = phi0;
1668 fvMbSolver().a_associatedBodyIds(cellId, 0) = body0;
1669 }
1670 }
1671}
1672
1676template <MInt nDim, class SysEqn>
1678 TRACE();
1679
1680 const MFloat time = fvMbSolver().m_physicalTime;
1681
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);
1686
1687 if(fvMbSolver().m_movingBndryCndId == 3008 || fvMbSolver().m_movingBndryCndId == 3010) {
1688 computeBodyProperties(4, &fvMbSolver().m_bodyTemperature[body], body, time);
1689 }
1690 }
1691}
1692
1693template class LsFvMb<2, FvSysEqnNS<2>>;
1694template class LsFvMb<3, FvSysEqnNS<3>>;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
Definition: lsfvmb.h:24
void lsGapInfo(const MInt, MInt *)
returns the gap region for a given fvCell
Definition: lsfvmb.cpp:1402
LsFvMb(const MInt couplingId, LsSolver *ls, FvMbSolver *fvMb)
Definition: lsfvmb.cpp:24
void init() override
performs the coupling after solver initialization
Definition: lsfvmb.cpp:1431
void updateLevelSet()
update the levelset outside of the band default should be case 2 -> don't do anything!
Definition: lsfvmb.cpp:1240
void testGapProperty()
transfers the LevelSetValues from the levelset to the moving boundary Part
Definition: lsfvmb.cpp:241
MFloat interpolateLevelSet(MInt cellId, MFloat *point, MInt set)
Definition: lsfvmb.cpp:528
void transferTimeStep()
transfers the gcell time step from the fvMbSolver! time should already be matching!
Definition: lsfvmb.cpp:1535
void initData()
Initialize coupling-class-specific Data.
Definition: lsfvmb.cpp:38
void transferBodyProperties()
transfer current body properties from the ls-Solver to the fv-Solver bodyPosition bodyVelocity bodyAc...
Definition: lsfvmb.cpp:1586
void readProperties()
reads lsfvmb-coupling-specific data
MFloat interpolateLevelSetMb(MInt *interpolationCells, MFloat *point, const MInt set)
Definition: lsfvmb.cpp:546
void finalizeAdaptation(const MInt) override
finalizeAdaptation
Definition: lsfvmb.cpp:1113
void preCouple(MInt recepiStep) override
preCoupler
Definition: lsfvmb.cpp:1042
void transferLevelSetFieldValues(MBool)
transfers the LevelSetValues for all cells from the levelset to the moving boundary Part
Definition: lsfvmb.cpp:297
void transferBodyRadius()
Copies the bodyRadius from the LS-solver into the FV-solver.
Definition: lsfvmb.cpp:1568
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...
Definition: lsfvmb.cpp:736
MFloat restartTime()
return restart time for lsSolver, when the fvSolver is not initialised yet!
Definition: lsfvmb.cpp:1351
void setGapState()
Sets the Gap-State in the fvmb-solver (stati are the same for all domains!) possible Gap-States:
Definition: lsfvmb.cpp:802
void postCouple(MInt recipeStep=0) override
postCoupler
Definition: lsfvmb.cpp:1067
void transferLevelSetValues()
Sets the Levelset-Values in fvSolver.
Definition: lsfvmb.cpp:265
void updateFlowSolver()
Updates the fv-mb-solver flow solver (after a completed levelSet TimeStep and finalizeLevelSet() )
Definition: lsfvmb.cpp:748
void updateLevelSetOutsideBandPar()
computes an approximate level set value for cells outside the level-set computing band should not be ...
Definition: lsfvmb.cpp:1264
void finalizeCouplerInit() override
performs the final coupling after finalization
Definition: lsfvmb.cpp:1493
void testLsValues()
transfers the LevelSetValues from the levelset to the moving boundary Part
Definition: lsfvmb.cpp:218
void finalizeBalance(const MInt) override
called after each solver-balance
Definition: lsfvmb.cpp:1088
void buildCollectedLevelSet(const MInt)
build the combined levelSet for the given cellId
Definition: lsfvmb.cpp:1635
void transferAngularVelocity()
Writes the angular velocity and the angular acceleration from the LS-solver into the FV-solver.
Definition: lsfvmb.cpp:1615
void interpolateLsFV(const MInt, const MInt)
interpolate levelset values on the fv-grid
Definition: lsfvmb.cpp:499
void postAdaptation() override
finalizeAdaptation
Definition: lsfvmb.cpp:1207
void initFvGapCells()
Initialises fv-Gap Cells for gapHandling (must be called each timeStep before the gapHandling call in...
Definition: lsfvmb.cpp:980
void initBodyProperties()
initialise the body properties in the fvmb-solver based
Definition: lsfvmb.cpp:1677
void transferGapCellProperty(MInt mode)
Sets the gap-cell-property mode 1 : regular call each timeStep (advance is/was-GapCell) mode 0 : init...
Definition: lsfvmb.cpp:569
void testCoupling()
transfers the LevelSetValues from the levelset to the moving boundary Part
Definition: lsfvmb.cpp:173
void prepareAdaptation() override
finalizeAdaptation
Definition: lsfvmb.cpp:1229
void finalizeSubCoupleInit(MInt) override
performs the coupling in solver finalization
Definition: lsfvmb.cpp:1513
void checkProperties()
Checks property-data which is read in by both ls-and Fv-Solver.
Definition: lsfvmb.cpp:75
This class is a ScratchSpace.
Definition: scratch.h:758
T * getPointer() const
Deprecated: use begin() instead!
Definition: scratch.h:316
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
@ IsSplitChild
cell is a split child
@ IsMovingBnd
cell at moving boundary
MInt globalTimeStep
MBool g_multiSolverGrid
InfoOutFile m_log
std::ostream cerr0
constexpr MLong IPOW2(MInt x)
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
MInt id
Definition: maiatypes.h:71
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