21#define MAX_NO_LS_BNDRY_CND 10
42 if(grid().azimuthalPeriodicity() && nDim == 2) {
43 mTerm(1,
"Azimuthal periodicity is untested in 2D and it doesn't make sense in 2D!");
48 m_levelSetMb = propertiesGroups[
LEVELSETMB] || m_levelSetLb;
52 m_levelSetRans = propertiesGroups[
LS_RANS];
59 if((levelSet || m_levelSetRans) && !m_levelSetMb && !m_combustion && !m_LSSolver && !m_freeSurface) {
64 cerr <<
"m_levelSetMb : " << m_levelSetMb << endl;
65 cerr <<
"m_combustion : " << m_combustion << endl;
66 cerr <<
"m_LSSolver : " << m_LSSolver << endl;
67 cerr <<
"m_levelSetRans: " << m_levelSetRans << endl;
68 cerr <<
"m_levelSetFv : " << m_levelSetFv << endl;
69 cerr <<
"m_freeSurface: " << m_freeSurface << endl;
72 ASSERT(m_LSSolver || m_levelSetMb || m_combustion || m_levelSetRans || m_levelSetFv || m_freeSurface,
73 "Unintentianal-ls-solver initialisation?!");
75 readLevelSetProperties();
76 allocateLevelSetMemory();
88 ASSERT(m_LSSolver || m_combustion || m_levelSetMb || m_levelSetRans || m_levelSetFv || m_freeSurface,
94 this->setHaloCellsOnInactiveRanks();
98 grid().updateLeafCellExchange();
101 if(m_useNonSpecifiedRestartFile) {
106 initAzimuthalExchange();
108 if(m_levelSetMb && m_constructGField)
return;
111 restartLocalizedLevelSetCG();
113 initLocalizedLevelSetCG();
117 this->checkNoHaloLayers();
119 computeGCellTimeStep();
122 determineSteadyFlameLength();
132 setGCellBndryProperty();
134 if(!m_semiLagrange) {
135 computeNormalVectors();
139 finalizeLevelSetInitialization();
141 buildMultipleLevelSet();
145 if(!m_semiLagrange) {
146 determinePropagationSpeed();
149 if(m_restart && m_GFieldFromSTLInitCheck) {
150 writeRestartLevelSetFileCG(1,
"restartLSGridCG_restart",
"restartLSCG_restart");
160 m_maxFlameFrontPosition = (
MFloat*)
nullptr;
161 m_minFlameFrontPosition = (
MFloat*)
nullptr;
162 m_meanFlameFrontPosition = (
MFloat*)
nullptr;
164 mAlloc(m_maxFlameFrontPosition, nDim,
"m_maxFlameFrontPosition", -1000.0, AT_);
165 mAlloc(m_minFlameFrontPosition, nDim,
"m_minFlameFrontPosition", 1000.0, AT_);
166 mAlloc(m_meanFlameFrontPosition, nDim,
"m_meanFlameFrontPosition", F0, AT_);
169 m_cells.setMaxNoSets(m_maxNoSets);
172 if(m_combustion || m_freeSurface) {
174 m_lsCollectorMode = 0;
175 }
else if(m_semiLagrange) {
177 m_lsCollectorMode = 2;
178 if(!m_guaranteeReinit && m_STLReinitMode == 2) {
180 m_lsCollectorMode = 1;
185 ASSERT(m_LSSolver || m_levelSetFv || m_levelSetRans,
"");
186 m_lsCollectorMode = 3;
189 m_cells.setLsCollectorType(m_lsCollectorMode);
191 m_noBodiesToCompute = 0;
195 allocateRotatingLs();
198 mAlloc(m_semiLagrange_xShift_ref, m_noEmbeddedBodies * nDim,
"m_semiLagrange_xShift_ref", F0, AT_);
201 m_cells.setGapClosing(m_closeGaps);
202 m_cells.setMaxBodiesToCompute(m_noBodiesToCompute);
203 m_cells.setReconstructOldG(m_reconstructOldG);
204 m_cells.setRotatingLs(m_LsRotate);
205 m_cells.setReinit(m_guaranteeReinit || m_STLReinitMode != 2);
207 m_cells.reset(m_maxNoCells);
210 m_cells.fillContainingCell();
211 if(!m_reconstructOldG) m_cells.fillContainingDomain();
218 mAlloc(m_bandCells, m_maxNoSets,
"m_bandCells", AT_);
219 mAlloc(m_internalBandCells, m_maxNoSets,
"m_internalBandCells", AT_);
220 mAlloc(m_bandBndryCells, m_maxNoSets,
"m_bandBndryCells", AT_);
221 mAlloc(m_G0Cells, m_maxNoSets,
"m_G0Cells", AT_);
222 for(
MInt i = 0; i < m_maxNoSets; i++) {
223 m_bandCells[i].clear();
224 m_internalBandCells[i].clear();
225 m_bandBndryCells[i].clear();
226 m_G0Cells[i].clear();
228 mAlloc(m_bandLayer, (m_gShadowWidth + 1) * m_maxNoSets,
"m_bandLayer", 0, AT_);
229 mAlloc(m_internalBandLayer, (m_gShadowWidth + 1) * m_maxNoSets,
"m_internalBandLayer", 0, AT_);
231 if(!m_semiLagrange) {
232 mAlloc(m_gBndryCells, m_maxNoSets,
"m_gBndryCells", AT_);
233 for(
MInt i = 0; i < m_maxNoSets; i++) {
234 m_gBndryCells[i].clear();
238 m_localMarksteinLength =
nullptr;
239 if(m_useLocalMarksteinLength) {
240 mAlloc(m_localMarksteinLength, m_maxNoCells,
"m_localMarksteinLength", F0, AT_);
241 mTerm(1, AT_,
"code should be debugged for multiple sets");
245 if(!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2) {
246 mAlloc(m_cellList, m_maxNoCells,
"m_cellList", 0, AT_);
247 mAlloc(m_phiRatioCells, m_maxNoCells, 2 * nDim * m_maxNoSets,
"m_phiRatioCells", 0, AT_);
248 mAlloc(m_correction, m_maxNoCells * m_maxNoSets,
"m_correction", F0, AT_);
249 mAlloc(m_d, m_maxNoCells * m_maxNoSets,
"m_d", F0, AT_);
250 mAlloc(m_phiRatio, m_maxNoCells, 2 * nDim * m_maxNoSets,
"m_phiRatio", F0, AT_);
251 mAlloc(m_signG, m_maxNoCells * m_maxNoSets,
"m_signG", F0, AT_);
256 if(noNeighborDomains() > 0) {
257 if(isActive() && grid().noNeighborDomains() > 0) {
259 if(!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2) {
260 mAlloc(m_gSendBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells,
"m_gSendBuffers", F0, AT_);
261 mAlloc(m_gReceiveBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells,
"m_gReceiveBuffers", F0, AT_);
265 mAlloc(m_intSendBuffers, grid().noNeighborDomains(), m_maxNoCells,
"m_intSendBuffers", 0, AT_);
266 mAlloc(m_intReceiveBuffers, grid().noNeighborDomains(), m_maxNoCells,
"m_intReceiveBuffers", 0, AT_);
269 if(m_combustion || (!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2)) {
270 mAlloc(mpi_request, grid().noNeighborDomains(),
"mpi_request", AT_);
271 mAlloc(mpi_recive, grid().noNeighborDomains(),
"mpi_recive", AT_);
289 mAlloc(m_bodyRadius, m_noEmbeddedBodies,
"m_bodyRadius", F0, AT_);
290 mAlloc(m_omega, m_noEmbeddedBodies * nDim,
"m_omega", F0, AT_);
291 mAlloc(m_bodyAngularVelocity, m_noEmbeddedBodies * nDim,
"m_bodyAngularVelocity", F0, AT_);
292 mAlloc(m_bodyAngularAcceleration, m_noEmbeddedBodies * nDim,
"m_bodyAngularAcceleration", F0, AT_);
293 mAlloc(m_semiLagrange_xRot_ref, m_noEmbeddedBodies * nDim,
"m_semiLagrange_xRot_ref", F0, AT_);
294 mAlloc(m_semiLagrange_xRot_STL, m_noEmbeddedBodies * nDim,
"m_semiLagrange_xRot_STL", F0, AT_);
295 if(!m_reconstructOldG) {
296 mAlloc(m_initialGCell, m_maxNoCells,
"m_initialGCell", 0, AT_);
297 mAlloc(m_cellDomIds, 2 * m_maxNoCells,
"m_cellDomIds", -1, AT_);
303 for(
MInt b = 0;
b < m_noEmbeddedBodies;
b++) {
304 rad = Context::getSolverProperty<MFloat>(
"bodyRadius", solverId(), AT_,
b);
305 m_bodyRadius[
b] = rad;
306 for(
MInt i = 0; i < nDim; i++) {
308 maRot = Context::getSolverProperty<MFloat>(
"MaRot", solverId(), AT_, ind);
309 if(abs(maRot) > F0) {
310 m_bodiesToCompute.push_back(
b);
316 m_noBodiesToCompute = m_bodiesToCompute.size();
319 if(!m_reconstructOldG && isActive()) {
321 mAlloc(m_globalSndOffsets, grid().noDomains() + 1,
"m_globalSndOffsets", 0, AT_);
322 mAlloc(m_globalRcvOffsets, grid().noDomains() + 1,
"m_globalRcvOffsets", 0, AT_);
352 for(
MInt set = m_startSet; set < m_noSets; set++) {
353 if(!m_computeSet[set])
continue;
355 for(
MInt bandId = 0; bandId < a_noBandCells(set); bandId++) {
356 cellId = a_bandCellId(bandId, set);
357 a_levelSetRHS(cellId, set) = F0;
360 for(
MInt bandId = 0; bandId < a_noBandCells(set); bandId++) {
361 cellId = a_bandCellId(bandId, set);
362 if(a_isHalo(cellId))
continue;
363 for(
MInt i = 0; i < nDim; i++) {
364 if(a_extensionVelocityG(cellId, i, set) > F0) {
365 nghbrL = c_neighborId(cellId, 2 * i);
366 nghbrL2 = c_neighborId(nghbrL, 2 * i);
367 nghbrL3 = c_neighborId(nghbrL2, 2 * i);
368 nghbrR = c_neighborId(cellId, 2 * i + 1);
369 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
371 if((!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR, set))
381 if((!a_inBandG(nghbrL3, set) || !a_inBandG(nghbrR2, set))
392 a_levelSetRHS(cellId, set) +=
393 a_extensionVelocityG(cellId, i, set)
394 * (-F1B30 * a_levelSetFunctionG(nghbrL3, set) + F1B4 * a_levelSetFunctionG(nghbrL2, set)
395 - a_levelSetFunctionG(nghbrL, set) + F1B3 * a_levelSetFunctionG(
id, set)
396 + F1B2 * a_levelSetFunctionG(nghbrR, set) - F1B20 * a_levelSetFunctionG(nghbrR2, set));
398 nghbrL = c_neighborId(cellId, 2 * i);
399 nghbrL2 = c_neighborId(nghbrL, 2 * i);
400 nghbrR = c_neighborId(cellId, 2 * i + 1);
401 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
402 nghbrR3 = c_neighborId(nghbrR2, 2 * i + 1);
404 if((!a_inBandG(nghbrR2, set) || !a_inBandG(nghbrL, set))
414 if((!a_inBandG(nghbrR3, set) || !a_inBandG(nghbrL2, set))
425 a_levelSetRHS(cellId, set) +=
426 a_extensionVelocityG(cellId, i, set)
427 * (F1B30 * a_levelSetFunctionG(nghbrR3, set) - F1B4 * a_levelSetFunctionG(nghbrR2, set)
428 + a_levelSetFunctionG(nghbrR, set) - F1B3 * a_levelSetFunctionG(
id, set)
429 - F1B2 * a_levelSetFunctionG(nghbrL, set) + F1B20 * a_levelSetFunctionG(nghbrL2, set));
432 a_levelSetRHS(cellId, set) *= m_FgCellDistance;
451 MBool timeStepCompleted =
false;
455 computeLevelSetRHS();
458 timeStepCompleted = gRungeKutta();
461 if(timeStepCompleted) levelSetRestriction();
463 return timeStepCompleted;
475 if(m_gRKMethod == 5)
return true;
478 for(
MInt set = 0; set < m_noSets; set++) {
479 if(!m_computeSet[set])
continue;
481 for(
MInt id = 0;
id < a_noBandCells(set);
id++)
482 a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) = a_levelSetFunctionG(a_bandCellId(
id, set), set);
485 switch(m_gRKMethod) {
487 factor = m_gRKalpha[m_gRKStep] * timeStep();
488 for(
MInt set = m_startSet; set < m_noSets; set++) {
489 if(!m_computeSet[set])
continue;
490 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
491 if(a_isGBoundaryCellG(a_bandCellId(
id, set), set))
continue;
492 a_levelSetFunctionG(a_bandCellId(
id, set), set) =
493 a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) - factor * a_levelSetRHS(a_bandCellId(
id, set), set);
499 factor = m_gRKalpha[m_gRKStep] * timeStep();
500 for(
MInt set = m_startSet; set < m_noSets; set++) {
501 if(!m_computeSet[set])
continue;
502 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
503 if(a_isGBoundaryCellG(a_bandCellId(
id, set), set))
continue;
504 a_levelSetFunctionG(a_bandCellId(
id, set), set) =
505 a_levelSetFunctionG(a_bandCellId(
id, set), set) * m_gRKalpha[m_gRKStep]
506 + a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) * (F1 - m_gRKalpha[m_gRKStep])
507 - a_levelSetRHS(a_bandCellId(
id, set), set) * factor;
513 MInt noIntegrationLayers = m_gBandWidth - 5;
514 factor = m_gRKalpha[m_gRKStep] * timeStep();
515 for(
MInt set = m_startSet; set < m_noSets; set++) {
516 if(!m_computeSet[set])
continue;
517 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
518 if(a_isGBoundaryCellG(a_bandCellId(
id, set), set))
continue;
519 c = fabs(a_levelSetFunctionG(a_bandCellId(
id, set), set)) * m_FgCellDistance - noIntegrationLayers;
521 a_levelSetRHS(a_bandCellId(
id, set), set) = F0;
523 a_levelSetRHS(a_bandCellId(
id, set), set) *= (F2B27 *
POW3(c) + F1B3 *
POW2(c));
524 a_levelSetFunctionG(a_bandCellId(
id, set), set) =
525 a_levelSetFunctionG(a_bandCellId(
id, set), set) * m_gRKalpha[m_gRKStep]
526 + a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) * (F1 - m_gRKalpha[m_gRKStep])
527 - a_levelSetRHS(a_bandCellId(
id, set), set) * factor;
533 factor = m_gRKalpha[m_gRKStep] * timeStep();
534 for(
MInt set = m_startSet; set < m_noSets; set++) {
535 if(!m_computeSet[set])
continue;
536 for(
MInt id = 0;
id < a_bandLayer(0, set);
id++) {
537 if(a_isGBoundaryCellG(a_bandCellId(
id, set), set))
continue;
538 a_levelSetFunctionG(a_bandCellId(
id, set), set) =
539 a_levelSetFunctionG(a_bandCellId(
id, set), set) * m_gRKalpha[m_gRKStep]
540 + a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) * (F1 - m_gRKalpha[m_gRKStep])
541 - a_levelSetRHS(a_bandCellId(
id, set), set) * factor;
544 reinitBand(m_startSet, m_noSets);
549 factor = m_gRKalpha[m_gRKStep] * timeStep();
550 for(
MInt set = m_startSet; set < m_noSets; set++) {
551 if(!m_computeSet[set])
continue;
552 for(
MInt id = 0;
id < a_bandLayer(0, set);
id++) {
553 if(a_isGBoundaryCellG(a_bandCellId(
id, set), set))
continue;
554 a_levelSetFunctionG(a_bandCellId(
id, set), set) =
555 a_levelSetFunctionG(a_bandCellId(
id, set), set) * m_gRKalpha[m_gRKStep]
556 + a_oldLevelSetFunctionG(a_bandCellId(
id, set), set) * (F1 - m_gRKalpha[m_gRKStep])
557 - a_levelSetRHS(a_bandCellId(
id, set), set) * factor;
567 mTerm(1, AT_,
"Unknown gRKMethod");
573 if(m_gRKStep == m_nogRKSteps) {
577 m_time += timeStep();
601 switch(
string2enum(m_levelSetDiscretizationScheme)) {
603 MFloat xOld[3] = {F0, F0, F0};
604 MInt containingCell = 0;
605 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
608 MFloat xCurrent[3] = {F0, F0, F0};
609 MFloat xShift[3] = {F0, F0, F0};
610 MFloat xShift_cur[3] = {F0, F0, F0};
611#if defined LS_DEBUG || !defined NDEBUG
612 MFloat shiftCheck[3] = {F0, F0, F0};
617 for(
MInt set = m_startSet; set < m_noSets; set++) {
618 if(!m_computeSet[set])
continue;
620 const MFloat cellLength = c_cellLengthAtLevel(a_maxGCellLevel(set));
621 const MFloat cellHalfLength = c_cellLengthAtLevel(a_maxGCellLevel(set) + 1);
623 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
624 const MInt body = m_setToBodiesTable[set][
b];
625 computeBodyPropertiesForced(1, xCurrent, body, time() + timeStep(),
true);
627#if defined LS_DEBUG || !defined NDEBUG
628 computeBodyPropertiesForced(1, shiftCheck, body, time());
629 for(
MInt d = 0; d < nDim; d++) {
630 MFloat shift = xCurrent[d] - shiftCheck[d];
631 if(shift > cellLength && !m_periodicMovement) {
632 mTerm(1, AT_,
"LevelSet-Shift is exceeding maximum shift-limit of a cellLength! Reduce timestep!");
636 computeBodyPropertiesForced(1, xOld, body, 0.0);
637 for(
MInt d = 0; d < nDim; d++) {
638 xShift[d] = xCurrent[d] - xOld[d];
639 xShift_cur[d] = xShift[d] - m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body];
643 for(
MInt d = 0; d < nDim; d++) {
644 MFloat tmp = xShift_cur[d];
645 if(abs(tmp) > 2 * cellLength && m_periodicMovement) {
646 m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body] -= m_periodicDistance - cellLength;
647 shiftOldLevelSetField(2 * d + 1, set, body);
648 exchangeLeafDataLS<false>();
650 if(tmp + cellHalfLength > cellLength) {
651 m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body] += cellLength;
652 shiftOldLevelSetField(2 * d + 1, set, body);
653 exchangeLeafDataLS<false>();
654 }
else if(tmp - cellHalfLength < -cellLength) {
655 m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body] -= cellLength;
656 shiftOldLevelSetField(2 * d, set, body);
657 exchangeLeafDataLS<false>();
663 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
665 if(!(a_bodyIdG(cellId, set) == body))
continue;
667 MBool boundaryCell =
false;
668 for(
MInt d = 0; d < m_noDirs; d++) {
669 if(!a_hasNeighbor(cellId, d)) {
670 a_levelSetFunctionG(cellId, set) = a_oldLevelSetFunctionG(cellId, set);
675 if(boundaryCell)
continue;
676 if(a_isHalo(cellId))
continue;
679 for(
MInt i = 0; i < nDim; i++) {
681 c_coordinate(cellId, i) - (xShift[i] - m_semiLagrange_xShift_ref[i * m_noEmbeddedBodies + body]);
684 containingCell = getContainingCell(cellId, xOld, set);
686 position = setUpLevelSetInterpolationStencil(containingCell, interpolationCells, xOld);
690 phiNew = interpolateOldLevelSet(interpolationCells, xOld, set);
692 phiNew = a_oldLevelSetFunctionG(containingCell, set);
694 a_levelSetFunctionG(cellId, set) = phiNew;
714 MBool firstRun =
false;
715 std::vector<MInt> remCells;
718 for(
MInt i = 0; i < m_noBodiesToCompute; i++) {
719 body = m_bodiesToCompute[i];
720 for(
MInt d = 0; d < nDim; d++) {
721 m_semiLagrange_xRot_ref[body * nDim + d] += m_omega[body * nDim + d] * timeStep();
722 m_semiLagrange_xRot_STL[body * nDim + d] += m_omega[body * nDim + d] * timeStep();
726 if(domainId() == 0) {
728 <<
" rot: " << m_semiLagrange_xRot_STL[body * nDim + 0] * 180.0 / PI <<
","
729 << m_semiLagrange_xRot_STL[body * nDim + 1] * 180.0 / PI <<
","
730 << m_semiLagrange_xRot_STL[body * nDim + 2] * 180.0 / PI <<
" / "
731 << m_semiLagrange_xRot_ref[body * nDim + 0] * 180.0 / PI <<
","
732 << m_semiLagrange_xRot_ref[body * nDim + 1] * 180.0 / PI <<
","
733 << m_semiLagrange_xRot_ref[body * nDim + 2] * 180.0 / PI <<
" deg;"
734 <<
" Omega: " << m_omega[body * nDim + 0] <<
" " << m_omega[body * nDim + 1] <<
" "
735 << m_omega[body * nDim + 2] << endl;
741 if(m_reconstructOldG) {
743 MInt noData = m_noBodiesToCompute;
745 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
746 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
747 for(
MInt j = 0; j < noWindowCells(i); j++) {
748 cellId = windowCellId(i, j);
749 if(a_containingCell(cellId,
b) > -1) {
750 tmp_data(cellId,
b) = c_globalId(a_containingCell(cellId,
b));
752 tmp_data(cellId,
b) = -1;
756 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
757 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
758 cellId = grid().azimuthalWindowCell(i, j);
759 if(a_containingCell(cellId,
b) > -1) {
760 tmp_data(cellId,
b) = c_globalId(a_containingCell(cellId,
b));
762 tmp_data(cellId,
b) = -1;
767 exchangeDataLS(&tmp_data(0, 0), noData);
768 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
769 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
770 for(
MInt j = 0; j < noHaloCells(i); j++) {
771 cellId = haloCellId(i, j);
772 if(tmp_data(cellId,
b) > -1) {
773 a_containingCell(cellId,
b) = a_localId(tmp_data(cellId,
b));
775 a_containingCell(cellId,
b) = -1;
779 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
780 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
781 cellId = grid().azimuthalHaloCell(i, j);
782 if(tmp_data(cellId,
b) > -1) {
783 a_containingCell(cellId,
b) = a_localId(tmp_data(cellId,
b));
785 a_containingCell(cellId,
b) = -1;
792 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
793 body = m_bodiesToCompute[
b];
794 set = m_bodyToSetTable[body];
797 computeBodyPropertiesForced(1, xCurrent, body, time() + timeStep());
798 computeBodyPropertiesForced(1, xOld, body, 0.0);
800 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
801 cellId = a_bandCellId(
id, set);
802 if(!(a_bodyIdG(cellId, set) == body))
continue;
803 if(a_isHalo(cellId))
continue;
805 searchCell = a_containingCell(cellId,
b);
807 for(
MInt i = 0; i < nDim; i++)
808 xCoord[i] = c_coordinate(cellId, i);
810 getContainingCellFromNeighbor(
b, cellId, xCoord, xOld);
811 m_newCells.push_back(cellId);
817 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
818 cellId = a_bandCellId(
id, set);
819 if(!(a_bodyIdG(cellId, set) == body))
continue;
820 if(a_isHalo(cellId))
continue;
824 searchCell = a_containingCell(cellId,
b);
827 for(
MInt i = 0; i < nDim; i++) {
828 xCoord[i] = c_coordinate(cellId, i);
830 rotateLevelSet(1, xInitial, body, xCoord, xOld, &m_semiLagrange_xRot_ref[body * nDim]);
831 for(
MInt i = 0; i < nDim; i++) {
832 xInitial[i] += xCurrent[i] - xOld[i];
835 if(grid().azimuthalPeriodicity()) {
837 for(
MInt d = 0; d < nDim; d++) {
838 shift = shift || !
approx(c_coordinate(searchCell, d), xInitial[d], F2 * c_cellLengthAtCell(searchCell));
842 MFloat coordsCylSearch[nDim];
844 for(
MInt d = 0; d < nDim; d++) {
845 coords[d] = c_coordinate(searchCell, d);
847 grid().raw().cartesianToCylindric(coords, coordsCylSearch);
848 grid().raw().cartesianToCylindric(xInitial, coordsCyl);
849 MInt side = grid().determineAzimuthalBoundarySide(xInitial);
852 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() - F1B2);
853 }
else if(side == 1) {
854 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() + F1B2);
856 mTerm(1, AT_,
"Invalid side!");
858 grid().raw().rotateCartesianCoordinates(xInitial, fac * grid().azimuthalAngle());
863 containingCell = getContainingCell(searchCell, xInitial);
864 if(containingCell != cellId) {
865 m_rotatingReinitTrigger = 1;
869 MInt dummyDomain = -1;
870 processRotatingLevelSet(phiNew, containingCell, dummyDomain, xInitial, set);
872 a_levelSetFunctionG(cellId, set) = phiNew;
873 a_containingCell(cellId,
b) = containingCell;
877 for(
MInt i = 0; i < m_maxNoCells; i++) {
878 if(!a_inBandG(i, set)) {
879 a_containingCell(i,
b) = -1;
886 MInt noData = 2 * m_noBodiesToCompute;
888 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
889 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
890 for(
MInt j = 0; j < noWindowCells(i); j++) {
891 cellId = windowCellId(i, j);
892 if(a_containingCell(cellId,
b) > -1) {
893 tmp_data(cellId,
b) = a_containingCell(cellId,
b);
894 tmp_data(cellId, m_noBodiesToCompute +
b) = a_containingDomain(cellId,
b);
896 tmp_data(cellId,
b) = -1;
897 tmp_data(cellId, m_noBodiesToCompute +
b) = -1;
901 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
902 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
903 cellId = grid().azimuthalWindowCell(i, j);
904 if(a_containingCell(cellId,
b) > -1) {
905 tmp_data(cellId,
b) = a_containingCell(cellId,
b);
906 tmp_data(cellId, m_noBodiesToCompute +
b) = a_containingDomain(cellId,
b);
908 tmp_data(cellId,
b) = -1;
909 tmp_data(cellId, m_noBodiesToCompute +
b) = -1;
914 exchangeDataLS(&tmp_data(0, 0), noData);
915 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
916 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
917 for(
MInt j = 0; j < noHaloCells(i); j++) {
918 cellId = haloCellId(i, j);
919 if(tmp_data(cellId,
b) > -1) {
920 a_containingCell(cellId,
b) = tmp_data(cellId,
b);
921 a_containingDomain(cellId,
b) = tmp_data(cellId, m_noBodiesToCompute +
b);
923 a_containingCell(cellId,
b) = -1;
924 a_containingDomain(cellId,
b) = -1;
928 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
929 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
930 cellId = grid().azimuthalHaloCell(i, j);
931 if(tmp_data(cellId,
b) > -1) {
932 a_containingCell(cellId,
b) = tmp_data(cellId,
b);
933 a_containingDomain(cellId,
b) = tmp_data(cellId, m_noBodiesToCompute +
b);
935 a_containingCell(cellId,
b) = -1;
936 a_containingDomain(cellId,
b) = -1;
943 for(
MInt b = 0;
b < m_noBodiesToCompute;
b++) {
944 body = m_bodiesToCompute[
b];
945 set = m_bodyToSetTable[body];
948 computeBodyPropertiesForced(1, xCurrent, body, time() + timeStep());
949 computeBodyPropertiesForced(1, xOld, body, 0.0);
953 noCellsToDom.fill(0);
955 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
956 cellId = a_bandCellId(
id, set);
957 if(!(a_bodyIdG(cellId, set) == body))
continue;
958 if(a_isHalo(cellId))
continue;
960 searchCell = a_containingCell(cellId,
b);
961 searchDomain = a_containingDomain(cellId,
b);
962 if(searchCell < 0 || searchDomain < 0) {
963 for(
MInt i = 0; i < nDim; i++)
964 xCoord[i] = c_coordinate(cellId, i);
965 getContainingCellFromNeighbor(
b, cellId, xCoord, xOld);
966 searchDomain = a_containingDomain(cellId,
b);
967 m_newCells.push_back(cellId);
969 if(searchDomain > -1) {
970 noCellsToDom[searchDomain]++;
975 prepareGlobalComm(&noCellsToDom[0]);
976 MInt noCellsComm =
mMax(m_globalSndOffsets[grid().noDomains()], m_globalRcvOffsets[grid().noDomains()]);
978 MIntScratchSpace intSndBufSizeGlob(grid().noDomains(), AT_,
"intSndBufSizeGlob");
979 MIntScratchSpace intRcvBufSizeGlob(grid().noDomains(), AT_,
"intRcvBufSizeGlob");
980 MIntScratchSpace floatSndBufSizeGlob(grid().noDomains(), AT_,
"floatSndBufSizeGlob");
981 MIntScratchSpace floatRcvBufSizeGlob(grid().noDomains(), AT_,
"floatRcvBufSizeGlob");
982 MInt floatOffset = 3;
984 MIntScratchSpace intSndBufGlob(intOffset * noCellsComm, AT_,
"intSndBufGlob");
985 MIntScratchSpace intRcvBufGlob(intOffset * noCellsComm, AT_,
"intRcvBufGlob");
986 MFloatScratchSpace floatSndBufGlob(floatOffset * noCellsComm, AT_,
"floatSndBufGlob");
987 MFloatScratchSpace floatRcvBufGlob(floatOffset * noCellsComm, AT_,
"floatRcvBufGlob");
989 std::vector<std::vector<MInt>> cellIdsLoc;
990 cellIdsLoc.resize(grid().noDomains());
992 intSndBufGlob.fill(-1);
993 intRcvBufGlob.fill(-1);
994 floatSndBufGlob.fill(-F1);
995 floatRcvBufGlob.fill(-F1);
996 intSndBufSizeGlob.fill(0);
997 intRcvBufSizeGlob.fill(0);
998 floatSndBufSizeGlob.fill(0);
999 floatRcvBufSizeGlob.fill(0);
1002 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
1003 cellId = a_bandCellId(
id, set);
1004 if(!(a_bodyIdG(cellId, set) == body))
continue;
1005 if(a_isHalo(cellId))
continue;
1009 searchCell = a_containingCell(cellId,
b);
1010 searchDomain = a_containingDomain(cellId,
b);
1026 for(
MInt i = 0; i < nDim; i++) {
1027 xCoord[i] = c_coordinate(cellId, i);
1029 rotateLevelSet(1, xInitial, body, xCoord, xOld, &m_semiLagrange_xRot_ref[body * nDim]);
1030 for(
MInt i = 0; i < nDim; i++) {
1031 xInitial[i] += xCurrent[i] - xOld[i];
1035 if(searchDomain == domainId()) {
1036 if(grid().azimuthalPeriodicity()) {
1037 MBool shift =
false;
1038 for(
MInt d = 0; d < nDim; d++) {
1040 shift || !
approx(c_coordinate(searchCell, d), xInitial[d], F2 * c_cellLengthAtCell(searchCell));
1044 MFloat coordsCylSearch[nDim];
1046 for(
MInt d = 0; d < nDim; d++) {
1047 coords[d] = c_coordinate(searchCell, d);
1049 grid().raw().cartesianToCylindric(coords, coordsCylSearch);
1050 grid().raw().cartesianToCylindric(xInitial, coordsCyl);
1051 MInt side = grid().determineAzimuthalBoundarySide(xInitial);
1054 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() - F1B2);
1055 }
else if(side == 1) {
1056 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() + F1B2);
1058 mTerm(1, AT_,
"Invalid side!");
1060 grid().raw().rotateCartesianCoordinates(xInitial, fac * grid().azimuthalAngle());
1065 containingCell = getContainingCell(searchCell, xInitial);
1068 if(firstRun && containingCell < 0) {
1069 remCells.push_back(cellId);
1073 processRotatingLevelSet(phiNew, containingCell, searchDomain, xInitial, set);
1075 a_levelSetFunctionG(cellId, set) = phiNew;
1076 a_containingCell(cellId,
b) = containingCell;
1077 a_containingDomain(cellId,
b) = searchDomain;
1078 }
else if(searchDomain < 0) {
1081 remCells.push_back(cellId);
1083 mTerm(1, AT_,
"Containing Domain unkown in ROTATING_LS!");
1088 cellIdsLoc[searchDomain].push_back(cellId);
1089 intSndBufGlob[m_globalSndOffsets[searchDomain] + intSndBufSizeGlob.p[searchDomain]] = searchCell;
1090 intSndBufSizeGlob.p[searchDomain]++;
1092 for(
MInt dim = 0; dim < nDim; dim++) {
1093 floatSndBufGlob[floatOffset * m_globalSndOffsets[searchDomain] + floatSndBufSizeGlob.p[searchDomain]] =
1095 floatSndBufSizeGlob.p[searchDomain]++;
1102 exchangeBuffersGlobal(intSndBufGlob.getPointer(), intRcvBufGlob.getPointer(), intSndBufSizeGlob.getPointer(),
1103 intRcvBufSizeGlob.getPointer(), m_globalSndOffsets, m_globalRcvOffsets, 3);
1104 exchangeBuffersGlobal(floatSndBufGlob.getPointer(), floatRcvBufGlob.getPointer(),
1105 floatSndBufSizeGlob.getPointer(), floatRcvBufSizeGlob.getPointer(), m_globalSndOffsets,
1106 m_globalRcvOffsets, 5, floatOffset);
1108 intSndBufGlob.fill(-1);
1109 floatSndBufGlob.fill(-F1);
1110 intSndBufSizeGlob.fill(0);
1111 floatSndBufSizeGlob.fill(0);
1114 for(
MInt i = 0; i < grid().noDomains(); i++) {
1115 ind = m_globalRcvOffsets[i];
1116 for(
MInt j = 0; j < intRcvBufSizeGlob(i); j++) {
1117 searchCell = intRcvBufGlob(ind + j);
1118 searchDomain = domainId();
1120 xInitial[0] = floatRcvBufGlob(ind * floatOffset + j * floatOffset + 0);
1121 xInitial[1] = floatRcvBufGlob(ind * floatOffset + j * floatOffset + 1);
1122 xInitial[2] = floatRcvBufGlob(ind * floatOffset + j * floatOffset + 2);
1124 if(grid().azimuthalPeriodicity()) {
1125 MBool shift =
false;
1126 for(
MInt d = 0; d < nDim; d++) {
1128 shift || !
approx(c_coordinate(searchCell, d), xInitial[d], F2 * c_cellLengthAtCell(searchCell));
1132 MFloat coordsCylSearch[nDim];
1134 for(
MInt d = 0; d < nDim; d++) {
1135 coords[d] = c_coordinate(searchCell, d);
1137 grid().raw().cartesianToCylindric(coords, coordsCylSearch);
1138 grid().raw().cartesianToCylindric(xInitial, coordsCyl);
1139 MInt side = grid().determineAzimuthalBoundarySide(xInitial);
1142 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() - F1B2);
1143 }
else if(side == 1) {
1144 fac = (
MInt)((coordsCyl[1] - coordsCylSearch[1]) / grid().azimuthalAngle() + F1B2);
1146 mTerm(1, AT_,
"Invalid side!");
1148 grid().raw().rotateCartesianCoordinates(xInitial, fac * grid().azimuthalAngle());
1153 containingCell = getContainingCell(searchCell, xInitial);
1156 if(firstRun && containingCell < 0) {
1157 intSndBufGlob(ind * intOffset + intSndBufSizeGlob.p[i]) = -2;
1158 intSndBufSizeGlob.p[i]++;
1159 intSndBufGlob(ind * intOffset + intSndBufSizeGlob.p[i]) = -2;
1160 intSndBufSizeGlob.p[i]++;
1161 floatSndBufGlob(ind * floatOffset + floatSndBufSizeGlob.p[i]) = F0;
1162 floatSndBufSizeGlob.p[i]++;
1167 processRotatingLevelSet(phiNew, containingCell, searchDomain, xInitial, set);
1169 floatSndBufGlob(ind + floatSndBufSizeGlob.p[i]) = phiNew;
1170 floatSndBufSizeGlob.p[i]++;
1171 intSndBufGlob(ind * intOffset + intSndBufSizeGlob.p[i]) = containingCell;
1172 intSndBufSizeGlob.p[i]++;
1173 intSndBufGlob(ind * intOffset + intSndBufSizeGlob.p[i]) = searchDomain;
1174 intSndBufSizeGlob.p[i]++;
1178 intRcvBufGlob.fill(-1);
1179 floatRcvBufGlob.fill(-F1);
1180 intRcvBufSizeGlob.fill(0);
1181 floatRcvBufSizeGlob.fill(0);
1184 exchangeBuffersGlobal(intSndBufGlob.getPointer(), intRcvBufGlob.getPointer(), intSndBufSizeGlob.getPointer(),
1185 intRcvBufSizeGlob.getPointer(), &m_globalRcvOffsets[0], &m_globalSndOffsets[0], 3,
1187 exchangeBuffersGlobal(floatSndBufGlob.getPointer(), floatRcvBufGlob.getPointer(),
1188 floatSndBufSizeGlob.getPointer(), floatRcvBufSizeGlob.getPointer(),
1189 &m_globalRcvOffsets[0], &m_globalSndOffsets[0], 5);
1192 for(
MInt i = 0; i < grid().noDomains(); i++) {
1193 ind = m_globalSndOffsets[i];
1194 for(
MInt j = 0; j < floatRcvBufSizeGlob(i); j++) {
1195 cellId = cellIdsLoc[i][j];
1197 a_containingCell(cellId,
b) = intRcvBufGlob(ind * intOffset + j * intOffset + 0);
1198 a_containingDomain(cellId,
b) = intRcvBufGlob(ind * intOffset + j * intOffset + 1);
1201 if(firstRun && a_containingCell(cellId,
b) < -1) {
1202 remCells.push_back(cellId);
1206 a_levelSetFunctionG(cellId, set) = floatRcvBufGlob(ind + j);
1212 for(
MInt dom = 0; dom < grid().noDomains(); dom++) {
1214 if(domainId() == dom) {
1215 cnt = remCells.size();
1216 if(cnt > 0) cerr <<
"D:" << domainId() <<
" Restart Backup LS!" << endl;
1219 MPI_Bcast(&cnt, 1, MPI_INT, dom, MPI_COMM_WORLD, AT_,
"cnt");
1221 for(
MInt c = 0; c < cnt; c++) {
1222 containingCell = -1;
1224 if(domainId() == dom) {
1225 for(
MInt i = 0; i < nDim; i++) {
1226 xCoord[i] = c_coordinate(remCells[c], i);
1228 rotateLevelSet(1, xInitial, body, xCoord, xOld, &m_semiLagrange_xRot_ref[body * nDim]);
1229 for(
MInt i = 0; i < nDim; i++) {
1230 xInitial[i] += xCurrent[i] - xOld[i];
1237 containingCell = getContainingCell(xInitial);
1239 if(containingCell > -1) {
1241 searchDomain = domainId();
1243 processRotatingLevelSet(phiNew, containingCell, searchDomain, xInitial, set);
1245 MPI_Allreduce(MPI_IN_PLACE, &searchDomain, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
1248 if(searchDomain != dom) {
1249 if(domainId() == searchDomain) {
1250 MPI_Send(&containingCell, 1, MPI_INT, dom, 5, mpiComm(), AT_,
"containingCell");
1253 if(domainId() == dom) {
1254 MPI_Recv(&containingCell, 1, MPI_INT, searchDomain, 5, mpiComm(), MPI_STATUS_IGNORE, AT_,
1257 MPI_STATUS_IGNORE, AT_,
"phiNew");
1261 if(domainId() == dom) {
1263 a_levelSetFunctionG(cellId, set) = phiNew;
1264 a_containingCell(cellId,
b) = containingCell;
1265 a_containingDomain(cellId,
b) = searchDomain;
1275 for(
MInt i = 0; i < m_maxNoCells; i++) {
1276 if(!a_inBandG(i, set)) {
1277 a_containingCell(i,
b) = -1;
1278 a_containingDomain(i,
b) = -1;
1285 for(
MInt i = 0; i < m_noBodiesToCompute; i++) {
1286 body = m_bodiesToCompute[i];
1287 rotateLevelSet(5, &m_bodyAngularVelocity[body * nDim], body,
nullptr,
nullptr,
1288 &m_semiLagrange_xRot_STL[body * nDim]);
1294 stringstream errorMessage;
1295 errorMessage <<
"LsCartesianSolver::semiLagrangeTimeStep(): switch variable 'm_levelSetDiscretizationScheme' "
1297 << m_levelSetDiscretizationScheme <<
" not matching any case." << endl;
1298 mTerm(1, AT_, errorMessage.str());
1312 NEW_TIMER_GROUP_STATIC(reInit,
"Reinitialisation");
1313 NEW_TIMER_STATIC(t_reInit,
"Total time - levelset Reinitialisation", reInit);
1314 NEW_SUB_TIMER_STATIC(t_c1,
"preparation", t_reInit);
1315 NEW_SUB_TIMER_STATIC(t_c2,
"solver", t_reInit);
1317 RECORD_TIMER_START(t_reInit);
1318 RECORD_TIMER_START(t_c1);
1331 MFloat smoothingTerm = F0;
1336#ifdef REINITIALIZATION_STATISTICS
1338 MFloat avgGradient, maxGradient, minGradient, meanGradient, temp;
1348#ifdef REINITIALIZATION_STATISTICS
1350 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1351 cellId = a_G0CellId(
id, startSet);
1353 if(a_levelSetFunctionG(cellId, startSet) < F0) {
1354 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
1355 if(a_hasNeighbor(cellId, dirId) > 0) {
1356 nghbrId = c_neighborId(cellId, dirId);
1357 if(a_isGZeroCell(nghbrId, startSet) && a_levelSetFunctionG(nghbrId, startSet) > F0) {
1358 factor =
ABS(a_levelSetFunctionG(cellId, startSet))
1359 / (
ABS(a_levelSetFunctionG(nghbrId, startSet)) +
ABS(a_levelSetFunctionG(cellId, startSet)));
1360 for(
MInt i = 0; i < nDim; i++) {
1361 x(counter, i) = c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i));
1371 avgGradient = F0, maxGradient = F0, minGradient = 1000.0, meanGradient = 0;
1374 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1375 cellId = a_G0CellId(
id, startSet);
1378 for(
MInt i = 0; i < nDim; i++) {
1379 temp +=
POW2(a_levelSetFunctionSlope(cellId, i, startSet));
1381 temp =
ABS(sqrt(temp));
1383 avgGradient +=
ABS(temp - F1);
1384 meanGradient += temp;
1385 maxGradient =
mMax(maxGradient, temp);
1386 minGradient =
mMin(minGradient, temp);
1387 variance +=
POW2(temp);
1389 avgGradient = avgGradient / (
MFloat)a_noG0Cells(startSet);
1390 meanGradient = meanGradient / (
MFloat)a_noG0Cells(startSet);
1391 variance = sqrt(variance) / (
MFloat)a_noG0Cells(startSet);
1393 avg = fopen(
"avgGradient",
"a+");
1395 fprintf(avg,
" %f", avgGradient * 1000.0);
1396 fprintf(avg,
" %f", variance);
1397 fprintf(avg,
" %f", meanGradient);
1398 fprintf(avg,
" %f", maxGradient);
1399 fprintf(avg,
" %f", minGradient);
1406 for(
MInt set = startSet; set < endSet; set++) {
1407 if(!m_computeSet[set])
continue;
1408 for(
MInt cell = 0; cell < a_internalBandLayer(0, set); cell++)
1409 reinit[IDX_LSSET(cell, set)] = 1;
1413 for(
MInt set = startSet; set < endSet; set++) {
1414 if(!m_computeSet[set])
continue;
1415 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1416 cellId = a_internalBandCellId(
id, set);
1417 for(
MInt j = 0; j < m_noDirs; j++) {
1418 nghbr[j] = a_bandNghbrIdsG(cellId, j, set);
1420 for(
MInt i = 0; i < nDim; i++) {
1421 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(nghbr[2 * i], set) > F0
1422 && a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(a_bandNghbrIdsG(nghbr[2 * i], 2 * i, set), set)
1426 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(nghbr[2 * i + 1], set) > F0
1427 && a_levelSetFunctionG(cellId, set)
1428 * a_levelSetFunctionG(a_bandNghbrIdsG(nghbr[2 * i + 1], 2 * i + 1, set), set)
1432 reinit[IDX_LSSET(
id, set)] = 0;
1440 for(
MInt set = startSet; set < endSet; set++) {
1441 if(!m_computeSet[set])
continue;
1442 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1443 cellId = a_internalBandCellId(
id, set);
1444 if(reinit[IDX_LSSET(
id, set)] == 0) {
1445 m_d[IDX_LSSET(cellId, set)] = a_levelSetFunctionG(cellId, set);
1449 for(
MInt j = 0; j < m_noDirs; j++) {
1450 nghbr[j] = a_bandNghbrIdsG(cellId, j, set);
1453 for(
MInt i = 0; i < nDim; i++) {
1455 dx[i] = F2 * m_gCellDistance;
1456 if(!a_isGZeroCell(nghbr[2 * i], set)) {
1459 dx[i] -= m_gCellDistance;
1461 if(!a_isGZeroCell(nghbr[2 * i + 1], set)) {
1462 nghbr[2 * i + 1] =
cellId;
1464 dx[i] -= m_gCellDistance;
1468 if(a_levelSetFunctionG(nghbr[2 * i], set) * a_levelSetFunctionG(nghbr[2 * i + 1], set) < F0) {
1469 if((a_levelSetFunctionG(nghbr[2 * i], set) - a_levelSetFunctionG(cellId, set))
1470 * (a_levelSetFunctionG(nghbr[2 * i + 1], set) - a_levelSetFunctionG(cellId, set))
1472 || a_levelSetFunctionG(nghbr[2 * i], set)
1473 * a_levelSetFunctionG(a_bandNghbrIdsG(nghbr[2 * i], 2 * i, set), set)
1475 || a_levelSetFunctionG(nghbr[2 * i + 1], set)
1476 * a_levelSetFunctionG(a_bandNghbrIdsG(nghbr[2 * i + 1], 2 * i + 1, set), set)
1478 if(fabs(a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(nghbr[2 * i], set))
1479 > fabs(a_levelSetFunctionG(nghbr[2 * i + 1], set) - a_levelSetFunctionG(cellId, set) + eps)) {
1480 nghbr[2 * i + 1] =
cellId;
1481 dx[i] -= m_gCellDistance;
1483 if(fabs(a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(nghbr[2 * i], set) + eps)
1484 < fabs(a_levelSetFunctionG(nghbr[2 * i + 1], set) - a_levelSetFunctionG(cellId, set))) {
1486 dx[i] -= m_gCellDistance;
1494 m_d[IDX_LSSET(cellId, set)] = F0;
1495 for(
MInt i = 0; i < nDim; i++) {
1496 dx[i] =
mMax(eps, dx[i]);
1497 m_d[IDX_LSSET(cellId, set)] +=
1498 POW2((a_levelSetFunctionG(nghbr[2 * i + 1], set) - a_levelSetFunctionG(nghbr[2 * i], set)) / dx[i]);
1500 m_d[IDX_LSSET(cellId, set)] = F1 / sqrt(m_d[IDX_LSSET(cellId, set)]);
1501 m_d[IDX_LSSET(cellId, set)] *= a_levelSetFunctionG(cellId, set);
1506 exchangeLs(m_d, 0, m_maxNoSets);
1509 for(
MInt set = startSet; set < endSet; set++) {
1510 if(!m_computeSet[set])
continue;
1511 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1512 cellId = a_internalBandCellId(
id, set);
1513 for(
MInt j = 0; j < m_noDirs; j++) {
1514 m_phiRatioCells[
cellId][IDX_LSSET(j, set)] = -1;
1516 for(
MInt j = 0; j < m_noDirs; j++) {
1517 nghbr[j] = a_bandNghbrIdsG(cellId, j, set);
1518 if(a_levelSetFunctionG(nghbr[j], set) * a_levelSetFunctionG(cellId, set) < F0) {
1519 m_phiRatioCells[
cellId][IDX_LSSET(j, set)] = nghbr[j];
1520 m_phiRatio[
cellId][IDX_LSSET(j, set)] = a_levelSetFunctionG(cellId, set) / a_levelSetFunctionG(nghbr[j], set);
1526 for(
MInt set = startSet; set < endSet; set++) {
1527 if(!m_computeSet[set])
continue;
1531 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1532 cellId = a_internalBandCellId(
id, set);
1533 if((a_curvatureG(cellId, set) >= F0 && a_levelSetFunctionG(cellId, set) < F0)
1534 || (a_curvatureG(cellId, set) < F0 && a_levelSetFunctionG(cellId, set) > F0)) {
1535 m_correction[IDX_LSSET(cellId, set)] = F0;
1537 for(
MInt i = 0; i < m_noDirs; i++) {
1538 if(m_phiRatioCells[cellId][IDX_LSSET(i, set)] != -1) {
1539 m_correction[IDX_LSSET(cellId, set)] += m_d[IDX_LSSET(m_phiRatioCells[cellId][IDX_LSSET(i, set)], set)]
1540 * m_phiRatio[
cellId][IDX_LSSET(i, set)];
1545 m_correction[IDX_LSSET(cellId, set)] = m_correction[IDX_LSSET(cellId, set)] / (
MFloat)counter;
1547 m_correction[IDX_LSSET(cellId, set)] = m_d[IDX_LSSET(cellId, set)];
1549 m_correction[IDX_LSSET(cellId, set)] = m_d[IDX_LSSET(cellId, set)];
1552 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
1553 cellId = a_G0CellId(
id, set);
1554 m_d[IDX_LSSET(cellId, set)] = m_correction[IDX_LSSET(cellId, set)];
1561 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1562 cellId = a_internalBandCellId(
id, set);
1564 if((a_curvatureG(cellId, set) >= F0 && a_levelSetFunctionG(cellId, set) < F0)
1565 || (a_curvatureG(cellId, set) < F0 && a_levelSetFunctionG(cellId, set) > F0)) {
1569 for(
MInt i = 0; i < m_noDirs; i++) {
1570 if(m_phiRatioCells[cellId][IDX_LSSET(i, set)] != -1) {
1571 sumOfD += m_d[IDX_LSSET(m_phiRatioCells[cellId][IDX_LSSET(i, set)], set)];
1572 sumOfPhi += a_levelSetFunctionG(m_phiRatioCells[cellId][IDX_LSSET(i, set)], set);
1577 m_correction[IDX_LSSET(cellId, set)] = a_levelSetFunctionG(cellId, set) * sumOfD / sumOfPhi;
1579 m_correction[IDX_LSSET(cellId, set)] = m_d[IDX_LSSET(cellId, set)];
1581 m_correction[IDX_LSSET(cellId, set)] = m_d[IDX_LSSET(cellId, set)];
1584 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
1585 cellId = a_G0CellId(
id, set);
1586 m_d[IDX_LSSET(cellId, set)] = m_correction[IDX_LSSET(cellId, set)];
1591 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++)
1592 if(reinit[IDX_LSSET(
id, set)] != 0)
1593 a_levelSetFunctionG(a_internalBandCellId(
id, set), set) +=
1595 * (m_d[IDX_LSSET(a_internalBandCellId(
id, set), set)]
1596 - a_levelSetFunctionG(a_internalBandCellId(
id, set), set));
1599 for(
MInt id = 0;
id < a_noInternalBandCells(set);
id++) {
1600 cellId = a_internalBandCellId(
id, set);
1601 m_signG[IDX_LSSET(cellId, set)] =
1602 a_levelSetFunctionG(cellId, set) / sqrt(
POW2(a_levelSetFunctionG(cellId, set)) +
POW2(smoothingTerm));
1603 if(a_levelSetFunctionG(cellId, set) > F0) {
1604 a_hasPositiveSign(cellId, set) =
true;
1606 a_hasPositiveSign(cellId, set) =
false;
1616 for(
MInt id = 0;
id < a_noInternalBandCells(set);
id++) {
1617 cellId = a_internalBandCellId(
id, set);
1620 if(!a_isGZeroCell(cellId, set) && a_nearGapG(cellId) > 0 && a_potentialGapCellClose(cellId)) {
1621 m_cellList[cellListSize] =
cellId;
1625 if(!a_isGZeroCell(cellId, set)) {
1626 m_cellList[cellListSize] =
cellId;
1632 RECORD_TIMER_STOP(t_c1);
1633 RECORD_TIMER_START(t_c2);
1634 res[set] = firstOrderEikonalSolver(cellListSize, m_gReinitIterations, set);
1635 RECORD_TIMER_STOP(t_c2);
1636 RECORD_TIMER_START(t_c1);
1638 m_log <<
"Reinitialization finished at ts " <<
globalTimeStep <<
": " << res[set] << endl;
1643#ifdef REINITIALIZATION_STATISTICS
1645 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1646 cellId = a_G0CellId(
id, startSet);
1647 if(a_levelSetFunctionG(cellId, startSet) < F0) {
1648 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
1649 if(a_hasNeighbor(cellId, dirId) > 0) {
1650 nghbrId = c_neighborId(cellId, dirId);
1651 if(a_isGZeroCell(nghbrId, startSet) && a_levelSetFunctionG(nghbrId, startSet) > F0) {
1652 factor =
ABS(a_levelSetFunctionG(cellId, startSet))
1653 / (
ABS(a_levelSetFunctionG(nghbrId, startSet)) +
ABS(a_levelSetFunctionG(cellId, startSet)));
1654 for(
MInt i = 0; i < nDim; i++) {
1658 - (c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i))));
1667 for(
MInt it = 0; it < counter; it++) {
1669 for(
MInt i = 0; i < nDim; i++)
1670 factor +=
POW2(x(it, i));
1671 deviation += sqrt(factor);
1673 deviation = deviation * 1000.0 / (
MFloat)counter;
1675 dev = fopen(
"deviation",
"a+");
1677 fprintf(dev,
" %f", deviation);
1682 computeNormalVectors();
1684 avgGradient = F0, maxGradient = F0, minGradient = 1000.0;
1687 MInt nghbrL, nghbrL2, nghbrR, nghbrR2;
1688 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1689 cellId = a_G0CellId(
id, startSet);
1692 for(
MInt i = 0; i < nDim; i++) {
1694 nghbrL = a_bandNghbrIdsG(cellId, 2 * i, startSet);
1695 nghbrL2 = a_bandNghbrIdsG(nghbrL, 2 * i, startSet);
1696 nghbrR = a_bandNghbrIdsG(cellId, 2 * i + 1, startSet);
1697 nghbrR2 = a_bandNghbrIdsG(nghbrR, 2 * i + 1, startSet);
1698 a_levelSetFunctionSlope(cellId, i, startSet) =
1700 * (F2B3 * (a_levelSetFunctionG(nghbrR, startSet) - a_levelSetFunctionG(nghbrL, startSet))
1701 - F1B12 * (a_levelSetFunctionG(nghbrR2, startSet) - a_levelSetFunctionG(nghbrL2, startSet)));
1702 temp +=
POW2(a_levelSetFunctionSlope(cellId, i, startSet));
1704 temp =
ABS(sqrt(temp));
1706 avgGradient +=
ABS(temp - F1);
1707 meanGradient += temp;
1708 maxGradient =
mMax(maxGradient, temp);
1709 minGradient =
mMin(minGradient, temp);
1710 variance +=
POW2(temp);
1712 avgGradient = avgGradient / (
MFloat)a_noG0Cells(startSet);
1713 meanGradient = meanGradient / (
MFloat)a_noG0Cells(startSet);
1714 variance = sqrt(variance) / (
MFloat)a_noG0Cells(startSet);
1716 avg2 = fopen(
"avgGradientAfter",
"a+");
1718 fprintf(avg2,
" %f", avgGradient * 1000.0);
1719 fprintf(avg2,
" %f", variance);
1720 fprintf(avg2,
" %f", meanGradient);
1721 fprintf(avg2,
" %f", maxGradient);
1722 fprintf(avg2,
" %f", minGradient);
1723 fprintf(avg2,
"\n");
1728 RECORD_TIMER_STOP(t_c1);
1729 RECORD_TIMER_STOP(t_reInit);
1748 MFloat smoothingTerm = m_gCellDistance;
1753 MInt noCellsToCorrect = 0;
1762 MFloat meanGradient = F0;
1770 if(!m_writeReinitializationStatistics) {
1773 x =
new MFloat*[a_noBandCells(startSet) * m_noDirs];
1775 if(m_writeReinitializationStatistics) {
1776 for(
MInt cell = 0; cell < a_noBandCells(startSet) * m_noDirs; cell++)
1777 x[cell] =
new MFloat[nDim];
1781 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1782 cellId = a_G0CellId(
id, startSet);
1784 if(a_levelSetFunctionG(cellId, startSet) < F0) {
1785 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
1786 if(a_hasNeighbor(cellId, dirId) > 0) {
1787 nghbrId = c_neighborId(cellId, dirId);
1788 if(a_isGZeroCell(nghbrId, startSet) && a_levelSetFunctionG(nghbrId, startSet) > F0) {
1789 factor =
ABS(a_levelSetFunctionG(cellId, startSet))
1790 / (
ABS(a_levelSetFunctionG(nghbrId, startSet)) +
ABS(a_levelSetFunctionG(cellId, startSet)));
1791 for(
MInt i = 0; i < nDim; i++) {
1792 x[counter][i] = c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i));
1802 for(
MInt set = startSet; set < endSet; set++) {
1803 if(!m_computeSet[set])
continue;
1805 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
1806 cellId = a_bandCellId(
id, set);
1807 m_signG[IDX_LSSET(cellId, set)] =
1808 a_levelSetFunctionG(cellId, set) / sqrt(
POW2(a_levelSetFunctionG(cellId, set)) +
POW2(smoothingTerm));
1809 if(a_levelSetFunctionG(cellId, set) > F0) {
1810 a_hasPositiveSign(cellId, set) =
true;
1812 a_hasPositiveSign(cellId, set) =
false;
1819 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
1820 cellId = a_bandCellId(
id, set);
1822 if(!a_isGZeroCell(cellId, set) && a_nearGapG(cellId) > 0 && a_potentialGapCellClose(cellId)) {
1823 m_cellList[cellListSize] =
cellId;
1827 m_cellList[cellListSize] =
cellId;
1833 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1834 cellId = a_internalBandCellId(
id, set);
1835 for(
MInt j = 0; j < m_noDirs; j++)
1836 m_phiRatioCells[cellId][IDX_LSSET(j, set)] = -1;
1837 for(
MInt j = 0; j < m_noDirs; j++) {
1838 if(a_levelSetFunctionG(a_bandNghbrIdsG(cellId, j, set), set) * a_levelSetFunctionG(cellId, set) < F0) {
1839 m_phiRatioCells[
cellId][IDX_LSSET(j, set)] = a_bandNghbrIdsG(cellId, j, set);
1840 m_phiRatio[
cellId][IDX_LSSET(j, set)] =
1841 a_levelSetFunctionG(cellId, set) / a_levelSetFunctionG(a_bandNghbrIdsG(cellId, j, set), set);
1852 noCellsToCorrect = 0;
1853 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1854 cellId = a_internalBandCellId(
id, set);
1855 m_correction[IDX_LSSET(cellId, set)] = F0;
1857 for(
MInt i = 0; i < m_noDirs; i++) {
1858 if(m_phiRatioCells[cellId][IDX_LSSET(i, set)] != -1) {
1859 factors.p[counter2++] =
1860 a_levelSetFunctionG(cellId, set) / a_levelSetFunctionG(m_phiRatioCells[cellId][IDX_LSSET(i, set)], set);
1864 if(counter > 0) cellsToCorrect.p[noCellsToCorrect++] =
cellId;
1867 res[set] = fifthOrderEikonalSolver(cellListSize, m_gReinitIterations, cellsToCorrect.getPointer(),
1868 noCellsToCorrect, factors.getPointer(), 1, set);
1873 if(methodId == 2 || methodId == 4 || methodId == 6) {
1874 noCellsToCorrect = 0;
1875 for(
MInt id = 0;
id < a_internalBandLayer(0, set);
id++) {
1876 cellId = a_internalBandCellId(
id, set);
1879 for(
MInt i = 0; i < m_noDirs; i++) {
1880 if(m_phiRatioCells[cellId][IDX_LSSET(i, set)] != -1) {
1881 sumOfPhi += a_levelSetFunctionG(m_phiRatioCells[cellId][IDX_LSSET(i, set)], set);
1885 factors.p[noCellsToCorrect] = a_levelSetFunctionG(cellId, set) / sumOfPhi;
1886 if(counter > 0) cellsToCorrect.p[noCellsToCorrect++] =
cellId;
1889 res[set] = fifthOrderEikonalSolver(cellListSize, m_gReinitIterations, cellsToCorrect.getPointer(),
1890 noCellsToCorrect, factors.getPointer(), 2, set);
1891 else if(methodId == 4)
1892 res[set] = fifthOrderEikonalSolver(cellListSize, m_gReinitIterations, cellsToCorrect.getPointer(),
1893 noCellsToCorrect, factors.getPointer(), 4, set);
1894 else if(methodId == 6)
1895 res[set] = fifthOrderEikonalSolver(cellListSize, m_gReinitIterations, cellsToCorrect.getPointer(),
1896 noCellsToCorrect, factors.getPointer(), 6, set);
1900 if(domainId() == 0) {
1902 FILE* datei =
nullptr;
1903 stringstream reinitFile;
1904 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
1905 datei = fopen((reinitFile.str()).c_str(),
"a+");
1906 fprintf(datei,
" %-10.8f reinitialized", res[startSet]);
1910 if(m_writeReinitializationStatistics) {
1913 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1914 cellId = a_G0CellId(
id, startSet);
1915 if(a_levelSetFunctionG(cellId, startSet) < F0) {
1916 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
1917 if(a_hasNeighbor(cellId, dirId) > 0) {
1918 nghbrId = c_neighborId(cellId, dirId);
1919 if(a_isGZeroCell(nghbrId, startSet) && a_levelSetFunctionG(nghbrId, startSet) > F0) {
1920 factor =
ABS(a_levelSetFunctionG(cellId, startSet))
1921 / (
ABS(a_levelSetFunctionG(nghbrId, startSet)) +
ABS(a_levelSetFunctionG(cellId, startSet)));
1922 for(
MInt i = 0; i < nDim; i++) {
1926 - (c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i))));
1935 for(
MInt it = 0; it < counter; it++) {
1937 for(
MInt i = 0; i < nDim; i++)
1938 factor +=
POW2(x[it][i]);
1939 deviation += sqrt(factor);
1941 deviation = deviation * 1000.0 / (
MFloat)counter;
1942 FILE* dev =
nullptr;
1943 dev = fopen(
"deviation",
"a+");
1945 fprintf(dev,
" %f", deviation);
1949 avgGradient = F0, maxGradient = F0, minGradient = 1000.0;
1956 for(
MInt id = 0;
id < a_noG0Cells(startSet);
id++) {
1957 cellId = a_G0CellId(
id, startSet);
1960 for(
MInt i = 0; i < nDim; i++) {
1962 nghbrL = a_bandNghbrIdsG(cellId, 2 * i, startSet);
1963 nghbrL2 = a_bandNghbrIdsG(nghbrL, 2 * i, startSet);
1964 nghbrR = a_bandNghbrIdsG(cellId, 2 * i + 1, startSet);
1965 nghbrR2 = a_bandNghbrIdsG(nghbrR, 2 * i + 1, startSet);
1966 a_levelSetFunctionSlope(cellId, i, startSet) =
1968 * (F2B3 * (a_levelSetFunctionG(nghbrR, startSet) - a_levelSetFunctionG(nghbrL, startSet))
1969 - F1B12 * (a_levelSetFunctionG(nghbrR2, startSet) - a_levelSetFunctionG(nghbrL2, startSet)));
1970 temp +=
POW2(a_levelSetFunctionSlope(cellId, i, startSet));
1972 temp =
ABS(sqrt(temp));
1974 avgGradient +=
ABS(temp - F1);
1975 meanGradient += temp;
1976 maxGradient =
mMax(maxGradient, temp);
1977 minGradient =
mMin(minGradient, temp);
1978 variance +=
POW2(temp);
1980 avgGradient = avgGradient / (
MFloat)a_noG0Cells(startSet);
1981 meanGradient = meanGradient / (
MFloat)a_noG0Cells(startSet);
1982 variance = sqrt(variance) / (
MFloat)a_noG0Cells(startSet);
1984 avg2 = fopen(
"avgGradientAfter",
"a+");
1986 fprintf(avg2,
" %f", avgGradient * 1000.0);
1987 fprintf(avg2,
" %f", variance);
1988 fprintf(avg2,
" %f", meanGradient);
1989 fprintf(avg2,
" %f", maxGradient);
1990 fprintf(avg2,
" %f", minGradient);
1991 fprintf(avg2,
"\n");
1995 for(
MInt cell = 0; cell < a_noBandCells(startSet) * m_noDirs; cell++)
2012 MFloat smoothingTerm = m_gCellDistance;
2014 auto startBand = (
MInt)(m_gBandWidth / 2);
2015 if(startBand > 6) startBand = 6;
2018 for(
MInt set = startSet; set < endSet; set++) {
2019 if(!m_computeSet[set])
continue;
2021 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
2022 cellId = a_bandCellId(
id, set);
2023 m_signG[IDX_LSSET(cellId, set)] =
2024 a_levelSetFunctionG(cellId, set) / sqrt(
POW2(a_levelSetFunctionG(cellId, set)) +
POW2(smoothingTerm));
2025 if(a_levelSetFunctionG(cellId, set) > F0) {
2026 a_hasPositiveSign(cellId, set) =
true;
2028 a_hasPositiveSign(cellId, set) =
false;
2034 for(
MInt id = a_bandLayer(startBand, set);
id < a_noBandCells(set);
id++) {
2035 cellId = a_bandCellId(
id, set);
2036 m_cellList[cellListSize] =
cellId;
2042 res[set] = firstOrderEikonalSolver(cellListSize, m_maintenanceIterations, set);
2046 fifthOrderEikonalSolver(cellListSize, m_maintenanceIterations, (
MInt*)
nullptr, 0, (
MFloat*)
nullptr, 0, set);
2049 stringstream errorMessage;
2050 errorMessage <<
"LsCartesianSolver::maintainOuterBandLayers(): switch variable 'order' with value " << order
2051 <<
" not matching any case." << endl;
2052 mTerm(1, AT_, errorMessage.str());
2058 stringstream reinitFile;
2059 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
2060 datei = fopen((reinitFile.str()).c_str(),
"a+");
2061 fprintf(datei,
" %f maintained", res[startSet]);
2092 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
2093 cellId = a_G0CellId(
id, set);
2094 if(a_isHalo(cellId))
continue;
2096 if(a_levelSetFunctionG(cellId, set) < F0) {
2097 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
2098 if(a_hasNeighbor(cellId, dirId) > 0) {
2099 nghbrId = c_neighborId(cellId, dirId);
2100 if(a_isGZeroCell(nghbrId, set) && a_levelSetFunctionG(nghbrId, set) > F0) {
2101 factor =
ABS(a_levelSetFunctionG(cellId, set))
2102 / (
ABS(a_levelSetFunctionG(nghbrId, set)) +
ABS(a_levelSetFunctionG(cellId, set)));
2103 for(
MInt i = 0; i < nDim; i++) {
2104 x.p[counter * nDim + i] =
2105 c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i));
2115 Fcounter = F1 / (
MFloat)counter;
2116 for(
MInt i = 0; i < nDim; i++) {
2117 m_minFlameFrontPosition[i] = 10000.0;
2118 m_maxFlameFrontPosition[i] = -10000.0;
2119 m_meanFlameFrontPosition[i] = F0;
2121 for(
MInt p = 0;
p < counter;
p++) {
2122 for(
MInt i = 0; i < nDim; i++) {
2123 m_minFlameFrontPosition[i] =
mMin(m_minFlameFrontPosition[i], x.p[nDim * p + i]);
2124 m_maxFlameFrontPosition[i] =
mMax(m_maxFlameFrontPosition[i], x.p[nDim * p + i]);
2125 m_meanFlameFrontPosition[i] += x.p[nDim *
p + i] * Fcounter;
2129 for(
MInt i = 0; i < nDim; i++) {
2130 MPI_Allreduce(MPI_IN_PLACE, &m_minFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
2131 "m_minFlameFrontPosition[i]");
2132 MPI_Allreduce(MPI_IN_PLACE, &m_maxFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
2133 "m_maxFlameFrontPosition[i]");
2134 MPI_Allreduce(MPI_IN_PLACE, &m_meanFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
2135 "m_meanFlameFrontPosition[i]");
2152 if(m_steadyFlameLength > -F1) {
2153 m_steadyFlameAngle = -F1;
2154 m_log <<
"WARINING: steady flame front length should be defined correctly in your properties.cdl " << endl;
2155 m_steadyFlameAngle = atan(m_steadyFlameLength / m_realRadiusFlameTube) * 180. / PI;
2157 m_log <<
"steadyFlameLength is : " << m_steadyFlameLength << endl;
2158 m_log <<
"uncurved flame base angle in Grad: " << m_steadyFlameAngle << endl;
2159 m_log <<
"flame surface slope is: " << tan(m_steadyFlameAngle * PI / 180.0) << endl;
2162 if(
approx(m_steadyFlameLength, -F1, MFloatEps) && m_forcing) {
2163 MString errorMessage =
"ERROR: steady flame length is not determined!!! should be defined for forced flames";
2164 mTerm(1, AT_, errorMessage);
2193 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
2194 cellId = a_G0CellId(
id, set);
2196 if(c_coordinate(cellId, 0) > xRegP)
continue;
2197 if(c_coordinate(cellId, 0) < xRegN)
continue;
2198 if(c_coordinate(cellId, 1) > yRegP)
continue;
2199 if(c_coordinate(cellId, 1) < yRegN)
continue;
2200 if(a_levelSetFunctionG(cellId, set) < F0) {
2201 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
2202 if(a_hasNeighbor(cellId, dirId) > 0) {
2203 nghbrId = c_neighborId(cellId, dirId);
2204 if(a_isGZeroCell(nghbrId, set) && a_levelSetFunctionG(nghbrId, set) > F0) {
2205 factor =
ABS(a_levelSetFunctionG(cellId, set))
2206 / (
ABS(a_levelSetFunctionG(nghbrId, set)) +
ABS(a_levelSetFunctionG(cellId, set)));
2207 for(
MInt i = 0; i < nDim; i++) {
2208 x.p[counter * nDim + i] =
2209 c_coordinate(cellId, i) + factor * (c_coordinate(nghbrId, i) - c_coordinate(cellId, i));
2219 Fcounter = F1 / (
MFloat)counter;
2220 for(
MInt i = 0; i < nDim; i++) {
2221 m_minFlameFrontPosition[i] = 10000.0;
2222 m_maxFlameFrontPosition[i] = -10000.0;
2223 m_meanFlameFrontPosition[i] = F0;
2225 for(
MInt p = 0;
p < counter;
p++) {
2226 for(
MInt i = 0; i < nDim; i++) {
2227 m_minFlameFrontPosition[i] =
mMin(m_minFlameFrontPosition[i], x.p[nDim * p + i]);
2228 m_maxFlameFrontPosition[i] =
mMax(m_maxFlameFrontPosition[i], x.p[nDim * p + i]);
2229 m_meanFlameFrontPosition[i] += x.p[nDim *
p + i] * Fcounter;
2234 for(
MInt i = 0; i < nDim; i++) {
2235 MPI_Allreduce(MPI_IN_PLACE, &m_minFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
2236 "m_minFlameFrontPosition[i]");
2237 MPI_Allreduce(MPI_IN_PLACE, &m_maxFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
2238 "m_maxFlameFrontPosition[i]");
2239 MPI_Allreduce(MPI_IN_PLACE, &m_meanFlameFrontPosition[i], 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
2240 "m_meanFlameFrontPosition[i]");
2259 for(
MInt set = startSet; set < endSet; set++) {
2260 if(!m_computeSet[set])
continue;
2262 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
2263 cellId = a_bandCellId(
id, set);
2264 m_signG[IDX_LSSET(cellId, set)] = a_levelSetFunctionG(cellId, set) /
ABS(a_levelSetFunctionG(cellId, set));
2265 if(a_levelSetFunctionG(cellId, set) > F0) {
2266 a_hasPositiveSign(cellId, set) =
true;
2268 a_hasPositiveSign(cellId, set) =
false;
2276 for(
MInt id = a_bandLayer(0, set);
id < a_noBandCells(set);
id++) {
2277 m_cellList[cellListSize] = a_bandCellId(
id, set);
2281 if(cellListSize > 0) {
2282 res[set] = firstOrderEikonalSolver(cellListSize, m_intermediateReinitIterations, set);
2285 m_log <<
"Reinitialization skipped since no cell was found to reinitialize " << endl;
2315 MFloat dt = m_reinitCFL * m_gCellDistance;
2325 if(maxIterations == 0) {
2329 while(iteration < maxIterations) {
2333 for(
MInt cell = 0; cell < cellListSize; cell++) {
2334 cellId = m_cellList[cell];
2335 a_levelSetRHS(cellId, set) = F0;
2336 for(
MInt i = 0; i < nDim; i++) {
2337 a = (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(a_bandNghbrIdsG(cellId, 2 * i, set), set))
2339 b = (a_levelSetFunctionG(a_bandNghbrIdsG(cellId, 2 * i + 1, set), set) - a_levelSetFunctionG(cellId, set))
2341 a_levelSetRHS(cellId, set) +=
2346 a_levelSetRHS(cellId, set) = m_signG[IDX_LSSET(cellId, set)] * (F1 - sqrt(a_levelSetRHS(cellId, set)));
2350 for(
MInt cell = 0; cell < cellListSize; cell++) {
2351 cellId = m_cellList[cell];
2352 G = a_levelSetFunctionG(cellId, set) + a_levelSetRHS(cellId, set) * dt;
2353 if(G * a_levelSetFunctionG(cellId, set) < F0) G = a_levelSetFunctionG(cellId, set);
2354 a_levelSetFunctionG(cellId, set) = G;
2355 res.p[0] =
mMax(res.p[0],
ABS(a_levelSetRHS(cellId, set)));
2360 q = (
MFloat*)&a_levelSetFunctionG(0, 0);
2361 exchangeLs(q, set, 1);
2363 MPI_Allreduce(res.getPointer(), globalRes.getPointer(), 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"res.getPointer()",
2364 "globalRes.getPointer()");
2366 res.p[0] = globalRes.p[0];
2368 if(res.p[0] < m_reinitConvergence) {
2402 MFloat dt = m_reinitCFL * m_gCellDistance;
2412 if(maxIterations == 0) {
2416 while(iteration < maxIterations) {
2420 for(
MInt cell = 0; cell < cellListSize; cell++) {
2421 cellId = m_cellList[cell];
2422 a_levelSetRHS(cellId, set) = F0;
2423 for(
MInt i = 0; i < nDim; i++) {
2427 PHI[0] = (q[IDX_LSSET(nghbrs[IDX_LSSETDIR(cellId, 2 * i, set)], set)]
2428 - q[IDX_LSSET(nghbrs[IDX_LSSETDIR(nghbrs[IDX_LSSETDIR(cellId, 2 * i, set)], 2 * i, set)], set)])
2430 PHI[1] = (q[IDX_LSSET(cellId, set)] - q[IDX_LSSET(nghbrs[IDX_LSSETDIR(cellId, 2 * i, set)], set)])
2432 PHI[2] = (q[IDX_LSSET(nghbrs[IDX_LSSETDIR(cellId, 2 * i + 1, set)], set)] - q[IDX_LSSET(cellId, set)])
2434 PHI[3] = (q[IDX_LSSET(nghbrs[IDX_LSSETDIR(nghbrs[IDX_LSSETDIR(cellId, 2 * i + 1, set)], 2 * i + 1, set)], set)]
2435 - q[IDX_LSSET(cellId, set)])
2437 PHI[4] = (PHI[1] - PHI[0]) * F1B2 * m_FgCellDistance;
2438 PHI[5] = (PHI[2] - PHI[1]) * F1B2 * m_FgCellDistance;
2439 PHI[6] = (PHI[3] - PHI[2]) * F1B2 * m_FgCellDistance;
2441 if(PHI[4] * PHI[5] > F0) {
2442 if(
ABS(PHI[4]) <=
ABS(PHI[5]))
2448 if(PHI[5] * PHI[6] > F0) {
2449 if(
ABS(PHI[5]) <=
ABS(PHI[6]))
2455 a = PHI[1] + cminus * m_gCellDistance;
2456 b = PHI[2] - cplus * m_gCellDistance;
2457 a_levelSetRHS(cellId, set) +=
2462 a_levelSetRHS(cellId, set) = m_signG[IDX_LSSET(cellId, set)] * (F1 - sqrt(a_levelSetRHS(cellId, set)));
2466 for(
MInt cell = 0; cell < cellListSize; cell++) {
2467 cellId = m_cellList[cell];
2469 G = q[IDX_LSSET(cellId, set)] + a_levelSetRHS(cellId, set) * dt;
2470 q[IDX_LSSET(cellId, set)] =
ABS(G) * a_levelSetSign(cellId, set);
2471 res.p[0] =
mMax(res.p[0],
ABS(a_levelSetRHS(cellId, set)));
2475 exchangeLs(q, set, 1);
2477 MPI_Allreduce(res.getPointer(), globalRes.getPointer(), 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"res.getPointer()",
2478 "globalRes.getPointer()");
2479 res.p[0] = globalRes.p[0];
2481 if(res.p[0] < m_reinitConvergence) {
2521 MInt nghbrL, nghbrL2, nghbrL3, nghbrL4, nghbrL5, nghbrR, nghbrR2, nghbrR3, nghbrR4, nghbrR5;
2523 MFloat dPlusL3, dPlusL2, dPlusL, dPlus, dPlusR, dPlusR2;
2526 MFloat alpha0, alpha1, alpha2, omega0, omega2;
2527 MFloat PsiMinus, PsiPlus;
2529 MBool converged =
false;
2530 MFloat dt = m_reinitCFL * m_gCellDistance;
2535 minIteration = m_gBandWidth / m_reinitCFL;
2545 if(!maxIterations) {
2553 for(
MInt cell = 0; cell < cellListSize; cell++) {
2554 firstOrder.p[cell] =
false;
2555 cellId = m_cellList[cell];
2556 if(a_isHalo(cellId))
continue;
2558 for(
MInt i = 0; i < nDim; i++) {
2559 nghbrL = a_bandNghbrIdsG(cellId, 2 * i, set);
2560 nghbrL2 = a_bandNghbrIdsG(nghbrL, 2 * i, set);
2561 nghbrL3 = a_bandNghbrIdsG(nghbrL2, 2 * i, set);
2562 nghbrL4 = a_bandNghbrIdsG(nghbrL3, 2 * i, set);
2563 nghbrL5 = a_bandNghbrIdsG(nghbrL4, 2 * i, set);
2564 nghbrR = a_bandNghbrIdsG(cellId, 2 * i + 1, set);
2565 nghbrR2 = a_bandNghbrIdsG(nghbrR, 2 * i + 1, set);
2566 nghbrR3 = a_bandNghbrIdsG(nghbrR2, 2 * i + 1, set);
2567 nghbrR4 = a_bandNghbrIdsG(nghbrR3, 2 * i + 1, set);
2568 nghbrR5 = a_bandNghbrIdsG(nghbrR4, 2 * i + 1, set);
2569 if(nghbrL5 == nghbrL4 || nghbrR5 == nghbrR4) {
2570 firstOrder.p[cell] =
true;
2579 for(
MInt cell = 0; cell < cellListSize; cell++) {
2580 firstOrder.p[cell] =
false;
2581 cellId = m_cellList[cell];
2582 if(a_isHalo(cellId))
continue;
2583 for(
MInt i = 0; i < nDim; i++) {
2584 nghbrL = a_bandNghbrIdsG(cellId, 2 * i, set);
2585 nghbrL2 = a_bandNghbrIdsG(nghbrL, 2 * i, set);
2586 nghbrL3 = a_bandNghbrIdsG(nghbrL2, 2 * i, set);
2587 nghbrL4 = a_bandNghbrIdsG(nghbrL3, 2 * i, set);
2588 nghbrL5 = a_bandNghbrIdsG(nghbrL4, 2 * i, set);
2589 nghbrR = a_bandNghbrIdsG(cellId, 2 * i + 1, set);
2590 nghbrR2 = a_bandNghbrIdsG(nghbrR, 2 * i + 1, set);
2591 nghbrR3 = a_bandNghbrIdsG(nghbrR2, 2 * i + 1, set);
2592 nghbrR4 = a_bandNghbrIdsG(nghbrR3, 2 * i + 1, set);
2593 nghbrR5 = a_bandNghbrIdsG(nghbrR4, 2 * i + 1, set);
2594 if(nghbrL5 == nghbrL4 || nghbrR5 == nghbrR4) {
2595 firstOrder.p[cell] =
true;
2604 while(iteration < maxIterations) {
2609 for(
MInt cell = 0; cell < cellListSize; cell++) {
2610 cellId = m_cellList[cell];
2611 if(a_isHalo(cellId))
continue;
2612 a_levelSetRHS(cellId, set) = F0;
2613 if(!firstOrder.p[cell]) {
2614 for(
MInt i = 0; i < nDim; i++) {
2615 nghbrL = a_bandNghbrIdsG(cellId, 2 * i, set);
2616 nghbrL2 = a_bandNghbrIdsG(nghbrL, 2 * i, set);
2617 nghbrL3 = a_bandNghbrIdsG(nghbrL2, 2 * i, set);
2618 nghbrR = a_bandNghbrIdsG(cellId, 2 * i + 1, set);
2619 nghbrR2 = a_bandNghbrIdsG(nghbrR, 2 * i + 1, set);
2620 nghbrR3 = a_bandNghbrIdsG(nghbrR2, 2 * i + 1, set);
2621 dPlusL3 = a_levelSetFunctionG(nghbrL2, set) - a_levelSetFunctionG(nghbrL3, set);
2622 dPlusL2 = a_levelSetFunctionG(nghbrL, set) - a_levelSetFunctionG(nghbrL2, set);
2623 dPlusL = a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(nghbrL, set);
2624 dPlus = a_levelSetFunctionG(nghbrR, set) - a_levelSetFunctionG(cellId, set);
2625 dPlusR = a_levelSetFunctionG(nghbrR2, set) - a_levelSetFunctionG(nghbrR, set);
2626 dPlusR2 = a_levelSetFunctionG(nghbrR3, set) - a_levelSetFunctionG(nghbrR2, set);
2627 a = (dPlusL2 - dPlusL3) * m_FgCellDistance;
2628 b = (dPlusL - dPlusL2) * m_FgCellDistance;
2629 c = (dPlus - dPlusL) * m_FgCellDistance;
2630 d = (dPlusR - dPlus) * m_FgCellDistance;
2632 IS1 = 13.0 *
POW2(
b - c) + 3.0 *
POW2(
b + c);
2633 IS2 = 13.0 *
POW2(c - d) + 3.0 *
POW2(3 * c - d);
2634 alpha0 = F1 /
POW2(eps + IS0);
2635 alpha1 = F6 /
POW2(eps + IS1);
2636 alpha2 = F3 /
POW2(eps + IS2);
2637 omega0 = alpha0 / (alpha0 + alpha1 + alpha2);
2638 omega2 = alpha2 / (alpha0 + alpha1 + alpha2);
2639 PsiMinus = F1B3 * omega0 * (
a - 2 *
b + c) + F1B6 * (omega2 - F1B2) * (
b - 2 * c + d);
2640 a = (dPlusR2 - dPlusR) * m_FgCellDistance;
2641 b = (dPlusR - dPlus) * m_FgCellDistance;
2642 d = (dPlusL - dPlusL2) * m_FgCellDistance;
2644 IS1 = 13.0 *
POW2(
b - c) + 3.0 *
POW2(
b + c);
2645 IS2 = 13.0 *
POW2(c - d) + 3.0 *
POW2(3 * c - d);
2646 alpha0 = F1 /
POW2(eps + IS0);
2647 alpha1 = F6 /
POW2(eps + IS1);
2648 alpha2 = F3 /
POW2(eps + IS2);
2649 omega0 = alpha0 / (alpha0 + alpha1 + alpha2);
2650 omega2 = alpha2 / (alpha0 + alpha1 + alpha2);
2651 PsiPlus = F1B3 * omega0 * (
a - 2 *
b + c) + F1B6 * (omega2 - F1B2) * (
b - 2 * c + d);
2652 a = F1B12 * m_FgCellDistance * (-dPlusL2 + F7 * dPlusL + F7 * dPlus - dPlusR) - PsiMinus;
2653 b = F1B12 * m_FgCellDistance * (-dPlusL2 + F7 * dPlusL + F7 * dPlus - dPlusR) + PsiPlus;
2655 a_levelSetRHS(cellId, set) +=
2661 for(
MInt i = 0; i < nDim; i++) {
2662 a = (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(a_bandNghbrIdsG(cellId, 2 * i, set), set))
2664 b = (a_levelSetFunctionG(a_bandNghbrIdsG(cellId, 2 * i + 1, set), set) - a_levelSetFunctionG(cellId, set))
2666 a_levelSetRHS(cellId, set) +=
2678 for(
MInt cell = 0; cell < cellListSize; cell++) {
2679 cellId = m_cellList[cell];
2680 if(a_isHalo(cellId))
continue;
2681 if(fabs(F1 - sqrt(a_levelSetRHS(cellId, set))) > 1.0) {
2683 a_levelSetRHS(cellId, set) = m_signG[IDX_LSSET(cellId, set)] * (F1 - sqrt(a_levelSetRHS(cellId, set)));
2685 a_levelSetRHS(cellId, set) = F0;
2689 for(
MInt cell = 0; cell < cellListSize; cell++) {
2690 cellId = m_cellList[cell];
2691 if(a_isHalo(cellId))
continue;
2692 a_levelSetRHS(cellId, set) = m_signG[IDX_LSSET(cellId, set)] * (F1 - sqrt(a_levelSetRHS(cellId, set)));
2703 MInt cnt, overallCnt;
2707 for(
MInt k = 0; k < noCRCells; k++) {
2711 if(a_isHalo(crCells[k]))
continue;
2712 for(
MInt i = 0; i < m_noDirs; i++) {
2713 if(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)] != -1) {
2714 if(a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set)
2715 * a_levelSetFunctionG(crCells[k], set)
2717 sum += factors[overallCnt++] * a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set);
2724 a_levelSetRHS(crCells[k], set) +=
2725 m_relaxationFactor * m_FgCellDistance * (sum / (
MFloat)cnt - a_levelSetFunctionG(crCells[k], set));
2735 for(
MInt k = 0; k < noCRCells; k++) {
2738 if(a_isHalo(crCells[k]))
continue;
2741 if(a_levelSetSign(crCells[k], set) > 0 && a_levelSetFunctionG(crCells[k], set) < 0) {
2744 if(a_levelSetSign(crCells[k], set) < 0 && a_levelSetFunctionG(crCells[k], set) > 0) {
2747 for(
MInt i = 0; i < m_noDirs; i++) {
2748 if(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)] != -1) {
2749 if(a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set)
2750 * a_levelSetFunctionG(crCells[k], set)
2752 sum += a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set);
2761 a_levelSetRHS(crCells[k], set) +=
2762 m_relaxationFactor * m_FgCellDistance * (factors[k] * sum - a_levelSetFunctionG(crCells[k], set));
2768 for(
MInt k = 0; k < noCRCells; k++) {
2769 if(a_isHalo(crCells[k]))
continue;
2770 a_levelSetRHS(crCells[k], set) +=
2771 m_relaxationFactor * m_FgCellDistance
2772 * (atanh(m_hypTanLSF[IDX_LSSET(crCells[k], set)] * F2 - F1) * m_gCellDistance
2773 - a_levelSetFunctionG(crCells[k], set));
2780 for(
MInt k = 0; k < noCRCells; k++) {
2781 if(a_isHalo(crCells[k]))
continue;
2782 if(abs(a_levelSetRHS(crCells[k], set)) < 0.000000000001)
continue;
2785 for(
MInt i = 0; i < m_noDirs; i++) {
2786 if(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)] != -1) {
2787 if(a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set)
2788 * a_levelSetFunctionG(crCells[k], set)
2790 sum += a_levelSetFunctionG(m_phiRatioCells[crCells[k]][IDX_LSSET(i, set)], set);
2796 a_levelSetRHS(crCells[k], set) +=
2797 m_relaxationFactor * m_FgCellDistance * (factors[k] * sum - a_levelSetFunctionG(crCells[k], set));
2802 mTerm(1, AT_,
"Unknown crMode");
2807 for(
MInt cell = 0; cell < cellListSize; cell++) {
2808 cellId = m_cellList[cell];
2809 if(a_isHalo(cellId))
continue;
2811 a_levelSetFunctionG(cellId, set) += a_levelSetRHS(cellId, set) * dt;
2812 res =
mMax(res,
ABS(a_levelSetRHS(cellId, set)));
2820 q = (
MFloat*)&a_levelSetFunctionG(0, 0);
2821 exchangeLs(q, set, 1);
2824 MPI_Allreduce(MPI_IN_PLACE, &res, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"res");
2828 if((res < m_reinitConvergence && iteration > minIteration) || converged) {
2829 if(set == m_startSet) {
2830 if(domainId() == 0) {
2832 stringstream reinitFile;
2833 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
2834 datei = fopen((reinitFile.str()).c_str(),
"a+");
2835 fprintf(datei,
" %d", iteration);
2843 if(set == m_startSet) {
2844 if(domainId() == 0) {
2846 stringstream reinitFile;
2847 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
2848 datei = fopen((reinitFile.str()).c_str(),
"a+");
2849 fprintf(datei,
" %d", iteration);
2855 m_reinitConvergence = m_reinitConvergenceReset;
2874 elapsedTime = time();
2889 m_GCtrlPntMethod = 2;
2890 m_GCtrlPntMethod = Context::getSolverProperty<MInt>(
"levelSetCtrlPntMethod", m_solverId, AT_, &m_GCtrlPntMethod);
2896 MFloat InitPos[3] = {F0, F0, F0};
2914 IF_CONSTEXPR(nDim == 2) {
2915 u[2] = v[2] = w[0] = w[1] = 0.0;
2921 switch(m_GCtrlPntMethod) {
2924 if(m_noBodyBndryCndIds > 1)
2926 "You are using GCtrlPntMethod 1, which is not adjusted to multiple bodies, but you are trying to "
2927 "compute multiple bodies. Please check!");
2928 m_gCtrlPnt.CtrlPnt1_Initialize(m_geometry, nDim);
2929 m_gCtrlPnt.CtrlPnt1_InitOrientation(u, v, w);
2930 computeBodyPropertiesForced(1, InitPos, 0, elapsedTime);
2931 IF_CONSTEXPR(nDim == 2) InitPos[2] = 0.0;
2932 m_gCtrlPnt.CtrlPnt1_InitPosition(InitPos);
2936 m_gCtrlPnt.CtrlPnt2_Initialize(m_geometry, nDim);
2937 for(
MInt body = 0; body < m_noEmbeddedBodies; body++) {
2938 const MInt bcId = m_bodyBndryCndIds[body];
2939 computeBodyPropertiesForced(1, InitPos, body, elapsedTime);
2940 IF_CONSTEXPR(nDim == 2) InitPos[2] = 0.0;
2941 m_gCtrlPnt.CtrlPnt2_InitOrientation(u, v, w, bcId);
2942 m_gCtrlPnt.CtrlPnt2_InitPosition(InitPos, bcId);
2944 stringstream controlfile;
2945 controlfile <<
"Ctrl_Body_" << body <<
".stl";
2946 m_gCtrlPnt.CtrlPnt2_CtrlPntToSTL((controlfile.str()).c_str(), bcId);
2949 m_gCtrlPnt.CtrlPnt2_Update();
2956 m_gCtrlPnt.CtrlPnt1_Initialize(m_geometry, nDim);
2957 m_gCtrlPnt.CtrlPnt1_InitOrientation(u, v, w);
2958 IF_CONSTEXPR(nDim == 2) InitPos[2] = 0.0;
2959 m_gCtrlPnt.CtrlPnt1_InitPosition(InitPos);
2963 mTerm(1, AT_,
"Unknown GCtrlPntMethod");
2985 m_nogRKSteps = Context::getSolverProperty<MInt>(
"nogRKSteps", m_solverId, AT_);
2988 m_gRKalpha =
new MFloat[m_nogRKSteps];
2989 for(
MInt i = 0; i < m_nogRKSteps; i++) {
2997 m_gRKalpha[i] = Context::getSolverProperty<MFloat>(
"grkalpha-step", m_solverId, AT_, i);
3002 if(!m_restart && m_LSSolver) {
3019 for(
MInt i = 0; i < nDim * m_noEmbeddedBodies; i++) {
3020 m_semiLagrange_xShift_ref[i] = F0;
3041 for(
MInt set = 0; set < m_noSets; set++) {
3042 if(!m_computeSet[set])
continue;
3043 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
3045 a_isBndryCellG(cellId) =
false;
3050 for(
MInt set = 0; set < m_noSets; set++) {
3051 if(!m_computeSet[set])
continue;
3052 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
3054 for(
MInt dir = 0; dir < 2 * nDim; dir++) {
3055 if(a_hasNeighbor(cellId, dir) == 0) {
3056 a_isBndryCellG(cellId) =
true;
3073 for(
MInt set = m_startSet; set < m_noSets; set++) {
3074 switch(m_levelSetBoundaryCondition) {
3077 MFloat deltaX = m_flameRadiusOffset;
3080 for(
MInt id = 0;
id < a_noGBndryCells(set);
id++) {
3081 a_isGBoundaryCellG(a_gBndryCellId(
id, set), set) =
true;
3082 x = c_coordinate(
id, 0);
3084 if((x > (-m_radiusFlameTube2 * 1.3 - err + m_xOffsetFlameTube))
3085 && (x < (m_radiusFlameTube2 * 1.3 + err + m_xOffsetFlameTube))) {
3086 a_levelSetFunctionG(a_gBndryCellId(
id, set), set) =
3087 ABS(c_coordinate(a_gBndryCellId(
id, set), 0) - m_xOffsetFlameTube) - m_radiusFlameTube * 1.3;
3089 }
else if((x > (-m_radiusFlameTube2 * 1.3 - err + m_xOffsetFlameTube2))
3090 && (x < (m_radiusFlameTube2 * 1.3 + err + m_xOffsetFlameTube2))) {
3091 a_levelSetFunctionG(a_gBndryCellId(
id, set), set) =
3092 ABS(c_coordinate(a_gBndryCellId(
id, set), 0) - m_xOffsetFlameTube2) - m_radiusFlameTube2 * 1.3;
3097 for(
MInt id = 0;
id < a_noGBndryCells(set);
id++) {
3099 a_isGBoundaryCellG(cellId, set) =
true;
3100 a_levelSetFunctionG(cellId, set) =
3101 ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube) - (m_radiusFlameTube + deltaX);
3102 a_curvatureG(cellId, 0) = 0;
3103 for(
MInt i = 0; i < nDim; i++)
3104 a_extensionVelocityG(cellId, i, set) = F0;
3111 MFloat deltaX = m_flameRadiusOffset;
3113 for(
MInt id = 0;
id < a_noGBndryCells(set);
id++) {
3115 a_isGBoundaryCellG(cellId, set) =
true;
3119 MFloat minXG =
ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube) - (m_jetHalfWidth + deltaX);
3120 MFloat minZG =
ABS(c_coordinate(cellId, 2)) - (m_jetHalfLength + deltaX);
3122 a_levelSetFunctionG(cellId, set) =
3123 m_initialFlameHeight * sqrt(2.0 - 1.0) * maxG + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3125 a_curvatureG(cellId, 0) = 0;
3127 for(
MInt i = 0; i < nDim; i++)
3128 a_extensionVelocityG(cellId, i, set) = F0;
3136 for(
MInt id = 0;
id < a_noGBndryCells(set);
id++) {
3138 a_isGBoundaryCellG(cellId, set) =
true;
3140 MFloat radius = sqrt(
POW2(c_coordinate(cellId, 0)) +
POW2(c_coordinate(cellId, 2)));
3142 MFloat maxG =
ABS(radius) - (0.515 + deltaX);
3143 a_levelSetFunctionG(cellId, set) =
3144 m_initialFlameHeight * sqrt(2.0 - 1.0) * maxG + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3146 a_curvatureG(cellId, 0) = 0;
3148 for(
MInt i = 0; i < nDim; i++)
3149 a_extensionVelocityG(cellId, i, set) = F0;
3175 ASSERT(!m_GFieldInitFromSTL,
"");
3177 MInt noCells = a_noCells();
3180 IF_CONSTEXPR(nDim == 2) {
3181 switch(m_initialCondition) {
3190 if(m_initialCondition == 504312) {
3194 for(
MInt set = m_startSet; set < m_noSets; set++) {
3196 radius =
POW2(c_coordinate(cellId, 0)) +
POW2(c_coordinate(cellId, 1) - dy);
3197 radius = sqrt(radius);
3198 x = c_coordinate(cellId, 0);
3199 y = c_coordinate(cellId, 1) - dy;
3204 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius, sqrt(
POW2(
ABS(x) - w) +
POW2(
y - h + R0)));
3206 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius,
ABS(
y - h + R0));
3210 a_levelSetFunctionG(cellId, set) =
mMax(-
ABS(
ABS(x) - w), -
ABS(
y - h + R0));
3212 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius,
ABS(x) - w);
3216 if(
ABS(x) > w ||
y > 0) {
3217 a_levelSetFunctionG(cellId, set) = R0 - radius;
3219 a_levelSetFunctionG(cellId, set) = -sqrt(
POW2(
ABS(x) - w) +
POW2(
y + R0));
3235 for(
MInt set = m_startSet; set < m_noSets; set++) {
3238 POW2(c_coordinate(cellId, 0) - a_meanCoord(0)) +
POW2(c_coordinate(cellId, 1) - a_meanCoord(1) - dy);
3239 radius = sqrt(radius);
3240 x = c_coordinate(cellId, 0);
3241 y = c_coordinate(cellId, 1) - dy;
3246 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius, sqrt(
POW2(
ABS(x) - w) +
POW2(
y - h + R0)));
3248 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius,
ABS(
y - h + R0));
3252 a_levelSetFunctionG(cellId, set) =
mMax(-
ABS(
ABS(x) - w), -
ABS(
y - h + R0));
3254 a_levelSetFunctionG(cellId, set) =
mMin(R0 - radius,
ABS(x) - w);
3258 if(
ABS(x) > w ||
y > 0) {
3259 a_levelSetFunctionG(cellId, set) = R0 - radius;
3261 a_levelSetFunctionG(cellId, set) = -sqrt(
POW2(
ABS(x) - w) +
POW2(
y + R0));
3281 R0 = Context::getSolverProperty<MFloat>(
"radius", m_solverId, AT_, &R0);
3285 for(
MInt i = 0; i < nDim; i++) {
3290 mTerm(1, AT_,
"Property 'initialBodyCenter' has invalid amount of entries!");
3292 for(
MInt i = 0; i < nDim; i++) {
3293 center[i] = Context::getSolverProperty<MFloat>(
"initialBodyCenter", m_solverId, AT_, i);
3299 radius =
POW2(c_coordinate(cellId, 0) - center[0]) +
POW2(c_coordinate(cellId, 1) - center[1]);
3300 radius = sqrt(radius);
3301 a_levelSetFunctionG(cellId, set) = radius - R0;
3308 MFloat deltaX = m_flameRadiusOffset;
3311 x = c_coordinate(cellId, 0);
3315 if((x > (-m_radiusFlameTube2 * 1.3 - err + m_xOffsetFlameTube))
3316 && (x < (m_radiusFlameTube2 * 1.3 + err + m_xOffsetFlameTube))) {
3317 a_levelSetFunctionG(cellId, set) =
3318 sqrt(4.0 - 1.0) * (
ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube) - m_radiusFlameTube * 1.3)
3319 + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3321 }
else if((x > (-m_radiusFlameTube2 * 1.3 - err + m_xOffsetFlameTube2))
3322 && (x < (m_radiusFlameTube2 * 1.3 + err + m_xOffsetFlameTube2))) {
3323 a_levelSetFunctionG(cellId, set) =
3324 sqrt(4.0 - 1.0) * (
ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube2) - m_radiusFlameTube2 * 1.3)
3325 + c_coordinate(cellId, 1) - m_yOffsetFlameTube2;
3329 a_levelSetFunctionG(cellId, set) = c_coordinate(cellId, 1) + 0.5;
3334 if((x > -m_radiusFlameTube - deltaX - 0.5) && (x < m_radiusFlameTube + deltaX + 0.5)) {
3335 a_levelSetFunctionG(cellId, set) =
3336 sqrt(4.0 - 1.0) * (
ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube) - (m_radiusFlameTube + deltaX))
3337 + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3341 a_levelSetFunctionG(cellId, set) = c_coordinate(cellId, 1) + 0.5;
3347 for(
MInt s = 1; s < m_noSets; s++)
3348 a_levelSetFunctionG(cellId, s) = a_levelSetFunctionG(cellId, 0);
3357 else IF_CONSTEXPR(nDim == 3) {
3358 switch(m_initialCondition) {
3364 radius =
POW2(c_coordinate(cellId, 0)) +
POW2(c_coordinate(cellId, 1)) +
POW2(c_coordinate(cellId, 2));
3365 radius = sqrt(radius);
3367 a_levelSetFunctionG(cellId, set) = (3.0 - radius);
3384 R0 = Context::getSolverProperty<MFloat>(
"radius", m_solverId, AT_, &R0);
3387 for(
MInt i = 0; i < nDim; i++) {
3392 mTerm(1, AT_,
"Property 'initialBodyCenter' has invalid amount of entries!");
3394 for(
MInt i = 0; i < nDim; i++) {
3395 center[i] = Context::getSolverProperty<MFloat>(
"initialBodyCenter", m_solverId, AT_, i);
3402 for(
MInt i = 0; i < nDim; i++) {
3403 radius +=
POW2(c_coordinate(cellId, i) - center[i]);
3405 radius = sqrt(radius);
3406 a_levelSetFunctionG(cellId, set) = radius - R0;
3413 MFloat deltaX = m_flameRadiusOffset;
3417 x = c_coordinate(cellId, 0);
3418 z = c_coordinate(cellId, 2);
3420 if((x > -m_radiusFlameTube - deltaX - 0.5) && (x < m_radiusFlameTube + deltaX + 0.5)
3421 && (z > -m_jetHalfLength - 0.5) && (z < m_jetHalfLength + 0.5)) {
3422 MFloat minXG =
ABS(c_coordinate(cellId, 0) - m_xOffsetFlameTube) - (m_jetHalfWidth + deltaX);
3423 MFloat minZG =
ABS(c_coordinate(cellId, 2)) - (m_jetHalfLength + deltaX);
3425 a_levelSetFunctionG(cellId, set) =
3426 m_initialFlameHeight * sqrt(2.0 - 1.0) * maxG + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3430 a_levelSetFunctionG(cellId, set) = c_coordinate(cellId, 1) - 1.0;
3432 if(
approx(a_levelSetFunctionG(cellId, set), 0.0, MFloatEps)) count++;
3436 for(
MInt s = 1; s < m_noSets; s++)
3437 a_levelSetFunctionG(cellId, s) = a_levelSetFunctionG(cellId, 0);
3449 x = c_coordinate(cellId, 0);
3450 z = c_coordinate(cellId, 2);
3453 if((radius < 0.5 + 0.3)) {
3454 MFloat maxG =
ABS(radius) - (0.53 + deltaX);
3455 a_levelSetFunctionG(cellId, set) =
3456 m_initialFlameHeight * sqrt(2.0 - 1.0) * maxG + c_coordinate(cellId, 1) - m_yOffsetFlameTube;
3460 a_levelSetFunctionG(cellId, set) = c_coordinate(cellId, 1) + 0.0;
3467 for(
MInt s = 1; s < m_noSets; s++)
3468 a_levelSetFunctionG(cellId, s) = a_levelSetFunctionG(cellId, 0);
3480 if(m_semiLagrange) {
3481 for(
MInt set = 0; set < m_noSets; set++) {
3483 a_oldLevelSetFunctionG(cellId, set) = a_levelSetFunctionG(cellId, set);
3487 m_log <<
"Level set function initialized on " << noCells <<
" cells" << endl;
3517 IF_CONSTEXPR(nDim == 1)
mTerm(1, AT_, "Initialize G Field from
STL does not support 1D problems");
3534 initMode =
Context::getSolverProperty<
MInt>("GFieldFromSTLInitMode", m_solverId, AT_, &initMode);
3537 auto signToBool = [](const
MInt& plusMinus) {
return (plusMinus > 0) ? true :
false; };
3542 switch(ConstructFlag) {
3547 for(
MInt set = m_startSet; set < m_noSets; set++) {
3548 for(
MInt GcellId = 0; GcellId < a_noCells(); GcellId++) {
3549 a_isGZeroCell(GcellId, set) =
false;
3554 for(
MInt set = 0; set < m_startSet; set++) {
3555 for(
MInt GcellId = 0; GcellId < a_noCells(); GcellId++) {
3556 a_levelSetFunctionG(GcellId, set) = -std::numeric_limits<MFloat>::infinity();
3561 for(
MInt set = m_startSet; set < m_noSets; set++) {
3562 for(
MInt GcellId = 0; GcellId < a_noCells(); GcellId++) {
3563 MFloat target[3] = {0, 0, 0};
3564 if(a_isHalo(GcellId))
continue;
3565 if(!c_isLeafCell(GcellId))
continue;
3568 for(
MInt Dir = 0; Dir < nDim; Dir++)
3569 target[Dir] = c_coordinate(GcellId, Dir);
3571 if(m_GCtrlPntMethod == 1 || m_GCtrlPntMethod == 3) m_gCtrlPnt.CtrlPnt1_quvw(target);
3572 a_hasPositiveSign(GcellId, set) = signToBool(determineLevelSetSignFromSTL(target, set));
3573 if(m_levelSetSign[set] < 0) {
3574 a_hasPositiveSign(GcellId, set) = signToBool(-a_levelSetSign(GcellId, set));
3576 a_levelSetFunctionG(GcellId, set) = a_levelSetSign(GcellId, set);
3584 for(
MInt set = m_startSet; set < m_noSets; set++) {
3585 MInt noCells = a_noG0Cells(set);
3586 if(initMode > 0 && initMode < 3) noCells = a_noCells();
3587 for(
MInt count = 0; count < noCells; count++) {
3589 if(initMode == 0 || initMode == 3) {
3590 cellId = a_G0CellId(count, set);
3594 if(a_isHalo(cellId))
continue;
3595 if(!c_isLeafCell(cellId))
continue;
3600 for(
MInt n = 0; n < nDim; n++) {
3601 radius += c_coordinate(cellId, n) * c_coordinate(cellId, n);
3603 radius = sqrt(radius);
3605 MFloat lvs = radius - 0.5;
3606 a_levelSetFunctionG(cellId, set) = lvs;
3609 MInt closestElement;
3610 IF_CONSTEXPR(nDim == 2) {
3611 MFloat closestPoint[2] = {F0, F0};
3612 MFloat refPoint[2] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1)};
3613 a_levelSetFunctionG(cellId, set) *=
3614 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3616 else IF_CONSTEXPR(nDim == 3) {
3617 MFloat closestPoint[3] = {F0, F0, F0};
3618 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
3619 a_levelSetFunctionG(cellId, set) *=
3620 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3632 if(m_GCtrlPntMethod == 2 && ConstructFlag != 5) {
3634 m_gCtrlPnt.CtrlPnt2_UpdateAllNormalVector();
3635 m_gCtrlPnt.CtrlPnt2_Update();
3639 for(
MInt set = 0; set < m_startSet; set++) {
3640 if(ConstructFlag == 5 && !m_geometryChange[set])
continue;
3641 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
3643 a_levelSetFunctionG(cellId, set) = -std::numeric_limits<MFloat>::infinity();
3648 for(
MInt set = m_startSet; set < m_noSets; set++) {
3649 if(ConstructFlag == 5 && !m_geometryChange[set])
continue;
3650 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
3652 MFloat target[3] = {0, 0, 0};
3653 if(a_isHalo(cellId))
continue;
3654 if(!c_isLeafCell(cellId))
continue;
3657 for(
MInt Dir = 0; Dir < nDim; Dir++)
3658 target[Dir] = c_coordinate(cellId, Dir);
3660 if(m_GCtrlPntMethod == 1 || m_GCtrlPntMethod == 3) m_gCtrlPnt.CtrlPnt1_quvw(target);
3661 a_hasPositiveSign(cellId, set) = signToBool(determineLevelSetSignFromSTL(target, set));
3662 if(m_levelSetSign[set] < 0) {
3663 a_hasPositiveSign(cellId, set) = signToBool(-a_levelSetSign(cellId, set));
3665 a_levelSetFunctionG(cellId, set) = a_levelSetSign(cellId, set);
3670 for(
MInt set = 0; set < m_noSets; set++) {
3671 std::vector<MInt>().swap(m_bandCells[set]);
3674 determineBandCells();
3677 for(
MInt set = m_startSet; set < m_noSets; set++) {
3678 if(ConstructFlag == 5 && !m_geometryChange[set])
continue;
3679 MInt noCells = a_noG0Cells(set);
3680 if(initMode > 0 && initMode < 3) noCells = a_noBandCells(set);
3682 for(
MInt count = 0; count < noCells; count++) {
3684 if(initMode == 0 || initMode == 3) {
3685 cellId = a_G0CellId(count, set);
3687 cellId = a_bandCellId(count, set);
3689 if(a_isHalo(cellId))
continue;
3690 if(!c_isLeafCell(cellId))
continue;
3695 for(
MInt n = 0; n < nDim; n++) {
3696 radius += c_coordinate(cellId, n) * c_coordinate(cellId, n);
3698 radius = sqrt(radius);
3700 const MFloat lvs = radius - 0.5;
3701 a_levelSetFunctionG(cellId, set) = lvs;
3704 MInt closestElement;
3705 IF_CONSTEXPR(nDim == 2) {
3706 MFloat closestPoint[2] = {F0, F0};
3707 MFloat refPoint[2] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1)};
3709 if(abs(a_levelSetFunctionG(cellId, set)) > 1.0) {
3710 a_hasPositiveSign(cellId, set) = signToBool(determineLevelSetSignFromSTL(refPoint, set));
3711 if(m_levelSetSign[set] < 0) {
3712 a_hasPositiveSign(cellId, set) = signToBool(-a_levelSetSign(cellId, set));
3714 a_levelSetFunctionG(cellId, set) = a_levelSetSign(cellId, set);
3716 a_levelSetFunctionG(cellId, set) *=
3717 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3719 else IF_CONSTEXPR(nDim == 3) {
3720 MFloat closestPoint[3] = {F0, F0, F0};
3721 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
3723 if(abs(a_levelSetFunctionG(cellId, set)) > 1.0) {
3724 a_hasPositiveSign(cellId, set) = signToBool(determineLevelSetSignFromSTL(refPoint, set));
3725 if(m_levelSetSign[set] < 0) {
3726 a_hasPositiveSign(cellId, set) = signToBool(-a_levelSetSign(cellId, set));
3728 a_levelSetFunctionG(cellId, set) = a_levelSetSign(cellId, set);
3730 a_levelSetFunctionG(cellId, set) *=
3731 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3742 for(
MInt set = 0; set < m_startSet; set++) {
3743 if(!m_geometryChange[set])
continue;
3745 a_oldLevelSetFunctionG(cellId, set) = -std::numeric_limits<MFloat>::infinity();
3750 for(
MInt set = m_startSet; set < m_noSets; set++) {
3751 if(!m_geometryChange[set])
continue;
3753 MFloat target[3] = {0, 0, 0};
3754 if(a_isHalo(cellId))
continue;
3755 if(!c_isLeafCell(cellId))
continue;
3757 for(
MInt Dir = 0; Dir < nDim; Dir++)
3758 target[Dir] = c_coordinate(cellId, Dir);
3760 if(m_GCtrlPntMethod == 1 || m_GCtrlPntMethod == 3) m_gCtrlPnt.CtrlPnt1_quvw(target);
3761 a_hasPositiveSign(cellId, set) = signToBool(determineLevelSetSignFromSTL(target, set));
3762 if(m_levelSetSign[set] < 0) {
3763 a_hasPositiveSign(cellId, set) = signToBool(-a_levelSetSign(cellId, set));
3765 a_oldLevelSetFunctionG(cellId, set) = a_levelSetSign(cellId, set);
3770 for(
MInt set = m_startSet; set < m_noSets; set++) {
3771 if(!m_geometryChange[set])
continue;
3773 if(a_isHalo(cellId))
continue;
3774 if(!c_isLeafCell(cellId))
continue;
3779 for(
MInt n = 0; n < nDim; n++) {
3780 radius += c_coordinate(cellId, n) * c_coordinate(cellId, n);
3782 radius = sqrt(radius);
3784 const MFloat lvs = radius - 0.5;
3785 a_oldLevelSetFunctionG(cellId, set) = lvs;
3788 MInt closestElement;
3790 MFloat closestPoint[2] = {F0, F0};
3791 MFloat refPoint[2] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1)};
3792 a_oldLevelSetFunctionG(cellId, set) *=
3793 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3794 }
else if(nDim == 3) {
3795 MFloat closestPoint[3] = {F0, F0, F0};
3796 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
3797 a_oldLevelSetFunctionG(cellId, set) *=
3798 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3808 ASSERT(initMode == 1,
"");
3809 ASSERT(m_STLReinitMode == 2,
"");
3812 for(
auto it = m_refinedCells.begin(); it != m_refinedCells.end(); it++) {
3814 const MInt set = it->second;
3815 ASSERT(cellId > -1 && cellId < a_noCells(),
"");
3817 ASSERT(!m_computeSet_backup[set] || m_maxLevelChange,
"");
3818 ASSERT(set >= 0 && set < m_noSets,
"");
3819 a_oldLevelSetFunctionG(cellId, set) = -std::numeric_limits<MFloat>::infinity();
3821 for(
MInt setI = m_startSet; setI < m_noSets; setI++) {
3822 if(!m_maxLevelChange && m_computeSet_backup[setI] && !m_virtualSurgery)
continue;
3823 a_oldLevelSetFunctionG(cellId, setI) = -std::numeric_limits<MFloat>::infinity();
3829 for(
auto it = m_refinedCells.begin(); it != m_refinedCells.end(); it++) {
3831 const MInt set = it->second;
3832 if(a_isHalo(cellId))
continue;
3833 if(!c_isLeafCell(cellId))
continue;
3835 MFloat target[3] = {0, 0, 0};
3836 for(
MInt dir = 0; dir < nDim; dir++) {
3837 target[dir] = c_coordinate(cellId, dir);
3839 ASSERT(m_GCtrlPntMethod == 2,
"");
3841 a_hasPositiveSign(cellId, set) = signToBool(determineLevelSetSignFromSTL(target, set));
3842 if(m_levelSetSign[set] < 0) {
3843 a_hasPositiveSign(cellId, set) = signToBool(-a_levelSetSign(cellId, set));
3845 a_oldLevelSetFunctionG(cellId, set) = a_levelSetSign(cellId, set);
3847 for(
MInt setI = m_startSet; setI < m_noSets; setI++) {
3848 if(!m_maxLevelChange && m_computeSet_backup[setI] && !m_virtualSurgery)
continue;
3849 a_hasPositiveSign(cellId, setI) = signToBool(determineLevelSetSignFromSTL(target, setI));
3850 if(m_levelSetSign[setI] < 0) {
3851 a_hasPositiveSign(cellId, setI) = signToBool(-a_levelSetSign(cellId, setI));
3853 a_oldLevelSetFunctionG(cellId, setI) = a_levelSetSign(cellId, setI);
3860 for(
auto it = m_refinedCells.begin(); it != m_refinedCells.end(); it++) {
3862 const MInt set = it->second;
3863 if(a_isHalo(cellId))
continue;
3864 if(!c_isLeafCell(cellId))
continue;
3867 MInt closestElement;
3868 IF_CONSTEXPR(nDim == 2) {
3869 MFloat closestPoint[2] = {F0, F0};
3870 MFloat refPoint[2] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1)};
3871 a_oldLevelSetFunctionG(cellId, set) *=
3872 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set, m_sphereRadiusLimit);
3874 else IF_CONSTEXPR(nDim == 3) {
3875 MFloat closestPoint[3] = {F0, F0, F0};
3876 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
3877 a_oldLevelSetFunctionG(cellId, set) *=
3878 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set, m_sphereRadiusLimit);
3881 for(
MInt setI = m_startSet; setI < m_noSets; setI++) {
3882 if(!m_maxLevelChange && m_computeSet_backup[setI] && !m_virtualSurgery)
continue;
3883 MInt closestElement;
3884 IF_CONSTEXPR(nDim == 2) {
3885 MFloat closestPoint[2] = {F0, F0};
3886 MFloat refPoint[2] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1)};
3887 a_oldLevelSetFunctionG(cellId, setI) *=
3888 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, setI, m_sphereRadiusLimit);
3890 else IF_CONSTEXPR(nDim == 3) {
3891 MFloat closestPoint[3] = {F0, F0, F0};
3892 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
3893 a_oldLevelSetFunctionG(cellId, setI) *=
3894 computeDistanceFromSTL(refPoint, &closestElement, closestPoint, setI, m_sphereRadiusLimit);
3902 mTerm(1, AT_,
"Unknown constructFlag");
3909 if(ConstructFlag == 0 || ConstructFlag == 2) {
3910 if(m_STLReinitMode == 2)
return;
3911 IF_CONSTEXPR(nDim == 2) {
3912 if(m_STLReinitMode != 0) {
3913 computeNormalVectors();
3919 MInt tmp_gReinitIterations = m_gReinitIterations;
3920 m_gReinitIterations =
3921 Context::getSolverProperty<MInt>(
"gReinitIterationsForGFieldFromSTL", m_solverId, AT_, &m_gReinitIterations);
3938 if(m_STLReinitMode == 0 || m_STLReinitMode == 3 || m_STLReinitMode == 1) {
3939 levelSetConstrainedReinitialization(2, m_startSet, m_noSets, 1);
3941 computeNormalVectors();
3943 if(m_STLReinitMode == 0 || m_STLReinitMode == 1) {
3944 levelSetConstrainedReinitialization(2, m_startSet, m_noSets, 1);
3945 }
else if(m_STLReinitMode == 3) {
3946 levelSetHighOrderConstrainedReinitialization(2, m_startSet, m_noSets, 1);
3949 m_gReinitIterations = tmp_gReinitIterations;
3951 if(m_STLReinitMode == 0 || m_STLReinitMode == 3) {
3953 if(a_isHalo(cellId))
continue;
3954 if(!c_isLeafCell(cellId))
continue;
3955 if(a_level(cellId) != a_maxGCellLevel())
continue;
3956 for(
MInt dir = 0; dir < m_noDirs; dir++) {
3957 const MInt nghbrId = c_neighborId(cellId, dir);
3958 if(nghbrId == -1 || nghbrId == cellId) {
3959 MFloat refPoint[3] = {F0, F0, F0};
3960 for(
MInt i = 0; i < nDim; i++) {
3961 refPoint[i] = c_coordinate(cellId, i);
3963 MInt closestElement;
3964 MFloat closestPoint[3] = {F0, F0, F0};
3965 for(
MInt set = m_startSet; set < m_noSets; set++) {
3966 MFloat sign = determineLevelSetSignFromSTL(refPoint, set);
3967 if(m_levelSetSign[set] < 0) sign *= -1.0;
3968 MFloat phi = sign * computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3970 a_levelSetFunctionG(cellId, set) = phi;
3975 }
else if(m_STLReinitMode == 1) {
3980 if(!c_isLeafCell(cellId))
continue;
3981 if(a_level(cellId) != a_maxGCellLevel())
continue;
3982 if(a_isHalo(cellId))
continue;
3983 for(
MInt dir = 0; dir < m_noDirs; dir++) {
3984 MInt nghbrId = c_neighborId(cellId, dir);
3985 if(nghbrId == -1 || nghbrId == cellId) {
3986 MFloat refPoint[3] = {F0, F0, F0};
3987 for(
MInt i = 0; i < nDim; i++) {
3988 refPoint[i] = c_coordinate(cellId, i);
3990 MInt closestElement;
3991 MFloat closestPoint[3] = {F0, F0, F0};
3992 for(
MInt set = m_startSet; set < m_noSets; set++) {
3993 MFloat sign = determineLevelSetSignFromSTL(refPoint, set);
3994 if(m_levelSetSign[set] < 0) sign *= -1.0;
3995 MFloat phi = sign * computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
3996 a_levelSetFunctionG(cellId, set) = phi;
4014 MInt containingCell = -1;
4015 MInt containingDomain = -1;
4018 bodyId = m_bodiesToCompute[body];
4020 std::vector<MInt> dir;
4021 dir.resize(2 * nDim);
4023 std::vector<MFloat> vel;
4026 MFloat minVel = std::numeric_limits<MFloat>::max();
4030 rotateLevelSet(2, &vel[0], bodyId, xCoord, xOld, &m_semiLagrange_xRot_STL[body * nDim]);
4031 for(
MInt i = 0; i < nDim; i++) {
4032 if(abs(vel[i]) > maxVel) {
4034 maxVel = abs(vel[i]);
4036 if(abs(vel[i]) < minVel) {
4038 minVel = abs(vel[i]);
4041 for(
MInt i = 0; i < nDim; i++) {
4045 dir[2 * nDim - 1] = i * 2 + 1;
4048 dir[2 * nDim - 1] = i * 2;
4050 }
else if(i == dirMin) {
4052 dir[nDim - 1] = i * 2;
4053 dir[nDim] = i * 2 + 1;
4055 dir[nDim - 1] = i * 2 + 1;
4071 MInt oDir[6] = {1, 2, 0, 2, 0, 1};
4073 for(
MInt n = 0; n < 2; n++) {
4075 for(
MInt i = 0; i < nDim; i++) {
4076 nghbrId = c_neighborId(cellId, dir[i + offset]);
4077 if(nghbrId == -1)
continue;
4079 containingCell = a_containingCell(nghbrId, body);
4080 if(containingCell > -1 && std::find(m_newCells.begin(), m_newCells.end(), nghbrId) == m_newCells.end()) {
4081 a_containingCell(cellId, body) = containingCell;
4083 if(!m_reconstructOldG) {
4084 containingDomain = a_containingDomain(nghbrId, body);
4085 a_containingDomain(cellId, body) = containingDomain;
4092 for(
MInt i = 0; i < nDim; i++) {
4093 if(!a_hasNeighbor(cellId, dir[i + offset]))
continue;
4094 nghbrId = c_neighborId(cellId, dir[i + offset]);
4095 for(
MInt j = 0; j < (nDim - 1); j++) {
4096 if(!a_hasNeighbor(nghbrId, dir[oDir[i * 2 + j] + offset]))
continue;
4097 nghbrId = c_neighborId(nghbrId, dir[oDir[i * 2 + j] + offset]);
4099 containingCell = a_containingCell(nghbrId, body);
4100 if(containingCell > -1 && std::find(m_newCells.begin(), m_newCells.end(), nghbrId) == m_newCells.end()) {
4101 a_containingCell(cellId, body) = containingCell;
4102 if(!m_reconstructOldG) {
4103 containingDomain = a_containingDomain(nghbrId, body);
4104 a_containingDomain(cellId, body) = containingDomain;
4113 mTerm(1, AT_,
"Get containingCell from neighbor did not work!");
4131 if(m_noBodyBndryCndIds > 0) {
4132 ASSERT(m_noBodiesInSet[set] <= m_noBodyBndryCndIds,
4133 to_string(m_noBodiesInSet[set]) +
" " + to_string(m_noBodyBndryCndIds));
4136 IF_CONSTEXPR(nDim == 2) {
4137 if(m_geometry->pointIsInsideMBElements(target, m_bodyBndryCndIds, m_setToBodiesTable[set], m_noBodiesInSet[set]))
4141 if(m_geometry->pointIsInsideMBElements2(target, m_bodyBndryCndIds, m_setToBodiesTable[set], m_noBodiesInSet[set]))
4163 MFloat q[3] = {F0, F0, F0};
4164 for(
MInt dim = 0; dim < nDim; dim++)
4165 q[dim] = target[dim];
4168 std::vector<MInt> nodeList;
4169 MInt noNodes_set = 0;
4170 *closestElement = -1;
4171 const MFloat cellLength = c_cellLengthAtLevel(a_maxGCellLevel(set));
4172 const MFloat cellHalfLength = c_cellLengthAtLevel(a_maxGCellLevel(set) + 1);
4176 MFloat enlargeFactor = 1.01;
4178 const MFloat radiusLimitSphere = sphereRadiusFactor * m_gBandWidth;
4180 while(noNodes_set == 0 && enlargeFactor < radiusLimitSphere)
4184 const MFloat radius = cellHalfLength * enlargeFactor * sqrt(nDim);
4187 m_geometry->getSphereIntersectionMBElements(q, radius, nodeList);
4188 for(
MInt node = 0; node < (signed)nodeList.size(); node++) {
4189 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
4190 const MInt body = m_setToBodiesTable[set][
b];
4191 const MInt bcId = m_bodyBndryCndIds[body];
4192 if(m_geometry->mbelements[nodeList[node]].m_bndCndId == bcId) {
4193 nodeList[noNodes_set] = nodeList[node];
4200 enlargeFactor *= 1.5;
4203 if(noNodes_set == 0) {
4204 mindist = F2 * m_gBandWidth * cellLength;
4209 for(
MInt inode = 0; inode < noNodes_set; inode++) {
4210 MInt e = nodeList[inode];
4214 MInt haveNormal = 0;
4216 MFloat transformationMatrix[3][3] = {{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}};
4217 haveNormal = checkNormal().PointInsideTriangle(el, q, transformationMatrix);
4220 IF_CONSTEXPR(nDim == 2) {
4222 MFloat quv[3] = {0, 0, 0};
4224 MFloat vuv[3] = {0, 0, 0};
4225 for(
MInt i = 0; i < nDim; i++) {
4230 checkNormal().rotation(q, quv, transformationMatrix);
4231 checkNormal().rotation(v, vuv, transformationMatrix);
4234 MFloat point[2] = {F0, F0};
4235 if(n[0] * (q[0] - v[0]) + n[1] * (q[1] - v[1]) > F0) {
4236 point[0] = q[0] - n[0] *
dist;
4237 point[1] = q[1] - n[1] *
dist;
4239 point[0] = q[0] + n[0] *
dist;
4240 point[1] = q[1] + n[1] *
dist;
4245 *closestElement = e;
4246 closestPoint[0] = point[0];
4247 closestPoint[1] = point[1];
4249 if(mindist >
dist) {
4251 *closestElement = e;
4252 closestPoint[0] = point[0];
4253 closestPoint[1] = point[1];
4260 for(
MInt i = 0; i < nDim; i++) {
4265 MFloat d = -(n[0] * v[0] + n[1] * v[1] + n[2] * v[2]);
4266 MFloat dist = fabs(n[0] * q[0] + n[1] * q[1] + n[2] * q[2] + d);
4267 MFloat point[3] = {F0, F0, F0};
4268 if(n[0] * (q[0] - v[0]) + n[1] * (q[1] - v[1]) + n[2] * (q[2] - v[2]) > F0) {
4269 point[0] = q[0] - n[0] *
dist;
4270 point[1] = q[1] - n[1] *
dist;
4271 point[2] = q[2] - n[2] *
dist;
4273 point[0] = q[0] + n[0] *
dist;
4274 point[1] = q[1] + n[1] *
dist;
4275 point[2] = q[2] + n[2] *
dist;
4279 *closestElement = e;
4280 closestPoint[0] = point[0];
4281 closestPoint[1] = point[1];
4282 closestPoint[2] = point[2];
4284 if(mindist >
dist) {
4286 *closestElement = e;
4287 closestPoint[0] = point[0];
4288 closestPoint[1] = point[1];
4289 closestPoint[2] = point[2];
4295 IF_CONSTEXPR(nDim == 2) {
4298 for(
MInt i = 0; i < noVertices; i++) {
4300 for(
MInt j = 0; j < nDim; j++) {
4303 MFloat dist = sqrt(pow(q[0] - v[0], 2) + pow(q[1] - v[1], 2) + pow(q[2] - v[2], 2));
4306 *closestElement = e;
4307 closestPoint[0] = v[0];
4308 closestPoint[1] = v[1];
4310 if(mindist >
dist) {
4312 *closestElement = e;
4313 closestPoint[0] = v[0];
4314 closestPoint[1] = v[1];
4321 for(
MInt i = 0; i < noVertices; i++) {
4322 MFloat v1[3] = {0, 0, 0}, v2[3] = {0, 0, 0};
4323 for(
MInt j = 0; j < nDim; j++) {
4325 v2[j] = mbelements[e].
m_vertices[(i + 1) % noVertices][j];
4328 MFloat vp[3] = {v2[0] - v1[0], v2[1] - v1[1], v2[2] - v1[2]};
4329 MFloat vq[3] = {q[0] - v1[0], q[1] - v1[1], q[2] - v1[2]};
4331 MFloat norm_vp = sqrt(vp[0] * vp[0] + vp[1] * vp[1] + vp[2] * vp[2]);
4332 MFloat vp_hat[3] = {vp[0] / norm_vp, vp[1] / norm_vp, vp[2] / norm_vp};
4333 MFloat vq_hat[3] = {vq[0] / norm_vp, vq[1] / norm_vp, vq[2] / norm_vp};
4335 MFloat I = vp_hat[0] * vq_hat[0] + vp_hat[1] * vq_hat[1] + vp_hat[2] * vq_hat[2];
4337 MFloat point[3] = {F0, F0, F0};
4338 if((0.0 <= I) && (I <= 1.0)) {
4339 MFloat x_e[3] = {v1[0] + I * vp[0], v1[1] + I * vp[1], v1[2] + I * vp[2]};
4340 dist = sqrt(
POW2(q[0] - x_e[0]) +
POW2(q[1] - x_e[1]) +
POW2(q[2] - x_e[2]));
4345 dist = sqrt(vq[0] * vq[0] + vq[1] * vq[1] + vq[2] * vq[2]);
4353 *closestElement = e;
4354 closestPoint[0] = point[0];
4355 closestPoint[1] = point[1];
4356 closestPoint[2] = point[2];
4358 if(mindist >
dist) {
4360 *closestElement = e;
4361 closestPoint[0] = point[0];
4362 closestPoint[1] = point[1];
4363 closestPoint[2] = point[2];
4388 computeNormalVectorsAtFront();
4391 m_gCtrlPnt.CtrlPnt2_UpdateAllNormalVector();
4392 m_gCtrlPnt.CtrlPnt2_Update();
4396 MInt maxNoG0Cells = 0;
4397 for(
MInt set = m_startSet; set < m_noSets; set++) {
4398 if(!m_computeSet[set])
continue;
4399 maxNoG0Cells =
mMax(maxNoG0Cells, a_noG0Cells(set));
4403 for(
MInt set = m_startSet; set < m_noSets; set++) {
4404 if(!m_computeSet[set])
continue;
4405 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
4407 gradCurvature[IDX_LSSET(
id, set)] = F0;
4408 cellId = a_G0CellId(
id, set);
4409 for(
MInt i = 0; i < nDim; i++) {
4410 MFloat gradComponent = F0;
4411 nghbrL = c_neighborId(cellId, 2 * i);
4412 nghbrR = c_neighborId(cellId, 2 * i + 1);
4413 gradComponent = (a_curvatureG(nghbrR, set) - a_curvatureG(nghbrL, set)) / (2.0 * m_gCellDistance);
4414 gradCurvature[IDX_LSSET(
id, set)] += (gradComponent * gradComponent);
4416 gradCurvature[IDX_LSSET(
id, set)] = sqrt(gradCurvature[IDX_LSSET(
id, set)]);
4421 for(
MInt set = m_startSet; set < m_noSets; set++) {
4422 if(!m_computeSet[set])
continue;
4440 MInt maxThresholdLevels = 3;
4441 maxThresholdLevels =
4442 Context::getSolverProperty<MInt>(
"levelSetMaxCorrectionThresholdLevels", m_solverId, AT_, &maxThresholdLevels);
4444 list<MInt> m_unmarked;
4445 list<MInt>::iterator it_unmarked;
4447 for(
MInt c = 0; c < a_noG0Cells(set); c++) {
4449 m_unmarked.push_back(c);
4453 MInt curThresholdLevel = 1;
4454 while((curThresholdLevel <= maxThresholdLevels) && (m_unmarked.size() != 0)) {
4455 MFloat avgCurvature = 0.0;
4456 it_unmarked = m_unmarked.begin();
4458 while(it_unmarked != m_unmarked.end()) {
4459 avgCurvature += (gradCurvature[IDX_LSSET(*it_unmarked, set)] * gradCurvature[IDX_LSSET(*it_unmarked, set)]);
4462 avgCurvature /= (
MFloat)m_unmarked.size();
4463 avgCurvature = sqrt(avgCurvature);
4465 it_unmarked = m_unmarked.begin();
4466 while(it_unmarked != m_unmarked.end()) {
4467 if(gradCurvature[IDX_LSSET(*it_unmarked, set)] > avgCurvature) {
4468 marker[*it_unmarked] = curThresholdLevel;
4469 *it_unmarked = a_noG0Cells(set);
4474 m_unmarked.remove(a_noG0Cells(set));
4476 curThresholdLevel++;
4479 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
4481 m_d[IDX_LSSET(cellId, set)] = F0;
4482 m_correction[IDX_LSSET(cellId, set)] = F0;
4483 if(marker[
id] > 0) {
4506 MInt closestElement;
4507 MFloat closestPoint[3] = {F0, F0, F0};
4508 MFloat refPoint[3] = {c_coordinate(cellId, 0), c_coordinate(cellId, 1), c_coordinate(cellId, 2)};
4509 MFloat dist_q = computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
4510 m_d[IDX_LSSET(cellId, set)] = dist_q;
4512 MInt sign = determineLevelSetSignFromSTL(refPoint, set);
4513 m_correction[IDX_LSSET(cellId, set)] = sign;
4515 a_levelSetFunctionG(cellId, set) = m_levelSetSign[set] * (
MFloat)sign * dist_q;
4536 MBool regrid =
false;
4539 for(
MInt set = m_startSet; set < m_noSets; set++) {
4540 if(!m_computeSet[set])
continue;
4541 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
4542 if(a_isHalo(a_bandCellId(
id, set)))
continue;
4543 if(a_regridTriggerG(a_bandCellId(
id, set))) {
4545 m_log << a_bandCellId(
id, set) <<
" with set " << set <<
" caused regridding " << endl;
4565 MString reinitMethod = m_reinitMethod;
4571 reinitMethod = m_gapReinitMethod;
4574 startSet = m_startSet;
4579 if(m_semiLagrange) {
4580 ASSERT(reinitMethod == m_gapReinitMethod,
"");
4581 ASSERT(m_guaranteeReinit,
"");
4585#ifndef orderOfAccuracyTest
4587 if(!mode || ((levelSetReinitializationTrigger() || m_guaranteeReinit) && !m_maintainOuterBandLayers)) {
4591 if(m_GFieldInitFromSTL && m_GWithReConstruction && mode) {
4593 spatiallyAdaptiveCorrectionFromSTL();
4601 levelSetConstrainedReinitialization(1, startSet, endSet, mode);
4605 levelSetConstrainedReinitialization(2, startSet, endSet, mode);
4609 levelSetHighOrderConstrainedReinitialization(1, startSet, endSet, mode);
4613 levelSetHighOrderConstrainedReinitialization(2, startSet, endSet, mode);
4617 levelSetHighOrderConstrainedReinitialization(4, startSet, endSet, mode);
4621 levelSetHighOrderConstrainedReinitialization(6, startSet, endSet, mode);
4630 ASSERT(!m_semiLagrange,
"");
4636 maintainOuterBandLayers(1, startSet, endSet);
4642 maintainOuterBandLayers(5, startSet, endSet);
4651 if(domainId() == 0) {
4654 stringstream reinitFile;
4655 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
4656 datei = fopen((reinitFile.str()).c_str(),
"a+");
4657 fprintf(datei,
"\n");
4667 levelSetConstrainedReinitialization(1, startSet, endSet, mode);
4671 levelSetConstrainedReinitialization(2, startSet, endSet, mode);
4675 levelSetHighOrderConstrainedReinitialization(1, startSet, endSet, mode);
4679 levelSetHighOrderConstrainedReinitialization(2, startSet, endSet, mode);
4683 levelSetHighOrderConstrainedReinitialization(6, startSet, endSet, mode);
4697 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
4698 cellId = a_G0CellId(
id, set);
4700 ABS(sqrt(
POW2(c_coordinate(cellId, 0)) +
POW2(c_coordinate(cellId, 1))) - 3 + a_levelSetFunctionG(cellId, set));
4702 error /= a_noG0Cells(set);
4703 cerr <<
"Error after reinitialization: " << error << endl;
4706 datei = fopen(
"ErrorInGamma",
"a+");
4708 fprintf(datei,
" %f", error);
4709 fprintf(datei,
"\n");
4726 MFloat temp = F0, avgDeviation = F0, maxDeviation = F0;
4727 MInt globalNoG0Cells = F0;
4731 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
4732 cellId = a_G0CellId(
id, set);
4733 if(a_isHalo(cellId))
continue;
4735 for(
MInt i = 0; i < nDim; i++)
4736 temp +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
4737 temp =
POW2(sqrt(temp) - F1);
4739 avgDeviation += temp;
4740 maxDeviation =
mMax(maxDeviation, sqrt(temp));
4744 MPI_Allreduce(MPI_IN_PLACE, &globalNoG0Cells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"globalNoG0Cells");
4745 MPI_Allreduce(MPI_IN_PLACE, &avgDeviation, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"avgDeviation");
4746 MPI_Allreduce(MPI_IN_PLACE, &maxDeviation, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxDeviation");
4747 avgDeviation = sqrt(avgDeviation / (
MFloat)globalNoG0Cells);
4750 if(domainId() == 0) {
4753 stringstream reinitFile;
4754 reinitFile <<
"Reinitialization_" << m_solverId <<
"_" << domainId();
4755 datei = fopen((reinitFile.str()).c_str(),
"a+");
4757 fprintf(datei,
" %f", time());
4759 fprintf(datei,
" %f", avgDeviation);
4760 fprintf(datei,
" %f", maxDeviation);
4761 fprintf(datei,
" %f", m_reinitThreshold);
4762 fprintf(datei,
" %d", globalNoG0Cells);
4767 if(fabs(maxDeviation) > m_reinitThreshold && fabs(avgDeviation) > m_reinitThresholdAvg)
4781 MInt endSet = m_noSets;
4782 if(m_buildCollectedLevelSetFunction &&
globalTimeStep > 0) startSet = 1;
4783 if(computingSet >= 0) {
4784 startSet = computingSet;
4785 endSet = computingSet + 1;
4786 ASSERT(m_computeSet[computingSet],
"");
4787 ASSERT(m_changedSet[computingSet],
"");
4793 for(
MInt set = startSet; set < endSet; set++) {
4794 if(!m_computeSet[set])
continue;
4798 for(
MInt id = 0;
id < a_noBandBndryCells(set);
id++) {
4799 const MInt cellId = a_bandBndryCellId(
id, set);
4800 if(a_isHalo(cellId)) {
4803 if(a_level(cellId) > a_maxGCellLevel(0))
continue;
4805 for(
MInt d = 0; d < m_noDirs; d++) {
4806 if(a_hasNeighbor(cellId, d) == 0) {
4809 if(!a_inBandG(c_neighborId(cellId, d), set)) {
4812 if(a_isGBoundaryCellG(c_neighborId(cellId, d), set)) {
4815 if(a_levelSetFunctionG(cellId, set) > F0) {
4816 a_levelSetFunctionG(cellId, set) =
mMin(a_levelSetFunctionG(cellId, set),
4817 a_levelSetFunctionG(c_neighborId(cellId, d), set) + m_gCellDistance);
4819 a_levelSetFunctionG(cellId, set) =
mMax(a_levelSetFunctionG(cellId, set),
4820 a_levelSetFunctionG(c_neighborId(cellId, d), set) - m_gCellDistance);
4846 MInt endSet = m_noSets;
4850 if(computingSet >= 0) {
4851 startSet = computingSet;
4852 endSet = computingSet + 1;
4853 ASSERT(m_computeSet[computingSet],
"");
4862 for(
MInt set = startSet; set < endSet; set++) {
4863 if(!m_computeSet[set])
continue;
4866 for(
MInt cell = 0; cell < a_noCells(); cell++) {
4867 skip.p[cell] =
false;
4871 MInt noTempCells = 0;
4872 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
4874 const MInt parentId = c_parentId(cellId);
4876 if(!skip.p[parentId]) {
4877 tempCells.p[noTempCells] = parentId;
4879 a_levelSetFunctionG(parentId, set) = F0;
4880 MInt noChildren = c_noChildren(parentId);
4881 if(!(noChildren > 0)) {
4882 cerr <<
"parent: " << parentId << endl;
4883 cerr <<
"gcell: " <<
cellId << endl;
4884 mTerm(1, AT_,
"this should not occur: parent g cell with m_noChildIdsG == 0...");
4886 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
4887 if(c_childId(parentId, child) < 0)
continue;
4888 a_levelSetFunctionG(parentId, set) += a_levelSetFunctionG(c_childId(parentId, child), set);
4890 a_levelSetFunctionG(parentId, set) /= (
MFloat)noChildren;
4891 skip.p[parentId] =
true;
4898 while(noTempCells > 0) {
4899 const MInt listSize = noTempCells;
4901 for(
MInt cell = 0; cell < listSize; cell++) {
4902 const MInt gCellId = tempCells.p[cell];
4903 const MInt parentId = c_parentId(gCellId);
4905 if(!skip.p[parentId]) {
4906 tempCells.p[noTempCells] = parentId;
4908 a_levelSetFunctionG(parentId, set) = F0;
4909 MInt noChildren = c_noChildren(parentId);
4910 if(!(noChildren > 0)) {
4911 cerr << parentId << endl;
4912 cerr <<
"gcell: " << gCellId << endl;
4913 mTerm(1, AT_,
"this should not occur: parent g cell with m_noChildIdsG == 0...");
4915 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
4916 if(c_childId(parentId, child) < 0)
continue;
4917 a_levelSetFunctionG(parentId, set) += a_levelSetFunctionG(c_childId(parentId, child), set);
4919 a_levelSetFunctionG(parentId, set) /= (
MFloat)noChildren;
4920 skip.p[parentId] =
true;
4933 MInt endSet = m_noSets;
4937 if(computingSet >= 0) {
4938 startSet = computingSet;
4939 endSet = computingSet + 1;
4940 ASSERT(m_computeSet[computingSet],
"");
4949 for(
MInt set = startSet; set < endSet; set++) {
4950 if(!m_computeSet[set])
continue;
4953 for(
MInt cell = 0; cell < a_noCells(); cell++) {
4954 skip.p[cell] =
false;
4958 MInt noTempCells = 0;
4959 for(
MInt gCellId = 0; gCellId < a_noCells(); gCellId++) {
4960 if(a_isHalo(gCellId))
continue;
4961 if(!c_isLeafCell(gCellId))
continue;
4962 MInt parentId = c_parentId(gCellId);
4964 if(!skip.p[parentId]) {
4965 tempCells.p[noTempCells] = parentId;
4967 a_levelSetFunctionG(parentId, set) = F0;
4968 MInt noChildren = c_noChildren(parentId);
4969 if(!(noChildren > 0)) {
4970 cerr <<
"parent: " << parentId << endl;
4971 cerr <<
"gcell: " << gCellId << endl;
4972 mTerm(1, AT_,
"this should not occur: parent g cell with m_noChildIdsG == 0...");
4974 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
4975 if(c_childId(parentId, child) < 0)
continue;
4976 a_levelSetFunctionG(parentId, set) += a_levelSetFunctionG(c_childId(parentId, child), set);
4978 a_levelSetFunctionG(parentId, set) /= (
MFloat)noChildren;
4979 skip.p[parentId] =
true;
4986 while(noTempCells > 0) {
4987 MInt listSize = noTempCells;
4989 for(
MInt cell = 0; cell < listSize; cell++) {
4990 MInt gCellId = tempCells.p[cell];
4991 MInt parentId = c_parentId(gCellId);
4993 if(!skip.p[parentId]) {
4994 tempCells.p[noTempCells] = parentId;
4996 a_levelSetFunctionG(parentId, set) = F0;
4997 MInt noChildren = c_noChildren(parentId);
4998 if(!(noChildren > 0)) {
4999 cerr << parentId << endl;
5000 cerr <<
"gcell: " << gCellId << endl;
5001 mTerm(1, AT_,
"this should not occur: parent g cell with m_noChildIdsG == 0...");
5003 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
5004 if(c_childId(parentId, child) < 0)
continue;
5005 a_levelSetFunctionG(parentId, set) += a_levelSetFunctionG(c_childId(parentId, child), set);
5007 a_levelSetFunctionG(parentId, set) /= (
MFloat)noChildren;
5008 skip.p[parentId] =
true;
5039 MInt endSet = m_noSets;
5040 if(m_buildCollectedLevelSetFunction &&
globalTimeStep > 0) startSet = 1;
5041 if(computingSet >= 0) {
5042 startSet = computingSet;
5043 endSet = computingSet + 1;
5044 ASSERT(m_computeSet[computingSet],
"");
5045 ASSERT(m_changedSet[computingSet],
"");
5047 const MInt noSets = endSet - startSet;
5052 if(computingSet == 0) m_bandCells[computingSet].clear();
5055 for(
MInt set = startSet; set < endSet; set++) {
5056 if(!m_computeSet[set])
continue;
5057 if(computingSet < 0 && m_levelSetMb) m_changedSet[set] =
false;
5060 std::vector<MInt>().swap(m_G0Cells[set]);
5062 if(a_noBandCells(set) == 0) {
5065 a_inBandG(cellId, set) =
false;
5066 a_isGBoundaryCellG(cellId, set) =
false;
5067 a_isGZeroCell(cellId, set) =
false;
5070 if(!c_isLeafCell(cellId))
continue;
5071 if(
approx(a_levelSetFunctionG(cellId, set), F0, MFloatEps) && !a_isHalo(cellId)) {
5072 a_inBandG(cellId, set) =
true;
5073 a_isGBoundaryCellG(cellId, set) =
true;
5074 m_G0Cells[set].push_back(cellId);
5075 a_isGZeroCell(cellId, set) =
true;
5076 if(!a_wasGZeroCell(cellId, set)) m_changedSet[set] =
true;
5079 for(
MInt d = 0; d < m_noDirs; d++) {
5085 if(!a_hasNeighbor(cellId, d)) {
5087 parentId = c_parentId(parentId);
5088 if(parentId == -1)
break;
5089 if(a_hasNeighbor(parentId, d)) {
5090 if(c_noChildren(c_neighborId(parentId, d)) == 0)
break;
5093 if(parentId == -1)
continue;
5094 nghbrId = c_neighborId(parentId, d);
5096 nghbrId = c_neighborId(cellId, d);
5098 if(nghbrId < 0)
continue;
5099 if(!c_isLeafCell(nghbrId))
continue;
5100 if(a_levelSetFunctionG(nghbrId, set) * a_levelSetFunctionG(cellId, set) < F0) {
5101 if(!a_isGZeroCell(cellId, set) && !a_isHalo(cellId)) {
5102 a_inBandG(cellId, set) =
true;
5103 a_isGBoundaryCellG(cellId, set) =
true;
5104 m_G0Cells[set].push_back(cellId);
5105 a_isGZeroCell(cellId, set) =
true;
5106 if(!a_wasGZeroCell(cellId, set)) m_changedSet[set] =
true;
5108 if(parentId != cellId && !a_isGZeroCell(nghbrId, set) && !a_isHalo(nghbrId)) {
5109 a_inBandG(nghbrId, set) =
true;
5110 a_isGBoundaryCellG(nghbrId, set) =
true;
5111 m_G0Cells[set].push_back(nghbrId);
5112 a_isGZeroCell(nghbrId, set) =
true;
5113 if(!a_wasGZeroCell(nghbrId, set)) m_changedSet[set] =
true;
5121 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5123 a_inBandG(cellId, set) =
false;
5124 a_isGBoundaryCellG(cellId, set) =
false;
5125 a_isGZeroCell(cellId, set) =
false;
5126 if(a_isHalo(cellId))
continue;
5127 if(
approx(a_levelSetFunctionG(cellId, set), F0, MFloatEps)) {
5128 a_inBandG(cellId, set) =
true;
5129 a_isGBoundaryCellG(cellId, set) =
true;
5130 m_G0Cells[set].push_back(cellId);
5131 a_isGZeroCell(cellId, set) =
true;
5132 if(!a_wasGZeroCell(cellId, set)) m_changedSet[set] =
true;
5134 for(
MInt d = 0; d < m_noDirs; d++) {
5135 if(!a_hasNeighbor(cellId, d))
continue;
5136 if(!c_isLeafCell(c_neighborId(cellId, d)))
continue;
5137 if((a_levelSetFunctionG(c_neighborId(cellId, d), set) * a_levelSetFunctionG(cellId, set) < F0)) {
5138 a_inBandG(cellId, set) =
true;
5139 a_isGBoundaryCellG(cellId, set) =
true;
5140 m_G0Cells[set].push_back(cellId);
5141 a_isGZeroCell(cellId, set) =
true;
5142 if(!a_wasGZeroCell(cellId, set)) m_changedSet[set] =
true;
5150 a_internalBandLayer(0, set) = 0;
5151 std::vector<MInt>().swap(m_internalBandCells[set]);
5152 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
5153 if(!a_isHalo(a_G0CellId(
id, set))) {
5154 a_internalBandLayer(0, set)++;
5155 m_internalBandCells[set].push_back(a_G0CellId(
id, set));
5163 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5164 for(
MInt j = 0; j < noWindowCells(i); j++) {
5166 for(
MInt set = startSet; set < endSet; set++) {
5167 tmp_data(windowCellId(i, j), dataSet) = a_isGZeroCell(windowCellId(i, j), set);
5172 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5173 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
5175 for(
MInt set = startSet; set < endSet; set++) {
5176 MInt windowId = grid().azimuthalWindowCell(i, j);
5177 tmp_data(windowId, dataSet) = a_isGZeroCell(windowId, set);
5183 exchangeDataLS(&tmp_data(0, 0), noSets);
5185 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5186 for(
MInt j = 0; j < noHaloCells(i); j++) {
5187 const MInt haloCell = haloCellId(i, j);
5189 for(
MInt set = startSet; set < endSet; set++) {
5190 if(!a_isGZeroCell(haloCell, set)) {
5191 a_isGZeroCell(haloCell, set) = tmp_data(haloCellId(i, j), dataSet);
5192 if(a_isGZeroCell(haloCell, set)) {
5193 m_G0Cells[set].push_back(haloCell);
5194 a_inBandG(haloCell, set) =
true;
5195 a_isGBoundaryCellG(haloCell, set) =
true;
5196 if(!a_wasGZeroCell(haloCell, set)) m_changedSet[set] =
true;
5203 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5204 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
5205 const MInt haloCell = grid().azimuthalHaloCell(i, j);
5207 for(
MInt set = startSet; set < endSet; set++) {
5208 if(!a_isGZeroCell(haloCell, set)) {
5209 a_isGZeroCell(haloCell, set) = tmp_data(haloCell, dataSet);
5210 if(a_isGZeroCell(haloCell, set)) {
5211 m_G0Cells[set].push_back(haloCell);
5212 a_inBandG(haloCell, set) =
true;
5213 a_isGBoundaryCellG(haloCell, set) =
true;
5214 if(!a_wasGZeroCell(haloCell, set)) {
5215 m_changedSet[set] =
true;
5225 if(m_buildCollectedLevelSetFunction && m_determineG0CellsMode && computingSet <= 0) {
5229 for(
MInt id = 0;
id < a_noG0Cells(changeSet);
id++) {
5231 a_inBandG(cellId, changeSet) =
false;
5232 a_isGBoundaryCellG(cellId, changeSet) =
false;
5233 a_isGZeroCell(cellId, changeSet) =
false;
5235 std::vector<MInt>().swap(m_G0Cells[changeSet]);
5236 for(
MInt set = startSet; set < endSet; set++) {
5237 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
5239 if(!a_isGZeroCell(cellId, changeSet)) {
5240 a_inBandG(cellId, changeSet) =
true;
5241 a_isGBoundaryCellG(cellId, changeSet) =
true;
5242 m_G0Cells[changeSet].push_back(cellId);
5243 a_isGZeroCell(cellId, changeSet) =
true;
5244 if(!a_wasGZeroCell(cellId, changeSet)) m_changedSet[changeSet] =
true;
5253 for(
MInt set = startSet; set < endSet; set++) {
5255 if(a_wasGZeroCell(cellId, set) && !a_isGZeroCell(cellId, set)) {
5256 m_changedSet[set] =
true;
5262 for(
MInt set = startSet; set < endSet; set++) {
5263 if(m_changedSet[set])
5264 changedSet[set] = 1;
5266 changedSet[set] = -1;
5270 MPI_Allreduce(MPI_IN_PLACE, &changedSet[0], m_noSets, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
5273 for(
MInt set = startSet; set < endSet; set++) {
5274 if(changedSet[set] > 0) {
5275 m_changedSet[set] =
true;
5277 m_changedSet[set] =
false;
5280 m_changedSet[set] =
true;
5281 m_changedSet[0] =
true;
5285 if(computingSet >= 0) ASSERT(m_changedSet[computingSet],
"");
5297 MInt endSet = m_noSets;
5298 if(m_buildCollectedLevelSetFunction &&
globalTimeStep > 0) startSet = 1;
5299 if(computingSet >= 0) {
5300 startSet = computingSet;
5301 endSet = computingSet + 1;
5302 ASSERT(m_computeSet[computingSet],
"");
5303 ASSERT(m_changedSet[computingSet],
"");
5313 for(
MInt set = startSet; set < endSet; set++) {
5314 if(!m_computeSet[set])
continue;
5320 std::vector<MInt>().swap(m_bandBndryCells[set]);
5323 a_bandLayer(0, set) = a_noG0Cells(set);
5324 MInt layerCount = 1;
5327 std::vector<MInt>().swap(m_bandCells[set]);
5328 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
5329 m_bandCells[set].push_back(a_G0CellId(
id, set));
5334 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
5336 a_isGBoundaryCellG(cellId, set) =
false;
5338 for(
MInt dir = 0; dir < m_noDirs; dir++) {
5339 const MInt nghbrId = c_neighborId(cellId, dir);
5340 if(nghbrId == -1)
continue;
5341 if(a_isHalo(nghbrId))
continue;
5342 if(a_inBandG(nghbrId, set))
continue;
5343 lastLayer.p[cnt++] = nghbrId;
5344 a_inBandG(nghbrId, set) =
true;
5345 m_bandCells[set].push_back(nghbrId);
5350 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5351 for(
MInt j = 0; j < noWindowCells(i); j++) {
5352 tmp_data(windowCellId(i, j)) = a_inBandG(windowCellId(i, j), set);
5355 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5356 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
5357 MInt windowId = grid().azimuthalWindowCell(i, j);
5358 tmp_data(windowId) = a_inBandG(windowId, set);
5362 exchangeDataLS(&tmp_data(0), 1);
5364 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5365 for(
MInt j = 0; j < noHaloCells(i); j++) {
5366 const MInt halocell = haloCellId(i, j);
5367 if(!a_inBandG(halocell, set)) {
5368 a_inBandG(halocell, set) = tmp_data(halocell);
5369 if(a_inBandG(halocell, set)) {
5370 m_bandCells[set].push_back(halocell);
5371 lastLayer.p[cnt++] = halocell;
5376 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5377 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
5378 const MInt haloCell = grid().azimuthalHaloCell(i, j);
5379 if(!a_inBandG(haloCell, set)) {
5380 a_inBandG(haloCell, set) = tmp_data(haloCell);
5381 if(a_inBandG(haloCell, set)) {
5382 m_bandCells[set].push_back(haloCell);
5383 lastLayer.p[cnt++] = haloCell;
5389 a_bandLayer(layerCount, set) = a_noBandCells(set);
5393 while(layerCount < m_gBandWidth) {
5395 for(
MInt c = 0; c < cnt; c++) {
5396 a_isGBoundaryCellG(lastLayer.p[c], set) =
false;
5398 for(
MInt dir = 0; dir < m_noDirs; dir++) {
5399 const MInt nghbrId = c_neighborId(lastLayer.p[c], dir);
5400 if(nghbrId == -1)
continue;
5401 if(a_isHalo(nghbrId))
continue;
5402 if(a_inBandG(nghbrId, set))
continue;
5403 temp.p[tempCnt++] = nghbrId;
5404 a_inBandG(nghbrId, set) =
true;
5405 m_bandCells[set].push_back(nghbrId);
5411 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5412 for(
MInt j = 0; j < noWindowCells(i); j++) {
5413 tmp_data(windowCellId(i, j)) = a_inBandG(windowCellId(i, j), set);
5416 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5417 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
5418 MInt windowId = grid().azimuthalWindowCell(i, j);
5419 tmp_data(windowId) = a_inBandG(windowId, set);
5423 exchangeDataLS(&tmp_data(0), 1);
5425 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5426 for(
MInt j = 0; j < noHaloCells(i); j++) {
5427 const MInt halocell = haloCellId(i, j);
5428 if(!a_inBandG(halocell, set)) {
5429 a_inBandG(halocell, set) = tmp_data(halocell);
5430 if(a_inBandG(halocell, set)) {
5431 m_bandCells[set].push_back(halocell);
5432 temp.p[tempCnt++] = halocell;
5437 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5438 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
5439 const MInt haloCell = grid().azimuthalHaloCell(i, j);
5440 if(!a_inBandG(haloCell, set)) {
5441 a_inBandG(haloCell, set) = tmp_data(haloCell);
5442 if(a_inBandG(haloCell, set)) {
5443 m_bandCells[set].push_back(haloCell);
5444 temp.p[tempCnt++] = haloCell;
5451 a_bandLayer(layerCount, set) = a_noBandCells(set);
5453 for(
MInt c = 0; c < tempCnt; c++) {
5454 lastLayer.p[c] = temp.p[c];
5461 for(
MInt c = 0; c < cnt; c++) {
5462 a_isGBoundaryCellG(lastLayer.p[c], set) =
true;
5463 m_bandBndryCells[set].push_back(lastLayer.p[c]);
5468 for(
MInt layer = 1; layer < m_gBandWidth + 1; layer++) {
5469 a_internalBandLayer(layer, set) = a_internalBandLayer(layer - 1, set);
5470 for(
MInt id = a_bandLayer(layer - 1, set);
id < a_bandLayer(layer, set);
id++) {
5471 if(!a_isHalo(a_bandCellId(
id, set))) {
5472 a_internalBandLayer(layer, set)++;
5473 m_internalBandCells[set].push_back(a_bandCellId(
id, set));
5498 for(
MInt set = 0; set < m_noSets; set++) {
5499 if(!m_computeSet[set])
continue;
5500 switch(m_levelSetBoundaryCondition) {
5502 MInt noGBndryCellsBackup = a_noGBndryCells(set);
5505 MInt nghbrXL = -1, nghbrXR = -1, nghbrXL2 = -1, nghbrXR2 = -1, parent,
cellId;
5506 MInt nghbrYL = -1, nghbrYR = -1, nghbrYL2 = -1, nghbrYR2 = -1;
5509 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5510 a_isBndryCellG(a_bandCellId(
id, set)) =
false;
5513 std::vector<MInt>().swap(m_gBndryCells[set]);
5515 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5516 cellId = a_bandCellId(
id, set);
5517 if(a_isHalo(cellId))
continue;
5519 nghbrXL = c_neighborId(cellId, 0);
5520 nghbrXL2 = c_neighborId(nghbrXL, 0);
5521 nghbrXR = c_neighborId(cellId, 1);
5522 nghbrXR2 = c_neighborId(nghbrXR, 1);
5524 nghbrYL = c_neighborId(cellId, 2);
5525 nghbrYL2 = c_neighborId(nghbrYL, 2);
5526 nghbrYR = c_neighborId(cellId, 3);
5527 nghbrYR2 = c_neighborId(nghbrYR, 3);
5529 for(
MInt i = 0; i < nDim; i++) {
5530 parent = c_parentId(cellId);
5532 if(a_hasNeighbor(cellId, 2 + i) == 0) {
5533 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5534 m_gBndryCells[set].push_back(cellId);
5535 a_isGBoundaryCellG(cellId, set) =
true;
5536 a_isBndryCellG(cellId) =
true;
5540 if(a_hasNeighbor(nghbrXL, 2 + i) == 0) {
5541 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5542 m_gBndryCells[set].push_back(cellId);
5543 a_isGBoundaryCellG(cellId, set) =
true;
5544 a_isBndryCellG(cellId) =
true;
5546 if(!a_isHalo(nghbrXL))
5547 if(a_inBandG(nghbrXL, set) && a_level(nghbrXL) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXL)) {
5548 m_gBndryCells[set].push_back(nghbrXL);
5549 a_isGBoundaryCellG(nghbrXL, set) =
true;
5550 a_isBndryCellG(nghbrXL) =
true;
5554 if(a_hasNeighbor(nghbrXL2, 2 + i) == 0) {
5555 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5556 m_gBndryCells[set].push_back(cellId);
5557 a_isGBoundaryCellG(cellId, set) =
true;
5558 a_isBndryCellG(cellId) =
true;
5560 if(!a_isHalo(nghbrXL2))
5561 if(a_inBandG(nghbrXL2, set) && a_level(nghbrXL2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXL2)) {
5562 m_gBndryCells[set].push_back(nghbrXL2);
5563 a_isGBoundaryCellG(nghbrXL2, set) =
true;
5564 a_isBndryCellG(nghbrXL2) =
true;
5568 if(a_hasNeighbor(nghbrXR, 2 + i) == 0) {
5569 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5570 m_gBndryCells[set].push_back(cellId);
5571 a_isGBoundaryCellG(cellId, set) =
true;
5572 a_isBndryCellG(cellId) =
true;
5574 if(!a_isHalo(nghbrXR))
5575 if(a_inBandG(nghbrXR, set) && a_level(nghbrXR) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXR)) {
5576 m_gBndryCells[set].push_back(nghbrXR);
5577 a_isGBoundaryCellG(nghbrXR, set) =
true;
5578 a_isBndryCellG(nghbrXR) =
true;
5582 if(a_hasNeighbor(nghbrXR2, 2 + i) == 0) {
5583 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5584 m_gBndryCells[set].push_back(cellId);
5585 a_isGBoundaryCellG(cellId, set) =
true;
5586 a_isBndryCellG(cellId) =
true;
5588 if(!a_isHalo(nghbrXR2))
5589 if(a_inBandG(nghbrXR2, set) && a_level(nghbrXR2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXR2)) {
5590 m_gBndryCells[set].push_back(nghbrXR2);
5591 a_isGBoundaryCellG(nghbrXR2, set) =
true;
5592 a_isBndryCellG(nghbrXR2) =
true;
5596 if(a_hasNeighbor(nghbrYL, i) == 0) {
5597 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5598 m_gBndryCells[set].push_back(cellId);
5599 a_isGBoundaryCellG(cellId, set) =
true;
5600 a_isBndryCellG(cellId) =
true;
5602 if(!a_isHalo(nghbrYL))
5603 if(a_inBandG(nghbrYL, set) && a_level(nghbrYL) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYL)) {
5604 m_gBndryCells[set].push_back(nghbrYL);
5605 a_isGBoundaryCellG(nghbrYL, set) =
true;
5606 a_isBndryCellG(nghbrYL) =
true;
5610 if(a_hasNeighbor(nghbrYL2, i) == 0) {
5611 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5612 m_gBndryCells[set].push_back(cellId);
5613 a_isGBoundaryCellG(cellId, set) =
true;
5614 a_isBndryCellG(cellId) =
true;
5616 if(!a_isHalo(nghbrYL2))
5617 if(a_inBandG(nghbrYL2, set) && a_level(nghbrYL2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYL2)) {
5618 m_gBndryCells[set].push_back(nghbrYL2);
5619 a_isGBoundaryCellG(nghbrYL2, set) =
true;
5620 a_isBndryCellG(nghbrYL2) =
true;
5624 if(a_hasNeighbor(nghbrYR, i) == 0) {
5625 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5626 m_gBndryCells[set].push_back(cellId);
5627 a_isGBoundaryCellG(cellId, set) =
true;
5628 a_isBndryCellG(cellId) =
true;
5630 if(!a_isHalo(nghbrYR))
5631 if(a_inBandG(nghbrYR, set) && a_level(nghbrYR) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYR)) {
5632 m_gBndryCells[set].push_back(nghbrYR);
5633 a_isGBoundaryCellG(nghbrYR, set) =
true;
5634 a_isBndryCellG(nghbrYR) =
true;
5638 if(a_hasNeighbor(nghbrYR2, i) == 0) {
5639 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5640 m_gBndryCells[set].push_back(cellId);
5641 a_isGBoundaryCellG(cellId, set) =
true;
5642 a_isBndryCellG(cellId) =
true;
5644 if(!a_isHalo(nghbrYR2))
5645 if(a_inBandG(nghbrYR2, set) && a_level(nghbrYR2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYR2)) {
5646 m_gBndryCells[set].push_back(nghbrYR2);
5647 a_isGBoundaryCellG(nghbrYR2, set) =
true;
5648 a_isBndryCellG(nghbrYR2) =
true;
5653 if(a_hasNeighbor(parent, 2 * i) == 0) {
5654 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
5655 if(c_childId(parent, ch) < 0)
continue;
5656 if(a_isHalo(c_childId(parent, ch)))
continue;
5657 if(a_isBndryCellG(c_childId(parent, ch)))
continue;
5658 if(!a_inBandG(c_childId(parent, ch), set))
continue;
5659 if(a_level(c_childId(parent, ch)) != a_maxGCellLevel())
continue;
5660 m_gBndryCells[set].push_back(c_childId(parent, ch));
5661 a_isGBoundaryCellG(c_childId(parent, ch), set) =
true;
5662 a_isBndryCellG(c_childId(parent, ch)) =
true;
5668 if(a_hasNeighbor(parent, 2 * i + 1) == 0) {
5669 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
5670 if(c_childId(parent, ch) < 0)
continue;
5671 if(a_isHalo(c_childId(parent, ch)))
continue;
5672 if(a_isBndryCellG(c_childId(parent, ch)))
continue;
5673 if(!a_inBandG(c_childId(parent, ch), set))
continue;
5674 if(a_level(c_childId(parent, ch)) != a_maxGCellLevel())
continue;
5675 m_gBndryCells[set].push_back(c_childId(parent, ch));
5676 a_isGBoundaryCellG(c_childId(parent, ch), set) =
true;
5677 a_isBndryCellG(c_childId(parent, ch)) =
true;
5683 MIntScratchSpace sendBufferSize(grid().noNeighborDomains(), AT_,
"sendBufferSize");
5684 MIntScratchSpace receiveBufferSize(grid().noNeighborDomains(), AT_,
"receiveBufferSize");
5686 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5687 sendBufferSize.p[i] = 0;
5688 for(
MInt j = 0; j < noWindowCells(i); j++) {
5689 m_intSendBuffers[i][sendBufferSize.p[i]++] = a_isBndryCellG(windowCellId(i, j));
5692 if(grid().azimuthalPeriodicity()) {
5693 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5694 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
5695 m_intSendBuffers[i][sendBufferSize.p[i]++] = a_isBndryCellG(grid().azimuthalWindowCell(i, j));
5701 exchangeIntBuffers(sendBufferSize.getPointer(), receiveBufferSize.getPointer(), 9, 1);
5706 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5710 if(receiveBufferSize.p[i] != noHaloCells(i))
5711 mTerm(1, AT_,
"this was not expected to happen: wrong number of window information...");
5713 for(
MInt j = 0; j < noHaloCells(i); j++) {
5714 MInt haloCell = haloCellId(i, j);
5716 if(m_intReceiveBuffers[i][j]) {
5717 a_isBndryCellG(haloCell) = m_intReceiveBuffers[i][j];
5718 a_isGBoundaryCellG(haloCell, set) = m_intReceiveBuffers[i][j];
5719 if(a_isBndryCellG(haloCell)) {
5720 m_gBndryCells[set].push_back(haloCell);
5725 if(grid().azimuthalPeriodicity()) {
5726 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5727 MInt offset = noHaloCells(grid().azimuthalNeighborDomain(i));
5728 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
5729 MInt n = offset + j;
5730 MInt haloCell = grid().azimuthalHaloCell(i, j);
5731 if(m_intReceiveBuffers[i][n]) {
5732 a_isBndryCellG(haloCell) = m_intReceiveBuffers[i][n];
5733 a_isGBoundaryCellG(haloCell, set) = m_intReceiveBuffers[i][n];
5734 if(a_isBndryCellG(haloCell)) {
5735 m_gBndryCells[set].push_back(haloCell);
5741 if(noGBndryCellsBackup != a_noGBndryCells(set) ||
globalTimeStep == 0) {
5742 m_log <<
"Number of level set boundary cells changed: " << endl;
5743 m_log << a_noGBndryCells(set) <<
" G boundary cells created..." << endl;
5748 MInt noGBndryCellsBackup = a_noGBndryCells(set);
5749 MFloat deltaX = m_flameRadiusOffset;
5752 std::vector<MInt>().swap(m_gBndryCells[set]);
5753 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5754 if(c_coordinate(a_bandCellId(
id, set), 1) < F0 || c_coordinate(a_bandCellId(
id, set), 1) > m_gCellDistance)
5756 m_gBndryCells[set].push_back(a_bandCellId(
id, set));
5761 MInt nghbrXL = -1, nghbrXR = -1, nghbrXL2 = -1, nghbrXR2 = -1, parent,
cellId;
5762 MInt nghbrYL = -1, nghbrYR = -1, nghbrYL2 = -1, nghbrYR2 = -1;
5765 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5766 a_isBndryCellG(a_bandCellId(
id, set)) =
false;
5769 std::vector<MInt>().swap(m_gBndryCells[set]);
5771 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
5772 cellId = a_bandCellId(
id, set);
5773 if(a_isHalo(cellId))
continue;
5775 nghbrXL = c_neighborId(cellId, 0);
5776 nghbrXL2 = c_neighborId(nghbrXL, 0);
5777 nghbrXR = c_neighborId(cellId, 1);
5778 nghbrXR2 = c_neighborId(nghbrXR, 1);
5780 nghbrYL = c_neighborId(cellId, 2);
5781 nghbrYL2 = c_neighborId(nghbrYL, 2);
5782 nghbrYR = c_neighborId(cellId, 3);
5783 nghbrYR2 = c_neighborId(nghbrYR, 3);
5785 if(c_coordinate(cellId, 1) < (m_yOffsetFlameTube - 0.1))
continue;
5787 if(c_coordinate(cellId, 1) > (m_yOffsetFlameTube + 0.1))
continue;
5789 if(
ABS(c_coordinate(cellId, 0)) > (m_radiusFlameTube + deltaX + 0.1))
continue;
5791 for(
MInt i = 0; i < nDim; i++) {
5792 parent = c_parentId(cellId);
5794 if(a_hasNeighbor(cellId, 2 + i) == 0) {
5795 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5796 m_gBndryCells[set].push_back(cellId);
5797 a_isGBoundaryCellG(cellId, set) =
true;
5798 a_isBndryCellG(cellId) =
true;
5802 if(a_hasNeighbor(nghbrXL, 2 + i) == 0) {
5803 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5805 m_gBndryCells[set].push_back(cellId);
5806 a_isGBoundaryCellG(cellId, set) =
true;
5807 a_isBndryCellG(cellId) =
true;
5809 if(!a_isHalo(nghbrXL))
5810 if(a_inBandG(nghbrXL, set) && a_level(nghbrXL) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXL)) {
5812 m_gBndryCells[set].push_back(nghbrXL);
5813 a_isGBoundaryCellG(nghbrXL, set) =
true;
5814 a_isBndryCellG(nghbrXL) =
true;
5818 if(a_hasNeighbor(nghbrXL2, 2 + i) == 0) {
5819 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5821 m_gBndryCells[set].push_back(cellId);
5822 a_isGBoundaryCellG(cellId, set) =
true;
5823 a_isBndryCellG(cellId) =
true;
5825 if(!a_isHalo(nghbrXL2))
5826 if(a_inBandG(nghbrXL2, set) && a_level(nghbrXL2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXL2)) {
5828 m_gBndryCells[set].push_back(nghbrXL2);
5829 a_isGBoundaryCellG(nghbrXL2, set) =
true;
5830 a_isBndryCellG(nghbrXL2) =
true;
5834 if(a_hasNeighbor(nghbrXR, 2 + i) == 0) {
5835 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5837 m_gBndryCells[set].push_back(cellId);
5838 a_isGBoundaryCellG(cellId, set) =
true;
5839 a_isBndryCellG(cellId) =
true;
5841 if(!a_isHalo(nghbrXR))
5842 if(a_inBandG(nghbrXR, set) && a_level(nghbrXR) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXR)) {
5844 m_gBndryCells[set].push_back(nghbrXR);
5845 a_isGBoundaryCellG(nghbrXR, set) =
true;
5846 a_isBndryCellG(nghbrXR) =
true;
5850 if(a_hasNeighbor(nghbrXR2, 2 + i) == 0) {
5851 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5853 m_gBndryCells[set].push_back(cellId);
5854 a_isGBoundaryCellG(cellId, set) =
true;
5855 a_isBndryCellG(cellId) =
true;
5857 if(!a_isHalo(nghbrXR2))
5858 if(a_inBandG(nghbrXR2, set) && a_level(nghbrXR2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrXR2)) {
5860 m_gBndryCells[set].push_back(nghbrXR2);
5861 a_isGBoundaryCellG(nghbrXR2, set) =
true;
5862 a_isBndryCellG(nghbrXR2) =
true;
5866 if(a_hasNeighbor(nghbrYL, i) == 0) {
5867 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5869 m_gBndryCells[set].push_back(cellId);
5870 a_isGBoundaryCellG(cellId, set) =
true;
5871 a_isBndryCellG(cellId) =
true;
5873 if(!a_isHalo(nghbrYL))
5874 if(a_inBandG(nghbrYL, set) && a_level(nghbrYL) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYL)) {
5876 m_gBndryCells[set].push_back(nghbrYL);
5877 a_isGBoundaryCellG(nghbrYL, set) =
true;
5878 a_isBndryCellG(nghbrYL) =
true;
5882 if(a_hasNeighbor(nghbrYL2, i) == 0) {
5883 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5885 m_gBndryCells[set].push_back(cellId);
5886 a_isGBoundaryCellG(cellId, set) =
true;
5887 a_isBndryCellG(cellId) =
true;
5889 if(!a_isHalo(nghbrYL2))
5890 if(a_inBandG(nghbrYL2, set) && a_level(nghbrYL2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYL2)) {
5892 m_gBndryCells[set].push_back(nghbrYL2);
5893 a_isGBoundaryCellG(nghbrYL2, set) =
true;
5894 a_isBndryCellG(nghbrYL2) =
true;
5898 if(a_hasNeighbor(nghbrYR, i) == 0) {
5899 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5901 m_gBndryCells[set].push_back(cellId);
5902 a_isGBoundaryCellG(cellId, set) =
true;
5903 a_isBndryCellG(cellId) =
true;
5905 if(!a_isHalo(nghbrYR))
5906 if(a_inBandG(nghbrYR, set) && a_level(nghbrYR) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYR)) {
5908 m_gBndryCells[set].push_back(nghbrYR);
5909 a_isGBoundaryCellG(nghbrYR, set) =
true;
5910 a_isBndryCellG(nghbrYR) =
true;
5914 if(a_hasNeighbor(nghbrYR2, i) == 0) {
5915 if(a_level(cellId) == a_maxGCellLevel() && !a_isBndryCellG(cellId)) {
5917 m_gBndryCells[set].push_back(cellId);
5918 a_isGBoundaryCellG(cellId, set) =
true;
5919 a_isBndryCellG(cellId) =
true;
5921 if(!a_isHalo(nghbrYR2))
5922 if(a_inBandG(nghbrYR2, set) && a_level(nghbrYR2) == a_maxGCellLevel() && !a_isBndryCellG(nghbrYR2)) {
5924 m_gBndryCells[set].push_back(nghbrYR2);
5925 a_isGBoundaryCellG(nghbrYR2, set) =
true;
5926 a_isBndryCellG(nghbrYR2) =
true;
5931 if(a_hasNeighbor(parent, 2 * i) == 0) {
5932 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
5933 if(c_childId(parent, ch) < 0)
continue;
5934 if(a_isHalo(c_childId(parent, ch)))
continue;
5935 if(a_isBndryCellG(c_childId(parent, ch)))
continue;
5936 if(!a_inBandG(c_childId(parent, ch), set))
continue;
5937 if(a_level(c_childId(parent, ch)) != a_maxGCellLevel())
continue;
5938 m_gBndryCells[set].push_back(c_childId(parent, ch));
5939 a_isGBoundaryCellG(c_childId(parent, ch), set) =
true;
5940 a_isBndryCellG(c_childId(parent, ch)) =
true;
5949 if(a_hasNeighbor(parent, 2 * i + 1) == 0) {
5950 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
5951 if(c_childId(parent, ch) < 0)
continue;
5952 if(a_isHalo(c_childId(parent, ch)))
continue;
5953 if(a_isBndryCellG(c_childId(parent, ch)))
continue;
5954 if(!a_inBandG(c_childId(parent, ch), set))
continue;
5955 if(a_level(c_childId(parent, ch)) != a_maxGCellLevel())
continue;
5956 m_gBndryCells[set].push_back(c_childId(parent, ch));
5957 a_isGBoundaryCellG(c_childId(parent, ch), set) =
true;
5958 a_isBndryCellG(c_childId(parent, ch)) =
true;
5969 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5970 for(
MInt j = 0; j < noWindowCells(i); j++) {
5971 tmp_data(windowCellId(i, j)) = a_isBndryCellG(windowCellId(i, j));
5975 exchangeDataLS(&tmp_data(0), 1);
5977 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
5978 for(
MInt j = 0; j < noHaloCells(i); j++) {
5979 const MInt haloCell = haloCellId(i, j);
5981 if(tmp_data(haloCell)) {
5983 a_isBndryCellG(haloCell) = tmp_data(haloCell);
5984 a_isGBoundaryCellG(haloCell, set) = tmp_data(haloCell);
5985 if(a_isBndryCellG(haloCell)) {
5986 m_gBndryCells[set].push_back(haloCell);
5992 if(noGBndryCellsBackup != a_noGBndryCells(set) ||
globalTimeStep == 0) {
5993 m_log <<
"Number of level set boundary cells changed: " << endl;
5994 m_log << a_noGBndryCells(set) <<
" G boundary cells created..." << endl;
6000 MInt noGBndryCellsBackup = a_noGBndryCells(set);
6001 MFloat deltaX = m_flameRadiusOffset;
6002 MInt nghbrId, nghbrIdT;
6006 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6007 a_isBndryCellG(a_bandCellId(
id, set)) =
false;
6010 std::vector<MInt>().swap(m_gBndryCells[set]);
6012 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6015 if(a_isHalo(cellId))
continue;
6017 if(a_level(cellId) != a_maxGCellLevel())
continue;
6020 IF_CONSTEXPR(nDim == 3) {
6021 if(c_coordinate(cellId, 1) < (m_yOffsetFlameTube - 0.05))
continue;
6023 if(c_coordinate(cellId, 1) > (m_yOffsetFlameTube + 0.1))
continue;
6025 if(
ABS(c_coordinate(cellId, 0)) > (m_jetHalfWidth + 0.3))
continue;
6027 if(
ABS(c_coordinate(cellId, 0)) < (m_jetHalfWidth - 0.1)
6028 &&
ABS(c_coordinate(cellId, 2)) < (m_jetHalfLength - 0.10))
6031 if(
ABS(c_coordinate(cellId, 2)) > (m_jetHalfLength + 0.3))
continue;
6034 if(c_coordinate(cellId, 1) < (m_yOffsetFlameTube - 0.1))
continue;
6036 if(c_coordinate(cellId, 1) > (m_yOffsetFlameTube + 0.1))
continue;
6038 if(
ABS(c_coordinate(cellId, 0)) > (m_radiusFlameTube + deltaX + 0.1))
continue;
6040 for(
MInt dirId = 0; dirId < nDim * 2; dirId++) {
6041 if(a_hasNeighbor(cellId, dirId) == 0 && a_level(cellId) == a_maxGCellLevel()) {
6042 a_isGBoundaryCellG(cellId, set) =
true;
6043 a_isBndryCellG(cellId) =
true;
6044 m_gBndryCells[set].push_back(cellId);
6046 for(
MInt dirIdS = 0; dirIdS < nDim * 2; dirIdS++) {
6047 if(dirId == dirIdS)
continue;
6051 MInt noNghbrIds = a_hasNeighbor(nghbrId, dirIdS);
6052 if(noNghbrIds == 0)
break;
6054 nghbrId = c_neighborId(nghbrId, dirIdS);
6055 if(nghbrId == -1)
break;
6057 if(a_isHalo(nghbrId))
break;
6058 if(!a_inBandG(nghbrId, set))
break;
6059 if(a_level(nghbrId) != a_maxGCellLevel())
break;
6060 if(!a_isBndryCellG(nghbrId)) {
6061 a_isGBoundaryCellG(nghbrId, set) =
true;
6062 a_isBndryCellG(nghbrId) =
true;
6063 m_gBndryCells[set].push_back(nghbrId);
6065 for(
MInt dirIdT = 0; dirIdT < nDim * 2; dirIdT++) {
6066 MInt noNghbrIdsT = a_hasNeighbor(nghbrId, dirIdT);
6067 if(noNghbrIdsT == 0)
continue;
6069 nghbrIdT = c_neighborId(nghbrId, dirIdT);
6070 if(nghbrIdT == -1)
continue;
6072 if(a_isHalo(nghbrIdT))
continue;
6074 if(!a_inBandG(nghbrIdT, set))
continue;
6075 if(!a_isBndryCellG(nghbrIdT)) {
6076 a_isGBoundaryCellG(nghbrIdT, set) =
true;
6077 a_isBndryCellG(nghbrIdT) =
true;
6078 m_gBndryCells[set].push_back(nghbrIdT);
6083 if(noDomains() > 1 && cnt == m_noHaloLayers + 1) {
6084 stringstream errorMessage;
6085 errorMessage <<
"cnt is equal to " << cnt <<
" exiting ....";
6086 mTerm(1, AT_, errorMessage.str());
6096 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
6097 for(
MInt j = 0; j < noWindowCells(i); j++) {
6098 tmp_data(windowCellId(i, j)) = a_isBndryCellG(windowCellId(i, j));
6102 exchangeDataLS(&tmp_data(0), 1);
6104 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
6105 for(
MInt j = 0; j < noHaloCells(i); j++) {
6106 const MInt haloCell = haloCellId(i, j);
6107 if(tmp_data(haloCell)) {
6108 a_isBndryCellG(haloCell) = tmp_data(haloCell);
6109 a_isGBoundaryCellG(haloCell, set) = tmp_data(haloCell);
6110 if(a_isBndryCellG(haloCell)) {
6111 m_gBndryCells[set].push_back(haloCell);
6116 if(noGBndryCellsBackup != a_noGBndryCells(set) ||
globalTimeStep == 0) {
6117 m_log <<
"Number of level set boundary cells changed: " << endl;
6118 m_log << a_noGBndryCells(set) <<
" G boundary cells created..." << endl;
6125 MInt noGBndryCellsBackup = a_noGBndryCells(set);
6127 MInt nghbrId, nghbrIdT;
6131 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6132 a_isBndryCellG(a_bandCellId(
id, set)) =
false;
6134 std::vector<MInt>().swap(m_gBndryCells[set]);
6135 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6138 radius = sqrt(
POW2(c_coordinate(cellId, 0)) +
POW2(c_coordinate(cellId, 2)));
6141 if(a_isHalo(cellId))
continue;
6142 if(a_level(cellId) != a_maxGCellLevel())
continue;
6143 IF_CONSTEXPR(nDim == 3) {
6144 if(c_coordinate(cellId, 1) < (m_yOffsetFlameTube - 0.05))
continue;
6145 if(c_coordinate(cellId, 1) > (m_yOffsetFlameTube + 0.1))
continue;
6146 if(radius > (0.55))
continue;
6147 if(radius < 0.48)
continue;
6157 for(
MInt dirId = 0; dirId < nDim * 2; dirId++) {
6158 if(a_hasNeighbor(cellId, dirId) == 0 && a_level(cellId) == a_maxGCellLevel()) {
6159 if(!a_isBndryCellG(cellId)) {
6160 a_isGBoundaryCellG(cellId, set) =
true;
6161 a_isBndryCellG(cellId) =
true;
6162 m_gBndryCells[set].push_back(cellId);
6166 for(
MInt dirIdS = 0; dirIdS < nDim * 2; dirIdS++) {
6167 if(dirId == dirIdS)
continue;
6175 MInt noNghbrIds = a_hasNeighbor(nghbrId, dirIdS);
6181 nghbrId = c_neighborId(nghbrId, dirIdS);
6186 if(a_isHalo(nghbrId))
break;
6187 if(!a_inBandG(nghbrId, set))
break;
6188 if(a_level(nghbrId) != a_maxGCellLevel())
break;
6189 if(!a_isBndryCellG(nghbrId)) {
6190 a_isGBoundaryCellG(nghbrId, set) =
true;
6191 a_isBndryCellG(nghbrId) =
true;
6192 m_gBndryCells[set].push_back(nghbrId);
6195 for(
MInt dirIdT = 0; dirIdT < nDim * 2; dirIdT++) {
6201 MInt noNghbrIdsT = a_hasNeighbor(nghbrId, dirIdT);
6202 if(noNghbrIdsT == 0)
6207 nghbrIdT = c_neighborId(nghbrId, dirIdT);
6210 if(a_isHalo(nghbrIdT))
continue;
6212 if(!a_inBandG(nghbrIdT, set))
continue;
6213 if(!a_isBndryCellG(nghbrIdT)) {
6214 a_isGBoundaryCellG(nghbrIdT, set) =
true;
6215 a_isBndryCellG(nghbrIdT) =
true;
6216 m_gBndryCells[set].push_back(nghbrIdT);
6221 if(noDomains() > 1 && cnt == m_noHaloLayers + 1) {
6222 stringstream errorMessage;
6223 errorMessage <<
"cnt is equal to " << cnt <<
" exiting ....";
6224 mTerm(1, AT_, errorMessage.str());
6235 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
6236 for(
MInt j = 0; j < noWindowCells(i); j++) {
6237 tmp_data(windowCellId(i, j)) = a_isBndryCellG(windowCellId(i, j));
6241 exchangeDataLS(&tmp_data(0), 1);
6243 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
6244 for(
MInt j = 0; j < noHaloCells(i); j++) {
6245 const MInt haloCell = haloCellId(i, j);
6246 if(tmp_data(haloCell)) {
6248 a_isBndryCellG(haloCell) = tmp_data(haloCell);
6249 a_isGBoundaryCellG(haloCell, set) = tmp_data(haloCell);
6250 if(a_isBndryCellG(haloCell)) {
6251 m_gBndryCells[set].push_back(haloCell);
6256 if(noGBndryCellsBackup != a_noGBndryCells(set) ||
globalTimeStep == 0) {
6257 m_log <<
"Number of level set boundary cells changed: " << endl;
6258 m_log << a_noGBndryCells(set) <<
" G boundary cells created...xy" << endl;
6284 if(m_levelSetRans)
return;
6285 if(m_virtualSurgery)
return;
6288 MInt endSet = m_noSets;
6289 if(m_buildCollectedLevelSetFunction &&
globalTimeStep > 0) startSet = 1;
6290 if(computingSet >= 0) {
6291 startSet = computingSet;
6292 endSet = computingSet + 1;
6293 ASSERT(m_computeSet[computingSet],
"");
6294 m_changedSet[computingSet] =
true;
6295 ASSERT(m_changedSet[computingSet],
"");
6301 for(
MInt set = startSet; set < endSet; set++) {
6302 if(!m_computeSet[set])
continue;
6303 if(!m_changedSet[set] && m_levelSetMb && a_maxGCellLevel(set) == maxRefinementLevel())
continue;
6305 for(
MInt cell = 0; cell < a_noCells(); cell++) {
6306 if(a_inBandG(cell, set))
continue;
6307 if(a_level(cell) > a_maxGCellLevel(0))
continue;
6309 if(c_noChildren(cell) > 0 && m_levelSetMb) {
6310 if(a_levelSetFunctionG(cell, set) > m_outsideGValue) {
6311 a_levelSetFunctionG(cell, set) = m_outsideGValue;
6312 }
else if(a_levelSetFunctionG(cell, set) < -m_outsideGValue) {
6313 a_levelSetFunctionG(cell, set) = -m_outsideGValue;
6317 if(a_levelSetFunctionG(cell, set) > F0) {
6318 a_levelSetFunctionG(cell, set) = m_outsideGValue;
6320 a_levelSetFunctionG(cell, set) = -m_outsideGValue;
6323 if(!m_semiLagrange) {
6324 a_correctedBurningVelocity(cell, set) = F0;
6325 for(
MInt i = 0; i < nDim; i++) {
6326 a_extensionVelocityG(cell, i, set) = F0;
6327 a_normalVectorG(cell, i, set) = F0;
6329 a_curvatureG(cell, set) = F0;
6341 for(
MInt set = 0; set < m_noSets; set++) {
6342 for(
MInt cell = 0; cell < noInternalCells(); cell++) {
6343 if(a_oldLevelSetFunctionG(cell, set) > m_outsideGValue) {
6344 a_oldLevelSetFunctionG(cell, set) = m_outsideGValue;
6345 }
else if(a_oldLevelSetFunctionG(cell, set) < -m_outsideGValue) {
6346 a_oldLevelSetFunctionG(cell, set) = -m_outsideGValue;
6367 ASSERT(m_lsCollectorMode == 0 || m_lsCollectorMode == 2 || m_lsCollectorMode == 3,
"");
6370 IF_CONSTEXPR(nDim == 2) {
6371 MInt cellId, nghbrL, nghbrL2, nghbrR, nghbrR2;
6373 MBool oneSidedR =
false;
6374 MBool oneSidedL =
false;
6375 MFloat FgCellDistanceL2R2 = m_FgCellDistance * F1B4, FgCellDistanceLR = m_FgCellDistance * F1B2;
6376 MFloat levelSetNegative = F0, levelSetPlus = F0;
6377 MFloat filterCoord = m_filterFlameTubeEdgesDistance + 0.0234;
6378 MFloat cR = -9999.9, cL = -9999.9;
6379 MBool filter =
false;
6382 MInt endSet = m_noSets;
6383 if(computingSet >= 0) {
6384 startSet = computingSet;
6385 endSet = computingSet + 1;
6389#ifdef standardStencil
6391 for(
MInt set = startSet; set < endSet; set++) {
6392 if(!m_computeSet[set])
continue;
6393 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6394 cellId = a_bandCellId(
id, set);
6396 if(a_isHalo(cellId))
continue;
6399 for(
MInt i = 0; i < nDim; i++) {
6401 (a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i + 1], set)
6402 + a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i], set) - F2 * a_levelSetFunctionG(cellId, set))
6409 mixedDerivative = 0.01;
6410 mTerm(1, AT_,
"ERROR: check code.. this part is assumed to not be used ");
6414 for(
MInt i = 0; i < nDim; i++) {
6415 denominator +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
6417 denominator = F1 /
POW2(denominator);
6418 denominator = sqrt(denominator * denominator * denominator);
6420 a_curvatureG(cellId, set) = -denominator
6421 * (grad2G[0] *
POW2(a_levelSetFunctionSlope(cellId, 1, set))
6422 + grad2G[1] *
POW2(a_levelSetFunctionSlope(cellId, 0, set))
6423 - F2 * a_levelSetFunctionSlope(cellId, 0, set)
6424 * a_levelSetFunctionSlope(cellId, 1, set) * mixedDerivative);
6429 if(m_fourthOrderNormalCurvatureComputation) {
6430 for(
MInt set = startSet; set < endSet; set++) {
6431 if(!m_computeSet[set])
continue;
6432 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6433 cellId = a_bandCellId(
id, set);
6436 a_curvatureG(cellId, set) = F0;
6437 if(a_isHalo(cellId))
continue;
6439 for(
MInt i = 0; i < nDim; i++) {
6444 FgCellDistanceL2R2 = m_FgCellDistance * F1B4;
6445 FgCellDistanceLR = m_FgCellDistance * F1B2;
6447 nghbrL = c_neighborId(cellId, 2 * i);
6448 nghbrL2 = c_neighborId(nghbrL, 2 * i);
6450 nghbrR = c_neighborId(cellId, 2 * i + 1);
6451 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
6454 if(!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR2, set)) {
6457 FgCellDistanceL2R2 = FgCellDistanceLR;
6461 if(a_hasNeighbor(nghbrL, 2 * i) == 0 || a_hasNeighbor(nghbrR, 2 * i + 1) == 0) {
6465 FgCellDistanceL2R2 = FgCellDistanceLR;
6470 if(a_hasNeighbor(cellId, 2 * i + 1) == 0 || a_hasNeighbor(nghbrR, 2 * i + 1) == 0
6471 || a_hasNeighbor(nghbrR2, 2 * i + 1) == 0) {
6474 a_curvatureG(cellId, set) = F0;
6485 if(a_hasNeighbor(cellId, 2 * i) == 0 || a_hasNeighbor(nghbrL, 2 * i) == 0
6486 || a_hasNeighbor(nghbrL2, 2 * i) == 0) {
6489 a_curvatureG(cellId, set) = F0;
6500 if(!oneSidedR && !oneSidedL && m_filterFlameTubeEdges) {
6501 if(c_coordinate(cellId, 1) < filterCoord) {
6504 cR = (a_normalVectorG(nghbrR, i, set) - a_normalVectorG(cellId, i, set)) * m_FgCellDistance;
6506 cL = (a_normalVectorG(cellId, i, set) - a_normalVectorG(nghbrL, i, set)) * m_FgCellDistance;
6509 a_curvatureG(cellId, 0) += (F1B2 * (cR + cL));
6515 if(!oneSidedR && !oneSidedL) {
6516 a_curvatureG(cellId, set) +=
6518 F4B3 * FgCellDistanceLR *
6520 (a_normalVectorG(nghbrR, i, set) - a_normalVectorG(nghbrL, i, set))
6522 - F1B3 * FgCellDistanceL2R2 *
6524 (a_normalVectorG(nghbrR2, i, set) - a_normalVectorG(nghbrL2, i, set));
6528 if(m_curvatureDamp) {
6529 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6530 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6532 a_curvatureG(cellId, set) = F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0))
6533 * a_curvatureG(cellId, set);
6538 for(
MInt set = startSet; set < endSet; set++) {
6539 if(!m_computeSet[set])
continue;
6540 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6541 cellId = a_bandCellId(
id, set);
6543 a_curvatureG(cellId, set) = F0;
6544 if(a_isHalo(cellId))
continue;
6546 if(!a_isGBoundaryCellG(cellId, set)) {
6548 a_curvatureG(cellId, set) = F1B2 * m_FgCellDistance
6549 * (a_normalVectorG(a_bandNghbrIdsG(cellId, 1, set), 0, set)
6550 - a_normalVectorG(a_bandNghbrIdsG(cellId, 0, set), 0, set)
6551 + a_normalVectorG(a_bandNghbrIdsG(cellId, 3, set), 1, set)
6552 - a_normalVectorG(a_bandNghbrIdsG(cellId, 2, set), 1, set));
6554 if(m_curvatureDamp) {
6555 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6556 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6558 a_curvatureG(cellId, set) = F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0))
6559 * a_curvatureG(cellId, set);
6568exchangeDataLS(&a_curvatureG(0, 0), m_maxNoSets);
6573 MInt endSet = m_noSets;
6574 if(computingSet >= 0) {
6575 startSet = computingSet;
6576 endSet = computingSet + 1;
6579 for(
MInt set = startSet; set < endSet; set++) {
6580 if(!m_computeSet[set])
continue;
6581 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6582 cellId = a_bandCellId(
id, set);
6583 if(a_isHalo(cellId))
continue;
6585 if(!a_isGBoundaryCellG(cellId, set)) {
6586#ifdef standardStencil
6588 for(
MInt i = 0; i < nDim; i++) {
6590 (a_levelSetFunctionG(c_neighborId(cellId, 2 * i + 1), set)
6591 + a_levelSetFunctionG(c_neighborId(cellId, 2 * i), set) - F2 * a_levelSetFunctionG(cellId, set))
6592 *
POW2(m_FgCellDistance);
6596 mixedDerivative[0] = F1B4 *
POW2(m_FgCellDistance)
6597 * (a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 0), 2 + 0), set)
6598 + a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 1), 2 + 1), set)
6599 - a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 0), 2 + 1), set)
6600 - a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 1), 2 + 0), set));
6601 mixedDerivative[1] = F1B4 *
POW2(m_FgCellDistance)
6602 * (a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 0), 4 + 0), set)
6603 + a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 1), 4 + 1), set)
6604 - a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 0), 4 + 1), set)
6605 - a_levelSetFunctionG(c_neighborId(c_neighborId(cellId, 1), 4 + 0), set));
6606 mixedDerivative[2] =
6607 F1B4 *
POW2(m_FgCellDistance)
6608 * (a_levelSetFunctionG(c_neighborId(c_neighborId(c_neighborId(cellId, 2), 2 + 0), 4 + 0), set)
6609 + a_levelSetFunctionG(c_neighborId(c_neighborId(c_neighborId(cellId, 2), 2 + 1), 4 + 1), set)
6610 - a_levelSetFunctionG(c_neighborId(c_neighborId(c_neighborId(cellId, 2), 2 + 0), 4 + 1), set)
6611 - a_levelSetFunctionG(c_neighborId(c_neighborId(c_neighborId(cellId, 2), 2 + 1), 4 + 0), set));
6615 for(
MInt i = 0; i < nDim; i++) {
6616 denominator +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
6618 denominator = F1 /
POW2(denominator);
6619 denominator = sqrt(denominator * denominator * denominator);
6621 a_curvatureG(cellId, set) =
6624 * (
POW2(a_levelSetFunctionSlope(cellId, 1, set)) +
POW2(a_levelSetFunctionSlope(cellId, 2, set)))
6626 * (
POW2(a_levelSetFunctionSlope(cellId, 0, set)) +
POW2(a_levelSetFunctionSlope(cellId, 2, set)))
6628 * (
POW2(a_levelSetFunctionSlope(cellId, 0, set)) +
POW2(a_levelSetFunctionSlope(cellId, 1, set)))
6630 * (mixedDerivative[0] * a_levelSetFunctionSlope(cellId, 0, set)
6631 * a_levelSetFunctionSlope(cellId, 1, set)
6632 + mixedDerivative[1] * a_levelSetFunctionSlope(cellId, 0, set)
6633 * a_levelSetFunctionSlope(cellId, 2, set)
6634 + mixedDerivative[2] * a_levelSetFunctionSlope(cellId, 1, set)
6635 * a_levelSetFunctionSlope(cellId, 2, set)));
6639 a_curvatureG(cellId, set) = F1B2 * m_FgCellDistance
6640 * (a_normalVectorG(a_bandNghbrIdsG(cellId, 1, set), 0, set)
6641 - a_normalVectorG(a_bandNghbrIdsG(cellId, 0, set), 0, set)
6642 + a_normalVectorG(a_bandNghbrIdsG(cellId, 3, set), 1, set)
6643 - a_normalVectorG(a_bandNghbrIdsG(cellId, 2, set), 1, set)
6644 + a_normalVectorG(a_bandNghbrIdsG(cellId, 5, set), 2, set)
6645 - a_normalVectorG(a_bandNghbrIdsG(cellId, 4, set), 2, set));
6647 if(m_curvatureDamp) {
6648 MFloat levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6649 MFloat levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6651 a_curvatureG(cellId, set) *= F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
6660 exchangeDataLS(&a_curvatureG(0, 0), m_maxNoSets);
6679 IF_CONSTEXPR(nDim == 2) {
6680 MInt cellId, nghbrL, nghbrL2, nghbrR, nghbrR2;
6682 MBool oneSidedR =
false;
6683 MBool oneSidedL =
false;
6684 MFloat FgCellDistanceL2R2 = m_FgCellDistance * F1B4, FgCellDistanceLR = m_FgCellDistance * F1B2;
6685 MFloat levelSetNegative = F0, levelSetPlus = F0;
6689#ifdef standardStencil
6691 for(
MInt set = 0; set < m_noSets; set++) {
6692 if(!m_computeSet[set])
continue;
6693 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6694 cellId = a_bandCellId(
id, set);
6695 if(a_isHalo(cellId))
continue;
6698 for(
MInt i = 0; i < nDim; i++) {
6700 (a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i + 1], set)
6701 + a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i], set) - F2 * a_levelSetFunctionG(cellId, set))
6708 mixedDerivative = 0.01;
6709 mTerm(1, AT_,
"ERROR: check code.. this part is assumed to not be used ");
6713 for(
MInt i = 0; i < nDim; i++) {
6714 denominator +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
6716 denominator = F1 /
POW2(denominator);
6717 denominator = sqrt(denominator * denominator * denominator);
6719 a_curvatureG(cellId, set) = -denominator
6720 * (grad2G[0] *
POW2(a_levelSetFunctionSlope(cellId, 1, set))
6721 + grad2G[1] *
POW2(a_levelSetFunctionSlope(cellId, 0, set))
6722 - F2 * a_levelSetFunctionSlope(cellId, 0, set)
6723 * a_levelSetFunctionSlope(cellId, 1, set) * mixedDerivative);
6729 if(m_fourthOrderNormalCurvatureComputation) {
6730 for(
MInt set = 0; set < m_noSets; set++) {
6731 if(!m_computeSet[set])
continue;
6732 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6733 cellId = a_bandCellId(
id, set);
6736 a_curvatureG(cellId, set) = F0;
6737 if(a_isHalo(cellId))
continue;
6739 for(
MInt i = 0; i < nDim; i++) {
6743 FgCellDistanceL2R2 = m_FgCellDistance * F1B4;
6744 FgCellDistanceLR = m_FgCellDistance * F1B2;
6746 nghbrL = c_neighborId(cellId, 2 * i);
6747 nghbrL2 = c_neighborId(nghbrL, 2 * i);
6748 nghbrR = c_neighborId(cellId, 2 * i + 1);
6749 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
6751 if(a_hasNeighbor(nghbrL2, 2 * i) != 0 && a_hasNeighbor(nghbrR2, 2 * i + 1) != 0) {
6753 if((!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR2, set))) {
6756 FgCellDistanceL2R2 = m_FgCellDistance * F1B2;
6760 if(!oneSidedR && !oneSidedL) {
6761 a_curvatureG(cellId, set) +=
6763 F4B3 * FgCellDistanceLR *
6765 (a_normalVectorG(nghbrR, i, set) - a_normalVectorG(nghbrL, i, set))
6767 - F1B3 * FgCellDistanceL2R2 *
6769 (a_normalVectorG(nghbrR2, i, set) - a_normalVectorG(nghbrL2, i, set));
6772 if(m_curvatureDamp) {
6773 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6774 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6776 a_curvatureG(cellId, set) *= F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
6782 for(
MInt set = 0; set < m_noSets; set++) {
6783 if(!m_computeSet[set])
continue;
6784 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6785 cellId = a_bandCellId(
id, set);
6786 a_curvatureG(cellId, set) = F0;
6787 if(a_isHalo(cellId))
continue;
6789 if(!a_isGBoundaryCellG(cellId, set)) {
6790 a_curvatureG(cellId, set) = F1B2 * m_FgCellDistance
6791 * (a_normalVectorG(a_bandNghbrIdsG(cellId, 1, set), 0, set)
6792 - a_normalVectorG(a_bandNghbrIdsG(cellId, 0, set), 0, set)
6793 + a_normalVectorG(a_bandNghbrIdsG(cellId, 3, set), 1, set)
6794 - a_normalVectorG(a_bandNghbrIdsG(cellId, 2, set), 1, set));
6796 if(m_curvatureDamp) {
6797 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6798 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6800 a_curvatureG(cellId, set) *=
6801 F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
6810 mTerm(1, AT_,
"ERROR: check 3D implementation, not done ");
6811 MInt cellId, nghbrL, nghbrL2, nghbrR, nghbrR2;
6812 MBool oneSidedR =
false;
6813 MBool oneSidedL =
false;
6814 MFloat FgCellDistanceL2R2 = m_FgCellDistance * F1B4, FgCellDistanceLR = m_FgCellDistance * F1B2;
6815 MFloat levelSetNegative = F0, levelSetPlus = F0;
6817#ifdef standardStencil
6818 for(
MInt set = 0; set < m_noSets; set++) {
6819 if(!m_computeSet[set])
continue;
6820 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6821 cellId = a_bandCellId(
id, set);
6822 if(a_isHalo(cellId))
continue;
6824 for(
MInt i = 0; i < nDim; i++) {
6826 (a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i + 1], set)
6827 + a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i], set) - F2 * a_levelSetFunctionG(cellId, set))
6831 for(
MInt i = 0; i < nDim; i++) {
6833 (a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i + 1], set)
6834 + a_levelSetFunctionG(m_cells[cellId].m_cells[2 * i], set) - F2 * a_levelSetFunctionG(cellId, set))
6839 mixedDerivative = 0.01;
6840 mTerm(1, AT_,
"ERROR: check code.. this part is assumed to not be used ");
6844 for(
MInt i = 0; i < nDim; i++) {
6845 denominator +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
6847 denominator = F1 /
POW2(denominator);
6848 denominator = sqrt(denominator * denominator * denominator);
6850 a_curvatureG(cellId, set) = -denominator
6851 * (grad2G[0] *
POW2(a_levelSetFunctionSlope(cellId, 1, set))
6852 + grad2G[1] *
POW2(a_levelSetFunctionSlope(cellId, 0, set))
6853 - F2 * a_levelSetFunctionSlope(cellId, 0, set)
6854 * a_levelSetFunctionSlope(cellId, 1, set) * mixedDerivative);
6859 if(m_fourthOrderNormalCurvatureComputation) {
6860 for(
MInt set = 0; set < m_noSets; set++) {
6861 if(!m_computeSet[set])
continue;
6862 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6863 cellId = a_bandCellId(
id, set);
6865 a_curvatureG(cellId, set) = F0;
6866 if(a_isHalo(cellId))
continue;
6868 for(
MInt i = 0; i < nDim; i++) {
6872 FgCellDistanceL2R2 = m_FgCellDistance * F1B4;
6873 FgCellDistanceLR = m_FgCellDistance * F1B2;
6875 nghbrL = c_neighborId(cellId, 2 * i);
6876 nghbrL2 = c_neighborId(nghbrL, 2 * i);
6877 nghbrR = c_neighborId(cellId, 2 * i + 1);
6878 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
6880 if(a_hasNeighbor(nghbrL2, 2 * i) != 0 && a_hasNeighbor(nghbrR2, 2 * i + 1) != 0) {
6882 if((!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR2, set))) {
6885 FgCellDistanceL2R2 = m_FgCellDistance * F1B2;
6889 if(!oneSidedR && !oneSidedL) {
6890 a_curvatureG(cellId, set) +=
6892 F4B3 * FgCellDistanceLR *
6894 (a_normalVectorG(nghbrR, i, set) - a_normalVectorG(nghbrL, i, set))
6896 - F1B3 * FgCellDistanceL2R2 *
6898 (a_normalVectorG(nghbrR2, i, set) - a_normalVectorG(nghbrL2, i, set));
6901 if(m_curvatureDamp) {
6902 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6903 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6905 a_curvatureG(cellId, set) = F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0))
6906 * a_curvatureG(cellId, set);
6911 for(
MInt set = 0; set < m_noSets; set++) {
6912 if(!m_computeSet[set])
continue;
6913 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
6914 cellId = a_bandCellId(
id, set);
6915 if(a_isHalo(cellId))
continue;
6917 if(!a_isGBoundaryCellG(cellId, set)) {
6919 a_curvatureG(cellId, set) = F1B2 * m_FgCellDistance
6920 * (a_normalVectorG(a_bandNghbrIdsG(cellId, 1, set), 0, set)
6921 - a_normalVectorG(a_bandNghbrIdsG(cellId, 0, set), 0, set)
6922 + a_normalVectorG(a_bandNghbrIdsG(cellId, 3, set), 1, set)
6923 - a_normalVectorG(a_bandNghbrIdsG(cellId, 2, set), 1, set));
6925 if(m_curvatureDamp) {
6926 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
6927 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
6929 a_curvatureG(cellId, set) = F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0))
6930 * a_curvatureG(cellId, set);
6951 ASSERT(m_lsCollectorMode == 0 || m_lsCollectorMode == 3,
"");
6953 if(m_gRKStep == 0) {
6955 if(domainId() == 0) {
6956 cerr <<
"time step #" <<
globalTimeStep <<
" - time " << m_time << endl;
6960 switch(m_levelSetTestCase) {
6963 for(
MInt set = m_startSet; set < m_noSets; set++) {
6965 a_extensionVelocityG(cellId, 0, set) = PI / 31.4 * (-c_coordinate(cellId, 1));
6966 a_extensionVelocityG(cellId, 1, set) = PI / 31.4 * (c_coordinate(cellId, 0));
6967 if(m_levelSetTestCase == 504312) {
6968 a_extensionVelocityG(cellId, 0, set) *= -1;
6969 a_extensionVelocityG(cellId, 1, set) *= -1;
6971 a_flameSpeedG(cellId, set) = F0;
6979 for(
MInt set = m_startSet; set < m_noSets; set++) {
6984 a_extensionVelocityG(cellId, 0, set) = PI / 31.4 * (-c_coordinate(cellId, 1));
6985 a_extensionVelocityG(cellId, 1, set) = PI / 31.4 * (c_coordinate(cellId, 0));
6986 a_flameSpeedG(cellId, set) = F0;
6993 MFloat Vtrans[3] = {F0, F0, F0};
6995 for(
MInt body = 0; body < m_noEmbeddedBodies; body++) {
6996 computeBodyPropertiesForced(2, Vtrans, body, time());
6997 for(
MInt i = 0; i < 3; i++) {
6998 VtransBodies(body, i) = Vtrans[i];
7004 for(
MInt set = m_startSet; set < m_noSets; set++) {
7005 if(!m_computeSet[set]) {
7008 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7010 MInt body = a_bodyIdG(cellId, set);
7012 a_extensionVelocityG(cellId, 0, set) = VtransBodies(body, 0);
7013 a_extensionVelocityG(cellId, 1, set) = VtransBodies(body, 1);
7014 IF_CONSTEXPR(nDim == 3) { a_extensionVelocityG(cellId, 2, set) = VtransBodies(body, 2); }
7016 a_extensionVelocityG(cellId, 0, set) = F0;
7017 a_extensionVelocityG(cellId, 1, set) = F0;
7018 IF_CONSTEXPR(nDim == 3) { a_extensionVelocityG(cellId, 2, set) = F0; }
7025 MFloat dx[3] = {F0, F0, F0};
7026 MFloat x1[3] = {F0, F0, F0};
7027 MFloat x0[3] = {F0, F0, F0};
7028 if(m_GCtrlPntMethod == 2 && m_initialCondition != 31) {
7031 for(
MInt body = 0; body < m_noEmbeddedBodies; body++) {
7032 bcId = m_bodyBndryCndIds[body];
7033 computeBodyPropertiesForced(1, x1, body, time() + timeStep());
7034 computeBodyPropertiesForced(1, x0, body, time());
7035 for(
MInt i = 0; i < 3; i++) {
7036 dx[i] = (x1[i] - x0[i]);
7038 m_gCtrlPnt.CtrlPnt2_shiftSTL(bcId, dx);
7042 m_time += timeStep();
7068 ASSERT(m_lsCollectorMode == 0 || m_lsCollectorMode == 2 || m_lsCollectorMode == 3, m_lsCollectorMode);
7071 MFloat epsilon = m_gCellDistance * 0.00000001;
7073 MInt cellId, nghbrL, nghbrL2, nghbrR, nghbrR2;
7075 MBool oneSidedR =
false;
7076 MBool oneSidedL =
false;
7077 MFloat FgCellDistanceL2R2 = m_FgCellDistance * F1B4, FgCellDistanceLR = m_FgCellDistance * F1B2;
7078 MFloat filterCoord = m_filterFlameTubeEdgesDistance + 0.0234;
7079 MFloat a = -F3B2,
b = F2, c = -F1B2;
7080 MBool filter =
false;
7081 MFloat levelSlopeR = -9999.9, levelSlopeL = -9999.9;
7084 MInt endSet = m_noSets;
7085 if(computingSet >= 0) {
7086 startSet = computingSet;
7087 endSet = computingSet + 1;
7093 if(m_fourthOrderNormalCurvatureComputation) {
7094 for(
MInt set = startSet; set < endSet; set++) {
7095 if(!m_computeSet[set])
continue;
7096 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7097 cellId = a_bandCellId(
id, set);
7099 for(
MInt i = 0; i < nDim; i++) {
7104 FgCellDistanceL2R2 = m_FgCellDistance * F1B4;
7105 FgCellDistanceLR = m_FgCellDistance * F1B2;
7107 nghbrL = c_neighborId(cellId, 2 * i);
7108 nghbrL2 = c_neighborId(nghbrL, 2 * i);
7109 nghbrR = c_neighborId(cellId, 2 * i + 1);
7110 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
7112 if((!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR2, set)
7113 || (a_isGBoundaryCellG(nghbrL2, set) || a_isGBoundaryCellG(nghbrR2, set)))) {
7117 FgCellDistanceL2R2 = FgCellDistanceLR;
7121 if(a_hasNeighbor(nghbrL, 2 * i) == 0 || a_hasNeighbor(nghbrR, 2 * i + 1) == 0) {
7125 FgCellDistanceL2R2 = FgCellDistanceLR;
7140 if(a_hasNeighbor(cellId, 2 * i + 1) == 0) {
7143 a_levelSetFunctionSlope(cellId, i, set) =
7147 (
a * a_levelSetFunctionG(cellId, set) +
b * a_levelSetFunctionG(nghbrL, set)
7148 + c * a_levelSetFunctionG(nghbrL2, set));
7152 if(a_hasNeighbor(cellId, 2 * i) == 0) {
7155 a_levelSetFunctionSlope(cellId, i, set) =
7159 (
a * a_levelSetFunctionG(cellId, set) +
b * a_levelSetFunctionG(nghbrR, set)
7160 + c * a_levelSetFunctionG(nghbrR2, set));
7164 if(!oneSidedR && !oneSidedL && m_filterFlameTubeEdges) {
7165 if(c_coordinate(cellId, 1) < filterCoord) {
7168 levelSlopeR = (a_levelSetFunctionG(nghbrR, set) - a_levelSetFunctionG(cellId, set)) * m_FgCellDistance;
7170 levelSlopeL = (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(nghbrL, set)) * m_FgCellDistance;
7173 a_levelSetFunctionSlope(cellId, i, set) = (F1B2 * (levelSlopeR + levelSlopeL));
7179 if(!oneSidedR && !oneSidedL) {
7180 a_levelSetFunctionSlope(cellId, i, set) =
7182 F4B3 * FgCellDistanceLR *
7184 (a_levelSetFunctionG(nghbrR, set) - a_levelSetFunctionG(nghbrL, set))
7186 - F1B3 * FgCellDistanceL2R2 *
7188 (a_levelSetFunctionG(nghbrR2, set) - a_levelSetFunctionG(nghbrL2, set));
7191 FgradG =
POW2(a_levelSetFunctionSlope(cellId, 0, set));
7192 for(
MInt k = 1; k < nDim; k++)
7193 FgradG +=
POW2(a_levelSetFunctionSlope(cellId, k, set));
7195 FgradG = F1 /
mMax(epsilon, sqrt(FgradG));
7197 for(
MInt k = 0; k < nDim; k++)
7198 a_normalVectorG(cellId, k, set) = -FgradG * a_levelSetFunctionSlope(cellId, k, set);
7203 for(
MInt set = startSet; set < endSet; set++) {
7204 if(!m_computeSet[set])
continue;
7206 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7207 cellId = a_bandCellId(
id, set);
7208 if(a_isHalo(cellId))
continue;
7218 for(
MInt i = 0; i < nDim; i++) {
7219 MInt n0 = c_neighborId(cellId, 2 * i);
7220 MInt n1 = c_neighborId(cellId, 2 * i + 1);
7223 a_levelSetFunctionSlope(cellId, i, set) = (a_levelSetFunctionG(n1, set) - a_levelSetFunctionG(n0, set))
7224 / (c_coordinate(n1, i) - c_coordinate(n0, i));
7227 FgradG =
POW2(a_levelSetFunctionSlope(cellId, 0, set));
7228 for(
MInt i = 1; i < nDim; i++)
7229 FgradG +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
7230 FgradG = F1 /
mMax(epsilon, sqrt(FgradG));
7231 for(
MInt i = 0; i < nDim; i++)
7232 a_normalVectorG(cellId, i, set) = -FgradG * a_levelSetFunctionSlope(cellId, i, set);
7238 exchangeDataLS(&a_normalVectorG(0, 0, 0), m_maxNoSets * nDim);
7262 MFloat epsilon = m_gCellDistance * 0.00000001;
7263 const MFloat Fdx = F1B2 * m_FgCellDistance;
7264 MInt cellId, nghbrL, nghbrL2, nghbrR, nghbrR2;
7266 MBool oneSidedR =
false;
7267 MBool oneSidedL =
false;
7268 MFloat FgCellDistanceL2R2 = m_FgCellDistance * F1B4, FgCellDistanceLR = m_FgCellDistance * F1B2;
7272 if(m_fourthOrderNormalCurvatureComputation) {
7273 for(
MInt set = 0; set < m_noSets; set++) {
7274 if(!m_computeSet[set])
continue;
7275 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7276 cellId = a_bandCellId(
id, set);
7278 for(
MInt i = 0; i < nDim; i++) {
7282 FgCellDistanceL2R2 = m_FgCellDistance * F1B4;
7283 FgCellDistanceLR = m_FgCellDistance * F1B2;
7285 nghbrL = c_neighborId(cellId, 2 * i);
7286 nghbrL2 = c_neighborId(nghbrL, 2 * i);
7287 nghbrR = c_neighborId(cellId, 2 * i + 1);
7288 nghbrR2 = c_neighborId(nghbrR, 2 * i + 1);
7290 if(a_hasNeighbor(nghbrL2, 2 * i) != 0 && a_hasNeighbor(nghbrR2, 2 * i + 1) != 0) {
7291 if((!a_inBandG(nghbrL2, set) || !a_inBandG(nghbrR2, set))) {
7295 FgCellDistanceL2R2 = FgCellDistanceLR;
7299 if(!oneSidedR && !oneSidedL) {
7300 a_levelSetFunctionSlope(cellId, i, set) =
7302 F4B3 * FgCellDistanceLR *
7304 (a_levelSetFunctionG(nghbrR, set) - a_levelSetFunctionG(nghbrL, set))
7306 - F1B3 * FgCellDistanceL2R2 *
7308 (a_levelSetFunctionG(nghbrR2, set) - a_levelSetFunctionG(nghbrL2, set));
7311 FgradG =
POW2(a_levelSetFunctionSlope(cellId, 0, set));
7312 for(
MInt i = 1; i < nDim; i++)
7313 FgradG +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
7315 FgradG = F1 /
mMax(epsilon, sqrt(FgradG));
7317 for(
MInt i = 0; i < nDim; i++)
7318 a_normalVectorG(cellId, i, set) = -FgradG * a_levelSetFunctionSlope(cellId, i, set);
7322 for(
MInt set = 0; set < m_noSets; set++) {
7323 if(!m_computeSet[set])
continue;
7324 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7325 cellId = a_bandCellId(
id, set);
7329 for(
MInt i = 0; i < nDim; i++)
7330 a_levelSetFunctionSlope(cellId, i, set) = (a_levelSetFunctionG(c_neighborId(cellId, 2 * i + 1), set)
7331 - a_levelSetFunctionG(c_neighborId(cellId, 2 * i), set))
7334 FgradG =
POW2(a_levelSetFunctionSlope(cellId, 0, set));
7335 for(
MInt i = 1; i < nDim; i++)
7336 FgradG +=
POW2(a_levelSetFunctionSlope(cellId, i, set));
7337 FgradG = F1 /
mMax(epsilon, sqrt(FgradG));
7338 for(
MInt i = 0; i < nDim; i++)
7339 a_normalVectorG(cellId, i, set) = -FgradG * a_levelSetFunctionSlope(cellId, i, set);
7345 exchangeDataLS(&a_normalVectorG(0, 0, 0), m_maxNoSets * nDim);
7358 const MFloat Fdx = F1B2 * m_FgCellDistance;
7361 for(
MInt set = 0; set < m_noSets; set++) {
7362 if(!m_computeSet[set])
continue;
7363 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7364 for(
MInt i = 0; i < nDim; i++)
7365 a_levelSetFunctionSlope(a_G0CellId(
id, set), i, set) =
7366 (a_levelSetFunctionG(c_neighborId(a_G0CellId(
id, set), 2 * i + 1), set)
7367 - a_levelSetFunctionG(c_neighborId(a_G0CellId(
id, set), 2 * i), set))
7370 FgradG =
POW2(a_levelSetFunctionSlope(a_G0CellId(
id, set), 0, set));
7371 for(
MInt i = 1; i < nDim; i++)
7372 FgradG +=
POW2(a_levelSetFunctionSlope(a_G0CellId(
id, set), i, set));
7373 FgradG = F1 / sqrt(FgradG);
7374 for(
MInt i = 0; i < nDim; i++)
7375 a_normalVectorG(a_G0CellId(
id, set), i, set) = -FgradG * a_levelSetFunctionSlope(a_G0CellId(
id, set), i, set);
7393 MInt cellListSize = 0;
7397 gWindowCell.fill(0);
7399 fill_n(m_cellList, m_maxNoCells, -1);
7401 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7405 if(a_isGZeroCell(cellId, set)) {
7409 if(a_level(cellId) != a_maxGCellLevel()) {
7413 if(a_isHalo(cellId)) {
7418 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
7419 if(a_hasNeighbor(cellId, dirId) && a_hasNeighbor(c_neighborId(cellId, dirId), dirId)
7420 && !a_isGBoundaryCellG(cellId, set) && !a_isGBoundaryCellG(c_neighborId(cellId, dirId), set)) {
7425 if(count == m_noDirs) {
7426 m_cellList[cellListSize++] =
cellId;
7427 if(a_isWindow(cellId)) {
7435 MIntScratchSpace sendBufferSize(grid().noNeighborDomains(), AT_,
"sendBufferSize");
7436 MIntScratchSpace receiveBufferSize(grid().noNeighborDomains(), AT_,
"receiveBufferSize");
7438 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
7439 sendBufferSize.p[i] = 0;
7440 for(
MInt j = 0; j < noWindowCells(i); j++) {
7441 m_intSendBuffers[i][sendBufferSize.p[i]++] = gWindowCell[windowCellId(i, j)];
7444 if(grid().azimuthalPeriodicity()) {
7445 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7446 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
7447 m_intSendBuffers[i][sendBufferSize.p[i]++] = gWindowCell[grid().azimuthalWindowCell(i, j)];
7453 exchangeIntBuffers(sendBufferSize.getPointer(), receiveBufferSize.getPointer(), 11, 1);
7457 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
7460 if(receiveBufferSize.p[i] != noHaloCells(i))
7461 mTerm(1, AT_,
"this was not expected to happen: wrong number of halo information...");
7463 for(
MInt j = 0; j < noHaloCells(i); j++) {
7464 MInt haloCell = haloCellId(i, j);
7465 if(m_intReceiveBuffers[i][j] == 1) {
7466 m_cellList[cellListSize++] = haloCell;
7472 if(grid().azimuthalPeriodicity()) {
7473 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7474 MInt offset = noHaloCells(grid().azimuthalNeighborDomain(i));
7475 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
7476 MInt n = offset + j;
7477 MInt haloCell = grid().azimuthalHaloCell(i, j);
7478 if(m_intReceiveBuffers[i][n] == 1) {
7479 m_cellList[cellListSize++] = haloCell;
7488 for(
MInt n = 0; n < nDim; n++) {
7491 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7493 if(a_isHalo(cellId)) {
7497 velocity[
cellId] = a_extensionVelocityG(cellId, n, set);
7500 for(
MInt cell = 0; cell < cellListSize; cell++) {
7505 hyperbolicExtensionOpt(velocity.getPointer(), m_cellList, cellListSize, m_extVelConvergence, set);
7508 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7510 a_extensionVelocityG(cellId, n, set) = velocity[
cellId];
7513 for(
MInt cell = 0; cell < cellListSize; cell++) {
7515 a_extensionVelocityG(cellId, n, set) = velocity[
cellId];
7531 ASSERT(m_lsCollectorMode == 0,
"");
7538 MFloat FdampingDistanceFlameBase = F1 / m_dampingDistanceFlameBase;
7539 MFloat dampCoord = m_dampingDistanceFlameBase + m_yOffsetFlameTube;
7540 MFloat FextensionDampingDistanceFlameBase = F1 / m_dampingDistanceFlameBaseExtVel;
7541 MFloat extensionDampCoord = m_dampingDistanceFlameBaseExtVel + m_yOffsetFlameTube;
7542 MFloat levelSetPlus = F0, levelSetNegative = F0;
7552 gWindowCell.fill(0);
7554 for(
MInt c = 0; c < m_maxNoCells; c++) {
7558 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7559 cellId = a_bandCellId(
id, set);
7561 if(a_isGZeroCell(cellId, set))
continue;
7564 if(a_level(cellId) != a_maxGCellLevel())
continue;
7566 if(a_isHalo(cellId))
continue;
7568 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
7569 if(a_hasNeighbor(cellId, dirId) && a_hasNeighbor(c_neighborId(cellId, dirId), dirId) &&
7572 !a_isGBoundaryCellG(cellId, set) && !a_isGBoundaryCellG(c_neighborId(cellId, dirId), set)) {
7576 if(count == m_noDirs) {
7577 m_cellList[cellListSize++] =
cellId;
7580 if(a_isWindow(cellId)) gWindowCell[
cellId] = 1;
7586 MIntScratchSpace sendBufferSize(grid().noNeighborDomains(), AT_,
"sendBufferSize");
7587 MIntScratchSpace receiveBufferSize(grid().noNeighborDomains(), AT_,
"receiveBufferSize");
7589 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
7590 sendBufferSize.p[i] = 0;
7591 for(
MInt j = 0; j < noWindowCells(i); j++) {
7592 m_intSendBuffers[i][sendBufferSize.p[i]++] = gWindowCell[windowCellId(i, j)];
7595 if(grid().azimuthalPeriodicity()) {
7596 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7597 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
7598 m_intSendBuffers[i][sendBufferSize.p[i]++] = gWindowCell[grid().azimuthalWindowCell(i, j)];
7604 exchangeIntBuffers(sendBufferSize.getPointer(), receiveBufferSize.getPointer(), 11, 1);
7608 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
7612 if(receiveBufferSize.p[i] != noHaloCells(i))
7613 mTerm(1, AT_,
"this was not expected to happen: wrong number of halo information...");
7615 for(
MInt j = 0; j < noHaloCells(i); j++) {
7616 MInt haloCell = haloCellId(i, j);
7617 if(m_intReceiveBuffers[i][j] == 1) {
7618 m_cellList[cellListSize++] = haloCell;
7629 if(grid().azimuthalPeriodicity()) {
7630 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7631 MInt offset = noHaloCells(grid().azimuthalNeighborDomain(i));
7632 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
7633 MInt n = offset + j;
7634 MInt haloCell = grid().azimuthalHaloCell(i, j);
7635 if(m_intReceiveBuffers[i][n] == 1) {
7636 m_cellList[cellListSize++] = haloCell;
7644 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7645 cellId = a_G0CellId(
id, set);
7647 a_correctedBurningVelocity(cellId, set) =
7648 a_flameSpeedG(cellId, set) * (F1 - a_curvatureG(cellId, set) * m_marksteinLength);
7650 for(
MInt i = 0; i < nDim; i++) {
7651 a_extensionVelocityG(cellId, i, set) += a_normalVectorG(cellId, i, set) * m_rhoFlameTube * FfluidDensity[
id]
7652 * a_correctedBurningVelocity(cellId, set);
7656 if(cellListSize < a_noG0Cells(set)) {
7657 cerr <<
"Error: number of cells in cell list is smaller than number of G0 cells" << cellListSize
7658 <<
" , noG0cells: " << a_noG0Cells(set) << endl;
7661 IF_CONSTEXPR(nDim == 2) {
7663 for(
MInt i = 0; i < nDim; i++) {
7664 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7665 cellId = a_G0CellId(
id, set);
7666 if(a_isHalo(cellId))
continue;
7668 q.p[
cellId] = a_extensionVelocityG(cellId, i, set);
7669 if(c_coordinate(cellId, 1) < extensionDampCoord) {
7670 q.p[
cellId] = a_extensionVelocityG(cellId, i, set) * FextensionDampingDistanceFlameBase
7671 * (c_coordinate(cellId, 1) - m_yOffsetFlameTube);
7675 for(
MInt cell = 0; cell < cellListSize; cell++) {
7676 cellId = m_cellList[cell];
7680 hyperbolicExtensionOpt(q.getPointer(), m_cellList, cellListSize, m_extVelConvergence, set);
7682 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7683 cellId = a_G0CellId(
id, set);
7684 a_extensionVelocityG(cellId, i, set) = q.p[
cellId];
7687 for(
MInt cell = 0; cell < cellListSize; cell++) {
7688 cellId = m_cellList[cell];
7689 a_extensionVelocityG(cellId, i, set) = q.p[
cellId];
7693 if(m_useCorrectedBurningVelocity) {
7694 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7695 cellId = a_G0CellId(
id, set);
7696 if(a_isHalo(cellId))
continue;
7697 q.p[
cellId] = a_correctedBurningVelocity(cellId, set);
7699 hyperbolicExtensionOpt(q.getPointer(), m_cellList, cellListSize, m_extVelConvergence, set);
7701 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7702 cellId = a_G0CellId(
id, set);
7703 a_correctedBurningVelocity(cellId, set) = q.p[
cellId];
7705 for(
MInt cell = 0; cell < cellListSize; cell++) {
7706 cellId = m_cellList[cell];
7707 a_correctedBurningVelocity(cellId, set) = q.p[
cellId];
7711 if(m_hyperbolicCurvature)
7712 hyperbolicExtensionOpt(&a_curvatureG(0, 0), m_cellList, cellListSize, m_extVelConvergence, set);
7714 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7715 cellId = a_bandCellId(
id, set);
7717 if(c_coordinate(cellId, 1) < m_yOffsetFlameTube) {
7718 a_curvatureG(cellId, set) = F0;
7719 for(
MInt i = 0; i < nDim; i++) {
7720 a_extensionVelocityG(cellId, i, set) = F0;
7725 if(c_coordinate(cellId, 1) < dampCoord) {
7726 a_curvatureG(cellId, set) *= FdampingDistanceFlameBase * (c_coordinate(cellId, 1) - 0.0234);
7727 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
7728 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
7729 a_curvatureG(cellId, set) *= F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
7732 if(c_coordinate(cellId, 1) < extensionDampCoord) {
7733 for(
MInt i = 0; i < nDim; i++) {
7734 a_extensionVelocityG(cellId, i, set) *=
7735 FextensionDampingDistanceFlameBase * (c_coordinate(cellId, 1) - m_yOffsetFlameTube);
7743 for(
MInt i = 0; i < nDim; i++) {
7747 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7748 cellId = a_G0CellId(
id, set);
7749 if(a_isHalo(cellId))
continue;
7752 q.p[
cellId] = a_extensionVelocityG(cellId, i, set);
7754 if(c_coordinate(cellId, 1) < extensionDampCoord) {
7755 q.p[
cellId] *= FextensionDampingDistanceFlameBase * (c_coordinate(cellId, 1) - m_yOffsetFlameTube);
7757 if(c_coordinate(cellId, 1) < m_yOffsetFlameTube) {
7762 for(
MInt cell = 0; cell < cellListSize; cell++) {
7763 cellId = m_cellList[cell];
7767 hyperbolicExtensionOpt(q.getPointer(), m_cellList, cellListSize, m_extVelConvergence, set);
7769 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7770 cellId = a_G0CellId(
id, set);
7771 a_extensionVelocityG(cellId, i, set) = q.p[
cellId];
7774 for(
MInt cell = 0; cell < cellListSize; cell++) {
7775 cellId = m_cellList[cell];
7776 a_extensionVelocityG(cellId, i, set) = q.p[
cellId];
7780 if(m_useCorrectedBurningVelocity) {
7781 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7782 cellId = a_G0CellId(
id, set);
7783 if(a_isHalo(cellId))
continue;
7784 q.p[
cellId] = a_correctedBurningVelocity(cellId, set);
7786 hyperbolicExtensionOpt(q.getPointer(), m_cellList, cellListSize, m_extVelConvergence, set);
7788 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
7789 cellId = a_G0CellId(
id, set);
7790 a_correctedBurningVelocity(cellId, set) = q.p[
cellId];
7792 for(
MInt cell = 0; cell < cellListSize; cell++) {
7793 cellId = m_cellList[cell];
7794 a_correctedBurningVelocity(cellId, set) = q.p[
cellId];
7798 if(m_hyperbolicCurvature)
7799 hyperbolicExtensionOpt(&a_curvatureG(0, 0), m_cellList, cellListSize, m_extVelConvergence, set);
7801 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
7802 cellId = a_bandCellId(
id, set);
7804 if(c_coordinate(cellId, 1) < m_yOffsetFlameTube) {
7805 a_curvatureG(cellId, set) = F0;
7806 for(
MInt i = 0; i < nDim; i++) {
7807 a_extensionVelocityG(cellId, i, set) = F0;
7812 if(c_coordinate(cellId, 1) < dampCoord) {
7813 a_curvatureG(cellId, set) *= FdampingDistanceFlameBase * (c_coordinate(cellId, 1) - m_yOffsetFlameTube);
7814 levelSetNegative = a_levelSetFunctionG(cellId, set) - (m_noReactionCells / m_curvatureDampFactor);
7815 levelSetPlus = a_levelSetFunctionG(cellId, set) + (m_noReactionCells / m_curvatureDampFactor);
7816 a_curvatureG(cellId, set) *= F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
7819 if(c_coordinate(cellId, 1) < extensionDampCoord) {
7820 for(
MInt i = 0; i < nDim; i++) {
7821 a_extensionVelocityG(cellId, i, set) *=
7822 FextensionDampingDistanceFlameBase * (c_coordinate(cellId, 1) - m_yOffsetFlameTube);
7828 DEBUG(
"LsCartesianSolver::computeExtensionVelocityGEQUPVMarksteinOpt return", MAIA_DEBUG_TRACE_OUT);
7848 m_log <<
"ERROR, WARNING, you are using hyperbolicExtensionOpt... look at the code and make sure the "
7849 "'optimization' below '//euler solver' is not commented since it is wrong"
7854 MInt nghbrL, nghbrR;
7855 MFloat dtEULER = m_extVelCFL * m_gCellDistance;
7856 MFloat eps = 0.000000001;
7862 minIteration = m_gBandWidth / m_extVelCFL;
7870 for(
MInt cell = 0; cell < cellListSize; cell++) {
7872 m_signG[IDX_LSSET(cellId, set)] =
7873 a_levelSetFunctionG(cellId, set) /
mMax(eps, fabs(a_levelSetFunctionG(cellId, set)));
7876 exchangeLs(q, set, 1);
7885 while(iteration < m_extVelIterations || iteration < minIteration || res < convergenceCriterion) {
7894 for(
MInt cell = 0; cell < cellListSize; cell++) {
7896 levelSetRHS[
cellId] = F0;
7897 if(a_isHalo(cellId))
continue;
7898 for(
MInt i = 0; i < nDim; i++) {
7899 nghbrL = c_neighborId(cellId, 2 * i);
7900 nghbrR = c_neighborId(cellId, 2 * i + 1);
7901 levelSetRHS[
cellId] +=
mMax(m_signG[IDX_LSSET(cellId, set)] * (-a_normalVectorG(cellId, i, set)), F0)
7902 * (q[
cellId] - q[nghbrL]) * m_FgCellDistance
7903 +
mMin(m_signG[IDX_LSSET(cellId, set)] * (-a_normalVectorG(cellId, i, set)), F0)
7904 * (q[nghbrR] - q[
cellId]) * m_FgCellDistance;
7917 res =
mMax(res,
ABS(q[cellId] - qOld));
7920 exchangeLs(q, set, 1);
7924 MPI_Allreduce(MPI_IN_PLACE, &res, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"res");
7926 switch(m_levelSetBoundaryCondition) {
7929 if(res < convergenceCriterion) {
7931 if(domainId() == 0) {
7933 stringstream hyperbolicFile;
7934 hyperbolicFile <<
"hyperbolicExtension";
7935 if(m_noSets > 1) hyperbolicFile <<
"_s" << set;
7936 hyperbolicFile <<
"_" << domainId();
7937 datei = fopen((hyperbolicFile.str()).c_str(),
"a+");
7939 fprintf(datei,
" %-10.10f", res);
7940 fprintf(datei,
" %d", iteration);
7941 fprintf(datei,
"\n");
7952 if(domainId() == 0) {
7954 stringstream hyperbolicFile;
7955 hyperbolicFile <<
"hyperbolicExtension";
7956 if(m_noSets > 1) hyperbolicFile <<
"_s" << set;
7957 hyperbolicFile <<
"_" << domainId();
7958 datei = fopen((hyperbolicFile.str()).c_str(),
"a+");
7960 fprintf(datei,
" %-10.10f", res);
7961 fprintf(datei,
" %d", iteration);
7962 fprintf(datei,
"\n");
7982 }
else if(m_levelSetMb || m_levelSetFv) {
7985 }
else if(m_freeSurface) {
7989 ASSERT(m_timeStepMethod == 8,
"");
7990 m_timeStep = m_cfl * m_gCellDistance;
8016 for(
MInt set = 0; set < m_noSets; set++) {
8018 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
8019 cellId = a_bandCellId(
id, set);
8020 while(c_parentId(cellId) > -1) {
8021 cellId = c_parentId(cellId);
8022 a_levelSetFunctionG(cellId, set) = 0;
8023 if(!m_semiLagrange) {
8024 a_correctedBurningVelocity(cellId, set) = 0;
8025 a_curvatureG(cellId, set) = F0;
8026 for(
MInt i = 0; i < nDim; i++) {
8027 a_extensionVelocityG(cellId, i, set) = 0;
8028 a_normalVectorG(cellId, i, set) = 0;
8035 for(
MInt id = 0;
id < a_noBandCells(set);
id++) {
8036 cellId = a_bandCellId(
id, set);
8038 while(c_parentId(cellId) > -1) {
8039 cellId = c_parentId(cellId);
8040 factor *= FnoChildren;
8041 a_levelSetFunctionG(cellId, set) += factor * a_levelSetFunctionG(a_bandCellId(
id, set), set);
8042 if(!m_semiLagrange) {
8043 a_correctedBurningVelocity(cellId, set) += factor * a_correctedBurningVelocity(a_bandCellId(
id, set), set);
8044 a_curvatureG(cellId, set) += factor * a_curvatureG(a_bandCellId(
id, set), set);
8046 for(
MInt i = 0; i < nDim; i++) {
8047 a_extensionVelocityG(cellId, i, set) += factor * a_extensionVelocityG(a_bandCellId(
id, set), i, set);
8048 a_normalVectorG(cellId, i, set) += factor * a_normalVectorG(a_bandCellId(
id, set), i, set);
8073 MFloat Dx0, Dxplus, Dxminus, Dy0, Dyplus, Dyminus, sigma, rhoS_L;
8075 const MFloat eps = F1 / FPOW10[10];
8081 if(!m_highOrderDeltaFunction) {
8083 m_massConsumption = F0;
8085 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
8087 cellId = a_G0CellId(
id, set);
8088 if(a_isHalo(cellId))
continue;
8090 if(a_level(cellId) != a_maxGCellLevel())
continue;
8092 Dx0 = (a_levelSetFunctionG(c_neighborId(cellId, 1), set) - a_levelSetFunctionG(c_neighborId(cellId, 0), set))
8093 * m_FgCellDistance * F1B2;
8095 (a_levelSetFunctionG(c_neighborId(cellId, 1), set) - a_levelSetFunctionG(cellId, set)) * m_FgCellDistance;
8097 (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(c_neighborId(cellId, 0), set)) * m_FgCellDistance;
8098 Dy0 = (a_levelSetFunctionG(c_neighborId(cellId, 3), set) - a_levelSetFunctionG(c_neighborId(cellId, 2), set))
8099 * m_FgCellDistance * F1B2;
8101 (a_levelSetFunctionG(c_neighborId(cellId, 3), set) - a_levelSetFunctionG(cellId, set)) * m_FgCellDistance;
8103 (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(c_neighborId(cellId, 2), set)) * m_FgCellDistance;
8104 IF_CONSTEXPR(nDim == 3) {
8108 Dz0 = (a_levelSetFunctionG(c_neighborId(cellId, 5), set) - a_levelSetFunctionG(c_neighborId(cellId, 4), set))
8109 * m_FgCellDistance * F1B2;
8111 (a_levelSetFunctionG(c_neighborId(cellId, 5), set) - a_levelSetFunctionG(cellId, set)) * m_FgCellDistance;
8113 (a_levelSetFunctionG(cellId, set) - a_levelSetFunctionG(c_neighborId(cellId, 4), set)) * m_FgCellDistance;
8117 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 4), set) < F0)
8118 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 4), set) * Dz0)
8119 / (
ABS(Dzminus) *
ABS(sigma) *
POW2(m_gCellDistance));
8120 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 5), set) < F0)
8121 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 5), set) * Dz0)
8122 / (
ABS(Dzplus) *
ABS(sigma) *
POW2(m_gCellDistance));
8125 sigma = sqrt(
POW2(Dx0) +
POW2(Dy0) + eps);
8136 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 0), set) < F0)
8137 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 0), set) * Dx0)
8138 / (
ABS(Dxminus) *
ABS(sigma) *
POW2(m_gCellDistance));
8139 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 1), set) < F0)
8140 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 1), set) * Dx0)
8141 / (
ABS(Dxplus) *
ABS(sigma) *
POW2(m_gCellDistance));
8142 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 2), set) < F0)
8143 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 2), set) * Dy0)
8144 / (
ABS(Dyminus) *
ABS(sigma) *
POW2(m_gCellDistance));
8145 if(a_levelSetFunctionG(cellId, set) * a_levelSetFunctionG(c_neighborId(cellId, 3), set) < F0)
8146 deltaFunction +=
ABS(a_levelSetFunctionG(c_neighborId(cellId, 3), set) * Dy0)
8147 / (
ABS(Dyplus) *
ABS(sigma) *
POW2(m_gCellDistance));
8149 if(m_combustion && m_plenum) {
8150 IF_CONSTEXPR(nDim == 2) {
8151 m_arcLength += deltaFunction *
POW2(m_gCellDistance);
8152 rhoS_L = m_rhoFlameTube * a_flameSpeedG(cellId, set) * (F1 - a_curvatureG(cellId, set) * m_marksteinLength);
8154 m_massConsumption += rhoS_L * deltaFunction * sigma *
POW2(m_gCellDistance);
8159 m_arcLength += deltaFunction *
POW3(m_gCellDistance);
8160 rhoS_L = m_rhoFlameTube * a_flameSpeedG(cellId, set) * (F1 - a_curvatureG(cellId, set) * m_marksteinLength);
8162 m_massConsumption += rhoS_L * deltaFunction * sigma *
POW3(m_gCellDistance);
8167 IF_CONSTEXPR(nDim == 2) {
8168 m_arcLength += deltaFunction *
POW2(m_gCellDistance);
8169 rhoS_L = m_rhoInfinity * a_flameSpeedG(cellId, set) * (F1 - a_curvatureG(cellId, set) * m_marksteinLength);
8170 m_massConsumption += rhoS_L * deltaFunction * sigma *
POW2(m_gCellDistance);
8175 m_arcLength += deltaFunction *
POW3(m_gCellDistance);
8176 rhoS_L = m_rhoInfinity * a_flameSpeedG(cellId, set) * (F1 - a_curvatureG(cellId, set) * m_marksteinLength);
8177 m_massConsumption += rhoS_L * deltaFunction * sigma *
POW3(m_gCellDistance);
8191 MPI_Allreduce(MPI_IN_PLACE, &m_arcLength, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"m_arcLength");
8192 MPI_Allreduce(MPI_IN_PLACE, &m_massConsumption, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
8193 "m_massConsumption");
8218 mAlloc(m_bodyToSetTable, m_noBodyBndryCndIds,
"m_bodyToSetTable", 0, AT_);
8219 mAlloc(m_noBodiesInSet, m_maxNoSets,
"m_noBodiesInSet", 0, AT_);
8220 mAlloc(m_setToBodiesTable, m_maxNoSets, m_noBodyBndryCndIds,
"m_setToBodiesTable", 0, AT_);
8225 m_startSet = (m_buildCollectedLevelSetFunction ? 1 : 0);
8226 m_noSets = m_noBodyBndryCndIds + m_startSet;
8227 m_noSets = Context::getSolverProperty<MInt>(
"nodifferentSets", m_solverId, AT_, &m_noSets);
8231 for(
MInt i = 0; i < m_noSets; i++) {
8232 bodiesinSet[i] = Context::getSolverProperty<MInt>(
"bodiesinSet", m_solverId, AT_, &bodiesinSet[i], i);
8233 sumbodies = sumbodies + bodiesinSet[i];
8236 if(sumbodies != m_noBodyBndryCndIds)
8238 "The number of bodies devided onto the sets does not fit the total number of moving "
8239 "boundery-conditions for mode 11!");
8240 m_noSets = m_noSets + m_startSet;
8244 for(
MInt j = 0; j < m_noSets; j++) {
8245 for(
MInt i = 0; i < bodiesinSet[j]; i++) {
8246 m_bodyToSetTable[count] = j + m_startSet;
8247 m_setToBodiesTable[m_startSet + j][i] = count;
8248 m_noBodiesInSet[m_startSet + j]++;
8256 m_noSets = m_noBodyBndryCndIds + m_startSet;
8257 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
8258 m_bodyToSetTable[i] = i + m_startSet;
8259 m_setToBodiesTable[i + m_startSet][m_noBodiesInSet[i + m_startSet]] = i;
8260 m_noBodiesInSet[i + m_startSet]++;
8264 if(m_noSets > 0 && domainId() == 0 && m_noBodyBndryCndIds <= 10) {
8265 cerr <<
" noSets: " << m_noSets << endl;
8266 cerr <<
" m_bodyToSetTable: ";
8267 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++)
8268 cerr <<
" " << m_bodyToSetTable[i];
8270 cerr <<
" m_noBodiesInSet: ";
8271 for(
MInt i = 0; i < m_maxNoSets; i++)
8272 cerr <<
" " << m_noBodiesInSet[i];
8274 cerr <<
" m_setToBodiesTable: ";
8275 for(
MInt i = 0; i < m_maxNoSets; i++) {
8276 cerr <<
"s" << i <<
": ";
8277 for(
MInt j = 0; j < m_noBodiesInSet[i]; j++)
8278 cerr <<
" " << m_setToBodiesTable[i][j];
8283 for(
MInt i = 0; i < m_maxNoSets; i++) {
8284 if(m_noBodiesInSet[i] > m_noBodyBndryCndIds)
mTerm(1, AT_, to_string(m_noBodiesInSet[i]));
8285 for(
MInt j = 0; j < m_noBodyBndryCndIds; j++) {
8286 if(m_setToBodiesTable[i][j] > m_noEmbeddedBodies)
mTerm(1, AT_, to_string(m_setToBodiesTable[i][j]));
8289 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
8290 if(m_bodyToSetTable[i] > m_noSets)
mTerm(1, AT_, to_string(m_bodyToSetTable[i]));
8317 ASSERT(!m_combustion && !m_freeSurface,
"");
8320 determinePeriodicDistance();
8325 MBool& first = m_static_computeBodyProperties_first;
8326 MFloat(&litude)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_amplitude;
8327 MFloat(&freqFactor)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_freqFactor;
8328 MFloat(&initialBodyCenter)[s_maxNoEmbeddedBodies * 3] = m_static_computeBodyProperties_initialBodyCenter;
8329 MFloat& Strouhal = m_static_computeBodyProperties_Strouhal;
8330 MFloat(&mu)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_mu;
8331 MFloat(&mu2)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_mu2;
8332 MFloat(&liftStartAngle1)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_liftStartAngle1;
8333 MFloat(&liftEndAngle1)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_liftEndAngle1;
8334 MFloat(&liftStartAngle2)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_liftStartAngle2;
8335 MFloat(&liftEndAngle2)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_liftEndAngle2;
8336 MFloat(&circleStartAngle)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_circleStartAngle;
8337 MFloat(&normal)[s_maxNoEmbeddedBodies * 3] = m_static_computeBodyProperties_normal;
8338 MInt(&bodyToFunction)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_bodyToFunction;
8339 MFloat& omega = m_static_computeBodyProperties_omega;
8340 MFloat& rotAngle = m_static_computeBodyProperties_rotAngle;
8341 MFloat(&temperature)[s_maxNoEmbeddedBodies] = m_static_computeBodyProperties_temperature;
8345 const MInt noEmbeddedBodies = m_noEmbeddedBodies;
8347 if(noEmbeddedBodies > s_maxNoEmbeddedBodies) {
8348 mTerm(1, AT_,
"Error in computeBodyProperties: too many embedded Bodies!");
8353 for(
MInt k = 0; k < s_maxNoEmbeddedBodies; k++) {
8355 freqFactor[k] = 1.0;
8356 bodyToFunction[k] = 1;
8357 for(
MInt i = 0; i < nDim; i++) {
8358 initialBodyCenter[k * nDim + i] = F0;
8359 normal[k * nDim + i] = F0;
8361 normal[k * nDim + 0] = 1.0;
8362 liftStartAngle1[k] = F0;
8363 liftEndAngle1[k] = PI;
8364 liftStartAngle2[k] = 3.0 * PI;
8365 liftEndAngle2[k] = 4.0 * PI;
8366 circleStartAngle[k] = F0;
8371 MFloat MaLb = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
8372 for(
MInt k = 0; k < s_maxNoEmbeddedBodies; k++) {
8373 amplitude[k] = MaLb * LBCS;
8391 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8392 amplitude[i] = Context::getSolverProperty<MFloat>(
"amplitudes", m_solverId, AT_, &litude[i], i);
8396 MFloat MaLb = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
8397 for(
MInt k = 0; k < s_maxNoEmbeddedBodies; k++) {
8398 amplitude[k] *= MaLb / F1BCS;
8414 for(
MInt i = 0; i < noEmbeddedBodies; i++)
8415 freqFactor[i] = Context::getSolverProperty<MFloat>(
"freqFactors", m_solverId, AT_, &freqFactor[i], i);
8429 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8431 Context::getSolverProperty<MInt>(
"bodyMovementFunctions", m_solverId, AT_, &bodyToFunction[i], i);
8433 Strouhal = Context::getSolverProperty<MFloat>(
"Strouhal", m_solverId, AT_, &Strouhal);
8445 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8446 for(
MInt j = 0; j < nDim; j++) {
8447 initialBodyCenter[i * nDim + j] = Context::getSolverProperty<MFloat>(
8448 "initialBodyCenters", m_solverId, AT_, &initialBodyCenter[i * nDim + j], i * nDim + j);
8452 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8453 for(
MInt j = 0; j < nDim; j++) {
8454 normal[i * nDim + j] = Context::getSolverProperty<MFloat>(
"bodyMotionNormals", m_solverId, AT_,
8455 &normal[i * nDim + j], i * nDim + j);
8471 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8472 liftStartAngle1[i] =
8473 Context::getSolverProperty<MFloat>(
"liftStartAngles1", m_solverId, AT_, &liftStartAngle1[i], i);
8488 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8489 liftStartAngle2[i] =
8490 Context::getSolverProperty<MFloat>(
"liftStartAngles2", m_solverId, AT_, &liftStartAngle2[i], i);
8503 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8504 liftEndAngle1[i] = Context::getSolverProperty<MFloat>(
"liftEndAngles1", m_solverId, AT_, &liftEndAngle1[i], i);
8517 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8518 liftEndAngle2[i] = Context::getSolverProperty<MFloat>(
"liftEndAngles2", m_solverId, AT_, &liftEndAngle2[i], i);
8532 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8533 circleStartAngle[i] =
8534 Context::getSolverProperty<MFloat>(
"circleStartAngles", m_solverId, AT_, &circleStartAngle[i], i);
8550 rotAngle = Context::getSolverProperty<MFloat>(
"rotAngle", m_solverId, AT_, &rotAngle);
8551 rotAngle *= -PI / 180;
8554 const MFloat freq0 = Strouhal * m_referenceVelocity;
8555 const MFloat freq02 = Strouhal;
8556 for(
MInt k = 0; k < noEmbeddedBodies; k++) {
8559 mu[k] = freqFactor[k] * freq0 * F2 * PI;
8560 mu2[k] = freqFactor[k] * freq02 * F2 * PI;
8564 MFloat MaLb = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
8565 const MFloat referenceLengthLb = Context::getSolverProperty<MFloat>(
"referenceLengthLB", m_solverId, AT_);
8566 const MFloat freq02Lb = Strouhal * MaLb * LBCS / referenceLengthLb;
8567 for(
MInt k = 0; k < noEmbeddedBodies; k++) {
8569 mu2[k] = freqFactor[k] * freq02Lb;
8574 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8575 if(bodyToFunction[i] == 6 || bodyToFunction[i] == 7) {
8576 liftStartAngle1[i] = liftStartAngle1[i] * PI;
8577 liftEndAngle1[i] = liftEndAngle1[i] * PI - liftStartAngle1[i];
8581 omega = freqFactor[body] * m_referenceVelocity * PI / (F2 * amplitude[body]);
8584 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8585 temperature[i] = Context::getSolverProperty<MFloat>(
"bodyTemperature", m_solverId, AT_, &temperature[i], i);
8590 MInt noControllFiles = 0;
8591 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8592 if(bodyToFunction[i] == 14) {
8597 if(noControllFiles > 0) {
8598 mAlloc(m_forcedMotionInput, noEmbeddedBodies,
"m_forcedMotionInput", AT_);
8599 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8600 m_forcedMotionInput[i].clear();
8605 for(
MInt i = 0; i < noEmbeddedBodies; i++) {
8606 if(bodyToFunction[i] == 14) {
8611 stringstream filename;
8614 filename <<
"forcedMotion_" << i <<
".txt";
8616 readFile.open(filename.str(), ios_base::in);
8619 mTerm(1, AT_,
"Error reading forced motion input file!");
8623 if((readFile.rdstate() & ifstream::eofbit) != 0) {
8630 m_forcedMotionInput[i].insert(make_pair(time, coord));
8641 if((m_levelSetMb && !m_levelSetLb) || m_levelSetFv) {
8642 if(returnMode == 4) {
8643 bodyData[0] = temperature[body];
8649 switch(bodyToFunction[body]) {
8652 angle = mu[body] * elapsedTime - liftStartAngle1[body];
8653 switch(returnMode) {
8655 if(angle > liftEndAngle1[body]) angle = liftEndAngle1[body];
8657 bodyData[0] = -amplitude[body] *
cos(angle);
8659 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8661 bodyData[0] = -amplitude[body];
8663 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8667 if((angle > 0 && angle < liftEndAngle1[body])) {
8668 bodyData[0] = mu[body] * amplitude[body] * sin(angle);
8670 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8674 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8678 if((angle > 0 && angle < liftEndAngle1[body])) {
8679 bodyData[0] = mu[body] * mu[body] * amplitude[body] *
cos(angle);
8681 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8685 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8691 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8698 angle = mu2[body] * elapsedTime;
8700 switch(returnMode) {
8702 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8703 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8704 bodyData[0] = amplitude[body] *
POW2(sin(mu2[body] * elapsedTime)) * normal[body * nDim + 0];
8705 bodyData[1] = amplitude[body] *
POW2(sin(mu2[body] * elapsedTime)) * normal[body * nDim + 1];
8706 IF_CONSTEXPR(nDim == 3) {
8707 bodyData[2] = amplitude[body] *
POW2(sin(mu2[body] * elapsedTime)) * normal[body * nDim + 2];
8712 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8716 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8717 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8718 bodyData[0] = amplitude[body] * mu2[body] * sin(2 * mu2[body] * elapsedTime) * normal[body * nDim + 0];
8719 bodyData[1] = amplitude[body] * mu2[body] * sin(2 * mu2[body] * elapsedTime) * normal[body * nDim + 1];
8720 IF_CONSTEXPR(nDim == 3) {
8721 bodyData[2] = amplitude[body] * mu2[body] * sin(2 * mu2[body] * elapsedTime) * normal[body * nDim + 2];
8726 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8730 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8731 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8732 bodyData[0] = 2 * amplitude[body] * mu2[body] * mu2[body] *
cos(2 * mu2[body] * elapsedTime)
8733 * normal[body * nDim + 0];
8734 bodyData[1] = 2 * amplitude[body] * mu2[body] * mu2[body] *
cos(2 * mu2[body] * elapsedTime)
8735 * normal[body * nDim + 1];
8736 IF_CONSTEXPR(nDim == 3) {
8737 bodyData[2] = 2 * amplitude[body] * mu2[body] * mu2[body] *
cos(2 * mu2[body] * elapsedTime)
8738 * normal[body * nDim + 2];
8741 bodyData[0] = 2 * amplitude[body] * mu2[body] * mu2[body] * normal[body * nDim + 0];
8742 bodyData[1] = 2 * amplitude[body] * mu2[body] * mu2[body] * normal[body * nDim + 1];
8743 IF_CONSTEXPR(nDim == 3) {
8744 bodyData[2] = 2 * amplitude[body] * mu2[body] * mu2[body] * normal[body * nDim + 2];
8751 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8759 angle = mu2[body] * elapsedTime;
8761 switch(returnMode) {
8763 if(elapsedTime > F0) {
8764 bodyData[0] = -amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 0];
8765 bodyData[1] = -amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 1];
8766 IF_CONSTEXPR(nDim == 3) {
8767 bodyData[2] = -amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 2];
8770 bodyData[0] = -amplitude[body] * normal[body * nDim + 0];
8771 bodyData[1] = -amplitude[body] * normal[body * nDim + 1];
8772 IF_CONSTEXPR(nDim == 3) { bodyData[2] = -amplitude[body] * normal[body * nDim + 2]; }
8776 if(elapsedTime > F0) {
8777 bodyData[0] = mu2[body] * amplitude[body] * sin(mu2[body] * elapsedTime) * normal[body * nDim + 0];
8778 bodyData[1] = mu2[body] * amplitude[body] * sin(mu2[body] * elapsedTime) * normal[body * nDim + 1];
8779 IF_CONSTEXPR(nDim == 3) {
8780 bodyData[2] = mu2[body] * amplitude[body] * sin(mu2[body] * elapsedTime) * normal[body * nDim + 2];
8785 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8789 if(elapsedTime > F0) {
8791 mu2[body] * mu2[body] * amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 0];
8793 mu2[body] * mu2[body] * amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 1];
8794 IF_CONSTEXPR(nDim == 3) {
8796 mu2[body] * mu2[body] * amplitude[body] *
cos(mu2[body] * elapsedTime) * normal[body * nDim + 2];
8801 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8807 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8815 angle = mu2[body] * elapsedTime;
8817 switch(returnMode) {
8819 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8820 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8821 bodyData[0] = amplitude[body] *
cos(angle) * normal[body * nDim + 0];
8822 bodyData[1] = amplitude[body] *
cos(angle) * normal[body * nDim + 1];
8823 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] *
cos(angle) * normal[body * nDim + 2]; }
8825 bodyData[0] = amplitude[body] * normal[body * nDim + 0];
8826 bodyData[1] = amplitude[body] * normal[body * nDim + 1];
8827 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] * normal[body * nDim + 2]; }
8831 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8832 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8833 bodyData[0] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 0];
8834 bodyData[1] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 1];
8835 IF_CONSTEXPR(nDim == 3) {
8836 bodyData[2] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 2];
8841 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8845 if((angle > liftStartAngle1[body] && angle <= liftEndAngle1[body])
8846 || (angle > liftStartAngle2[body] && angle <= liftEndAngle2[body])) {
8847 bodyData[0] = -mu2[body] * mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 0];
8848 bodyData[1] = -mu2[body] * mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 1];
8849 IF_CONSTEXPR(nDim == 3) {
8850 bodyData[2] = -mu2[body] * mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 2];
8855 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8861 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8871 angle = mu2[body] * elapsedTime + circleStartAngle[body];
8873 switch(returnMode) {
8875 if(elapsedTime > F0) {
8876 bodyData[0] = amplitude[body] *
cos(angle);
8877 bodyData[1] = amplitude[body] * sin(angle);
8878 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8880 bodyData[0] = amplitude[body] *
cos(circleStartAngle[body]);
8881 bodyData[1] = amplitude[body] * sin(circleStartAngle[body]);
8882 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8886 if(elapsedTime > F0) {
8887 bodyData[0] = -amplitude[body] * sin(angle);
8888 bodyData[1] = amplitude[body] *
cos(angle);
8889 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8893 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8897 if(elapsedTime > F0) {
8898 bodyData[0] = -amplitude[body] *
cos(angle);
8899 bodyData[1] = -amplitude[body] * sin(angle);
8900 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8904 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8910 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8917 angle = omega * elapsedTime - liftStartAngle1[body];
8918 if(angle > liftEndAngle1[body]) angle = F0;
8920 switch(returnMode) {
8922 if(elapsedTime > F0) {
8923 bodyData[0] = -amplitude[body] *
cos(angle) * normal[body * nDim + 0];
8924 bodyData[1] = -amplitude[body] *
cos(angle) * normal[body * nDim + 1];
8925 IF_CONSTEXPR(nDim == 3) { bodyData[2] = -amplitude[body] *
cos(angle) * normal[body * nDim + 2]; }
8927 bodyData[0] = -amplitude[body] * normal[body * nDim + 0];
8928 bodyData[1] = -amplitude[body] * normal[body * nDim + 1];
8929 IF_CONSTEXPR(nDim == 3) { bodyData[2] = -amplitude[body] * normal[body * nDim + 2]; }
8933 if(elapsedTime > F0) {
8934 bodyData[0] = omega * amplitude[body] * sin(angle) * normal[body * nDim + 0];
8935 bodyData[1] = omega * amplitude[body] * sin(angle) * normal[body * nDim + 1];
8936 IF_CONSTEXPR(nDim == 3) { bodyData[2] = omega * amplitude[body] * sin(angle) * normal[body * nDim + 2]; }
8940 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8944 if(elapsedTime > F0) {
8945 bodyData[0] = omega * omega * amplitude[body] *
cos(angle) * normal[body * nDim + 0];
8946 bodyData[1] = omega * omega * amplitude[body] *
cos(angle) * normal[body * nDim + 1];
8947 IF_CONSTEXPR(nDim == 3) {
8948 bodyData[2] = omega * omega * amplitude[body] *
cos(angle) * normal[body * nDim + 2];
8953 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8959 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8968 angle = omega * elapsedTime - liftStartAngle1[body];
8969 if(angle > liftEndAngle1[body]) angle = F0;
8971 switch(returnMode) {
8974 bodyData[0] = amplitude[body] *
POW2(sin(angle)) * normal[body * nDim + 0];
8975 bodyData[1] = amplitude[body] *
POW2(sin(angle)) * normal[body * nDim + 1];
8976 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] *
POW2(sin(angle)) * normal[body * nDim + 2]; }
8980 IF_CONSTEXPR(nDim == 3) bodyData[2] = 0;
8985 bodyData[0] = amplitude[body] * omega * sin(2 * angle) * normal[body * nDim + 0];
8986 bodyData[1] = amplitude[body] * omega * sin(2 * angle) * normal[body * nDim + 1];
8987 IF_CONSTEXPR(nDim == 3) {
8988 bodyData[2] = amplitude[body] * omega * sin(2 * angle) * normal[body * nDim + 2];
8993 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
8998 bodyData[0] = 2 * amplitude[body] * omega * omega *
cos(2 * angle) * normal[body * nDim + 0];
8999 bodyData[1] = 2 * amplitude[body] * omega * omega *
cos(2 * angle) * normal[body * nDim + 1];
9000 IF_CONSTEXPR(nDim == 3) {
9001 bodyData[2] = 2 * amplitude[body] * omega * omega *
cos(2 * angle) * normal[body * nDim + 2];
9004 bodyData[0] = 2 * amplitude[body] * omega * omega * normal[body * nDim + 0];
9005 bodyData[1] = 2 * amplitude[body] * omega * omega * normal[body * nDim + 1];
9006 IF_CONSTEXPR(nDim == 3) { bodyData[2] = 2 * amplitude[body] * omega * omega * normal[body * nDim + 2]; }
9012 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9022 switch(returnMode) {
9024 bodyData[0] = amplitude[body] * m_referenceVelocity * elapsedTime * normal[body * nDim + 0];
9025 bodyData[1] = amplitude[body] * m_referenceVelocity * elapsedTime * normal[body * nDim + 1];
9026 IF_CONSTEXPR(nDim == 3) {
9027 bodyData[2] = amplitude[body] * m_referenceVelocity * elapsedTime * normal[body * nDim + 2];
9031 bodyData[0] = amplitude[body] * m_referenceVelocity * normal[body * nDim + 0];
9032 bodyData[1] = amplitude[body] * m_referenceVelocity * normal[body * nDim + 1];
9033 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] * m_referenceVelocity * normal[body * nDim + 2]; }
9038 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9044 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9051 angle = mu2[body] * elapsedTime;
9053 switch(returnMode) {
9055 if(angle >= liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9056 bodyData[0] = amplitude[body] * sin(angle) * normal[body * nDim + 0];
9057 bodyData[1] = amplitude[body] * sin(angle) * normal[body * nDim + 1];
9058 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] * sin(angle) * normal[body * nDim + 2]; }
9059 }
else if(angle < liftStartAngle1[body]) {
9062 IF_CONSTEXPR(nDim == 3) bodyData[2] = 0;
9063 } else if(angle > liftEndAngle1[body]) {
9064 bodyData[0] = amplitude[body] * sin(liftEndAngle1[body]) * normal[body * nDim + 0];
9065 bodyData[1] = amplitude[body] * sin(liftEndAngle1[body]) * normal[body * nDim + 1];
9066 IF_CONSTEXPR(nDim == 3) {
9067 bodyData[2] = amplitude[body] * sin(liftEndAngle1[body]) * normal[body * nDim + 2];
9072 if(angle > liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9073 bodyData[0] = mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 0];
9074 bodyData[1] = mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 1];
9075 IF_CONSTEXPR(nDim == 3) {
9076 bodyData[2] = mu2[body] * amplitude[body] *
cos(angle) * normal[body * nDim + 2];
9081 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9085 if(angle > liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9086 bodyData[0] = -mu2[body] * mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 0];
9087 bodyData[1] = -mu2[body] * mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 1];
9088 IF_CONSTEXPR(nDim == 3) {
9089 bodyData[2] = -mu2[body] * mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 2];
9094 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9100 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9114 const MFloat l = liftStartAngle1[body];
9115 const MFloat TDC = liftEndAngle1[body];
9116 const MFloat r = amplitude[body];
9120 switch(returnMode) {
9123 normal[body * nDim + 0] * (l + r + TDC - (r *
cos(phi) + sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi)))));
9125 normal[body * nDim + 1] * (l + r + TDC - (r *
cos(phi) + sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi)))));
9126 IF_CONSTEXPR(nDim == 3) {
9128 normal[body * nDim + 2] * (l + r + TDC - (r *
cos(phi) + sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi)))));
9131 if(domainId() == 0 && printPosition) {
9133 cerr <<
"Crank-angle-degree : " << cad << endl;
9134 if((cad / 45) > 0.989 && (cad / 45) < 1.01) {
9135 cerr <<
"Physical-Time : " << time() << endl;
9136 cerr <<
" " << time() * 0.002898783653689 << endl;
9138 cerr <<
"Piston-position : "
9139 << (l + r + TDC - (r *
cos(phi) + sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi))))) <<
" in m "
9140 << bodyData[1] * 0.075 << endl;
9141 cerr <<
"Piston-velocity : "
9151 normal[body * nDim + 0] * mu2[body]
9152 * (r * sin(phi) + (
POW2(r) * sin(phi) *
cos(phi) / (sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi))))));
9155 normal[body * nDim + 1] * mu2[body]
9156 * (r * sin(phi) + (
POW2(r) * sin(phi) *
cos(phi) / (sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi))))));
9157 IF_CONSTEXPR(nDim == 3) {
9159 normal[body * nDim + 2] * mu2[body]
9160 * (r * sin(phi) + (
POW2(r) * sin(phi) *
cos(phi) / (sqrt(
POW2(l) -
POW2(r) *
POW2(sin(phi))))));
9165 normal[body * nDim + 0] * mu2[body] * mu2[body]
9170 normal[body * nDim + 1] * mu2[body] * mu2[body]
9174 IF_CONSTEXPR(nDim == 3) {
9176 normal[body * nDim + 2] * mu2[body] * mu2[body]
9185 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9201 MFloat IO = liftStartAngle1[body];
9202 MFloat IC = liftEndAngle1[body];
9203 MFloat EO = liftStartAngle2[body];
9204 MFloat EC = liftEndAngle2[body];
9212 switch(returnMode) {
9217 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9218 } else if(cad >= 0 && cad < IC) {
9219 MFloat phi_i = (cad - IO) * PI / 180;
9220 MFloat delta_i = (IC - IO) * PI / 180;
9221 MFloat freq_i = 1 / (delta_i / 2 / PI);
9224 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq_i * phi_i - phase));
9225 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq_i * phi_i - phase));
9226 IF_CONSTEXPR(nDim == 3) {
9227 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq_i * phi_i - phase));
9230 }
else if(cad > IC && cad < EO) {
9233 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9234 } else if(cad >= EO && cad < EC) {
9235 MFloat phi_e = (cad - EO) * PI / 180;
9236 MFloat delta_e = (EC - EO) * PI / 180;
9237 MFloat freq_e = 1 / (delta_e / 2 / PI);
9240 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq_e * phi_e - phase));
9241 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq_e * phi_e - phase));
9242 IF_CONSTEXPR(nDim == 3) {
9243 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq_e * phi_e - phase));
9246 }
else if(cad >= EC) {
9249 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9251 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9254 if(domainId() == 0 && printPosition) {
9255 cerr <<
"Crank-angle-degree : " << cad << endl;
9256 cerr <<
"Valve-position : " << bodyData[0] <<
" in mm" << bodyData[0] * 75 << endl;
9264 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9265 } else if(cad >= 0 && cad < IC) {
9266 MFloat phi_i = (cad - IO) * PI / 180;
9267 MFloat delta_i = (IC - IO) * PI / 180;
9268 MFloat freq_i = 1 / (delta_i / 2 / PI);
9272 -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq_i *
cos(freq_i * phi_i - phase);
9274 -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq_i *
cos(freq_i * phi_i - phase);
9275 IF_CONSTEXPR(nDim == 3) {
9277 -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq_i *
cos(freq_i * phi_i - phase);
9280 }
else if(cad > IC && cad < EO) {
9283 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9284 } else if(cad >= EO && cad < EC) {
9285 MFloat phi_e = (cad - EO) * PI / 180;
9286 MFloat delta_e = (EC - EO) * PI / 180;
9287 MFloat freq_e = 1 / (delta_e / 2 / PI);
9291 -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq_e *
cos(freq_e * phi_e - phase);
9293 -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq_e *
cos(freq_e * phi_e - phase);
9294 IF_CONSTEXPR(nDim == 3) {
9296 -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq_e *
cos(freq_e * phi_e - phase);
9298 }
else if(cad >= EC) {
9301 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9303 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9306 if(domainId() == 0 && printPosition) {
9307 cerr <<
"Valve-velocity : " << bodyData[0] << endl;
9315 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9316 } else if(cad >= 0 && cad < IC) {
9317 MFloat phi_i = (cad - IO) * PI / 180;
9318 MFloat delta_i = (IC - IO) * PI / 180;
9319 MFloat freq_i = 1 / (delta_i / 2 / PI);
9322 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_i)
9323 * sin(freq_i * phi_i - phase);
9324 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_i)
9325 * sin(freq_i * phi_i - phase);
9326 IF_CONSTEXPR(nDim == 3) {
9327 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_i)
9328 * sin(freq_i * phi_i - phase);
9331 }
else if(cad > IC && cad < EO) {
9334 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9335 } else if(cad >= EO && cad < EC) {
9336 MFloat phi_e = (cad - EO) * PI / 180;
9337 MFloat delta_e = (EC - EO) * PI / 180;
9338 MFloat freq_e = 1 / (delta_e / 2 / PI);
9341 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_e)
9342 * sin(freq_e * phi_e - phase);
9343 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_e)
9344 * sin(freq_e * phi_e - phase);
9345 IF_CONSTEXPR(nDim == 3) {
9346 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq_e)
9347 * sin(freq_e * phi_e - phase);
9349 }
else if(cad > EC) {
9352 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9354 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9360 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9375 MFloat scaleToMeter = 0.075;
9379 MFloat IO = liftStartAngle1[body];
9380 MFloat IC = liftEndAngle1[body];
9391 switch(returnMode) {
9396 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9397 } else if(cad >= IO && cad <= IC) {
9398 phi = (cad - IO) * PI / 180;
9399 delta = (IC - IO) * PI / 180;
9400 freq = 1 / (delta / 2 / PI);
9403 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq * phi - phase));
9404 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq * phi - phase));
9405 IF_CONSTEXPR(nDim == 3) {
9406 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq * phi - phase));
9409 }
else if(cad >= 720 + IO) {
9410 phi = (cad - (720 + IO)) * PI / 180;
9411 delta = (IC - IO) * PI / 180;
9412 freq = 1 / (delta / 2 / PI);
9415 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq * phi - phase));
9416 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq * phi - phase));
9417 IF_CONSTEXPR(nDim == 3) {
9418 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq * phi - phase));
9421 }
else if(cad >= IC && cad < 720 + IO) {
9424 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9426 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9429 if(domainId() == 0 && printPosition) {
9430 cerr <<
"Crank-angle-degree : " << cad << endl;
9431 cerr <<
"dimensionless-Inlet-Valve-position : " << amplitude[body] * (1 - sin(freq * phi - phase))
9433 cerr <<
"dimensional-Inlet-Valve-position : "
9434 << amplitude[body] * (1 - sin(freq * phi - phase)) * scaleToMeter <<
" in m " << endl;
9435 cerr <<
"dimensionless-Inlet-Valve-velocity : "
9436 << -amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase) << endl;
9444 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9445 } else if(cad >= IO && cad <= IC) {
9446 phi = (cad - IO) * PI / 180;
9447 delta = (IC - IO) * PI / 180;
9448 freq = 1 / (delta / 2 / PI);
9451 bodyData[0] = -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9452 bodyData[1] = -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9453 IF_CONSTEXPR(nDim == 3) {
9454 bodyData[2] = -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9457 }
else if(cad >= 720 + IO) {
9458 phi = (cad - (720 + IO)) * PI / 180;
9459 delta = (IC - IO) * PI / 180;
9460 freq = 1 / (delta / 2 / PI);
9463 bodyData[0] = -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9464 bodyData[1] = -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9465 IF_CONSTEXPR(nDim == 3) {
9466 bodyData[2] = -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9469 }
else if(cad >= IC && cad < 720 + IO) {
9472 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9474 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9482 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9483 } else if(cad >= IO && cad <= IC) {
9484 phi = (cad - IO) * PI / 180;
9485 delta = (IC - IO) * PI / 180;
9486 freq = 1 / (delta / 2 / PI);
9489 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9490 * sin(freq * phi - phase);
9491 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9492 * sin(freq * phi - phase);
9493 IF_CONSTEXPR(nDim == 3) {
9494 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9495 * sin(freq * phi - phase);
9498 }
else if(cad >= 720 + IO) {
9499 phi = (cad - (720 + IO)) * PI / 180;
9500 delta = (IC - IO) * PI / 180;
9501 freq = 1 / (delta / 2 / PI);
9504 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9505 * sin(freq * phi - phase);
9506 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9507 * sin(freq * phi - phase);
9508 IF_CONSTEXPR(nDim == 3) {
9509 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9510 * sin(freq * phi - phase);
9513 }
else if(cad >= IC && cad < 720 + IO) {
9516 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9518 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9524 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9540 MFloat EO = liftStartAngle1[body];
9541 MFloat EC = liftEndAngle1[body];
9542 MFloat scaleToMeter = 0.075;
9553 switch(returnMode) {
9555 if(cad < EO && cad >= EC) {
9558 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9559 } else if(cad >= EO && cad < 720) {
9560 phi = (cad - EO) * PI / 180;
9561 delta = (720 + EC - EO) * PI / 180;
9562 freq = 1 / (delta / 2 / PI);
9565 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq * phi - phase));
9566 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq * phi - phase));
9567 IF_CONSTEXPR(nDim == 3) {
9568 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq * phi - phase));
9571 }
else if(cad < EC) {
9572 phi = -(EC - cad) * PI / 180;
9573 delta = (720 + EC - EO) * PI / 180;
9574 freq = 1 / (delta / 2 / PI);
9577 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * (1 - sin(freq * phi - phase));
9578 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * (1 - sin(freq * phi - phase));
9579 IF_CONSTEXPR(nDim == 3) {
9580 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * (1 - sin(freq * phi - phase));
9584 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9587 if(domainId() == 0 && printPosition) {
9588 cerr <<
"Crank-angle-degree : " << cad << endl;
9589 cerr <<
"dimensionless-Outlet-Valve-position : " << amplitude[body] * (1 - sin(freq * phi - phase))
9591 cerr <<
"dimensional-Outlet-Valve-position : "
9592 << amplitude[body] * (1 - sin(freq * phi - phase)) * scaleToMeter <<
" in m " << endl;
9593 cerr <<
"dimensionless-Outlet-Valve-velocity : "
9594 << -amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase) << endl;
9599 if(cad < EO && cad >= EC) {
9602 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9603 } else if(cad >= EO && cad < 720) {
9604 phi = (cad - EO) * PI / 180;
9605 delta = (720 + EC - EO) * PI / 180;
9606 freq = 1 / (delta / 2 / PI);
9609 bodyData[0] = -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9610 bodyData[1] = -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9611 IF_CONSTEXPR(nDim == 3) {
9612 bodyData[2] = -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9616 }
else if(cad < EC) {
9617 phi = -(EC - cad) * PI / 180;
9618 delta = (720 + EC - EO) * PI / 180;
9619 freq = 1 / (delta / 2 / PI);
9622 bodyData[0] = -normal[body * nDim + 0] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9623 bodyData[1] = -normal[body * nDim + 1] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9624 IF_CONSTEXPR(nDim == 3) {
9625 bodyData[2] = -normal[body * nDim + 2] * amplitude[body] * mu2[body] * freq *
cos(freq * phi - phase);
9628 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9633 if(cad < EO && cad >= EC) {
9636 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9637 } else if(cad >= EO && cad < 720) {
9638 phi = (cad - EO) * PI / 180;
9639 delta = (720 + EC - EO) * PI / 180;
9640 freq = 1 / (delta / 2 / PI);
9643 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9644 * sin(freq * phi - phase);
9645 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9646 * sin(freq * phi - phase);
9647 IF_CONSTEXPR(nDim == 3) {
9648 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9649 * sin(freq * phi - phase);
9652 }
else if(cad < EC) {
9653 phi = -(EC - cad) * PI / 180;
9654 delta = (720 + EC - EO) * PI / 180;
9655 freq = 1 / (delta / 2 / PI);
9658 bodyData[0] = normal[body * nDim + 0] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9659 * sin(freq * phi - phase);
9660 bodyData[1] = normal[body * nDim + 1] * amplitude[body] * mu2[body] * mu2[body] *
POW2(freq)
9661 * sin(freq * phi - phase);
9662 IF_CONSTEXPR(nDim == 3) {
9663 bodyData[2] = normal[body * nDim + 2] * amplitude[body] * mu2[body] * mu2[body]
9664 * (1 +
POW2(freq) * sin(freq * phi - phase));
9667 mTerm(1, AT_,
"Unexpected crank-angle-degree!");
9673 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9683 auto upperIt = upper_bound(m_forcedMotionInput[body].begin(), m_forcedMotionInput[body].end(),
9684 make_pair(elapsedTime, -999999.9));
9686 auto lowerIt = next(upperIt, -1);
9689 const MFloat pos = (*lowerIt).second
9690 + (elapsedTime - (*lowerIt).first) * ((*upperIt).second - (*lowerIt).second)
9691 / ((*upperIt).first - (*lowerIt).first);
9694 if(domainId() == 0 && returnMode == 1 && printPosition) {
9695 cerr <<
globalTimeStep <<
" body " << body <<
" time " << elapsedTime <<
" earlier " << (*lowerIt).first
9696 <<
" later " << (*upperIt).first <<
" earlier Pos " << (*lowerIt).second <<
" later Pos "
9697 << (*upperIt).second <<
" interp. Pos " << pos << endl;
9701 switch(returnMode) {
9704 bodyData[0] = normal[body * nDim + 0] * pos;
9705 bodyData[1] = normal[body * nDim + 1] * pos;
9706 IF_CONSTEXPR(nDim == 3) { bodyData[2] = normal[body * nDim + 2] * pos; }
9712 MFloat prevTime = elapsedTime - timeStep();
9714 upperIt = upper_bound(m_forcedMotionInput[body].begin(), m_forcedMotionInput[body].end(),
9715 make_pair(prevTime, -999999.9));
9716 lowerIt = next(upperIt, -1);
9718 const MFloat prevPos = (*lowerIt).second
9719 + (prevTime - (*lowerIt).first) * ((*upperIt).second - (*lowerIt).second)
9720 / ((*upperIt).first - (*lowerIt).first);
9721 MFloat vel = (pos - prevPos) / timeStep();
9724 bodyData[0] = normal[body * nDim + 0] * vel;
9725 bodyData[1] = normal[body * nDim + 1] * vel;
9726 IF_CONSTEXPR(nDim == 3) { bodyData[2] = normal[body * nDim + 2] * vel; }
9733 MFloat prevTime = elapsedTime - timeStep();
9737 upperIt = upper_bound(m_forcedMotionInput[body].begin(), m_forcedMotionInput[body].end(),
9738 make_pair(prevTime, -999999.9));
9739 lowerIt = next(upperIt, -1);
9741 const MFloat prevPos = (*lowerIt).second
9742 + (prevTime - (*lowerIt).first) * ((*upperIt).second - (*lowerIt).second)
9743 / ((*upperIt).first - (*lowerIt).first);
9746 MFloat olderTime = elapsedTime - 2 * timeStep();
9748 upperIt = upper_bound(m_forcedMotionInput[body].begin(), m_forcedMotionInput[body].end(),
9749 make_pair(olderTime, -999999.9));
9750 lowerIt = next(upperIt, -1);
9753 const MFloat olderPos = (*lowerIt).second
9754 + (olderTime - (*lowerIt).first) * ((*upperIt).second - (*lowerIt).second)
9755 / ((*upperIt).first - (*lowerIt).first);
9756 MFloat a = (pos - 2 * prevPos + olderPos) / (timeStep() * timeStep());
9759 bodyData[0] = normal[body * nDim + 0] *
a;
9760 bodyData[1] = normal[body * nDim + 1] *
a;
9761 IF_CONSTEXPR(nDim == 3) { bodyData[2] = normal[body * nDim + 2] *
a; }
9768 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9774 mTerm(1, AT_, "function type not implemented. Please check bodyMovementFunctions property!");
9778 if(returnMode == 1) {
9779 for(
MInt dir = 0; dir < nDim; dir++) {
9780 bodyData[dir] += initialBodyCenter[body * nDim + dir];
9785 if(rotAngle > 0 || rotAngle < 0) {
9786 MFloat tmp0 = bodyData[0] *
cos(rotAngle) + bodyData[1] * sin(rotAngle);
9787 MFloat tmp1 = bodyData[1] *
cos(rotAngle) - bodyData[0] * sin(rotAngle);
9790 bodyData[2] = bodyData[2];
9792 if(m_periodicMovement) {
9793 MFloat bodyTempData = bodyData[m_periodicDirection];
9794 bodyData[m_periodicDirection] =
9795 std::fmod(bodyTempData + initialBodyCenter[body * nDim + m_periodicDirection] + 0.5 * m_periodicDistance,
9797 - 0.5 * m_periodicDistance - initialBodyCenter[body * nDim + m_periodicDirection];
9799 }
else if(m_levelSetLb) {
9800 switch(bodyToFunction[body]) {
9803 angle = c_cellLengthAtLevel(maxLevel());
9804 switch(returnMode) {
9806 bodyData[0] = amplitude[body] * angle * elapsedTime * normal[body * nDim + 0];
9807 bodyData[1] = amplitude[body] * angle * elapsedTime * normal[body * nDim + 1];
9808 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] * angle * elapsedTime * normal[body * nDim + 2]; }
9811 bodyData[0] = amplitude[body] * normal[body * nDim + 0];
9812 bodyData[1] = amplitude[body] * normal[body * nDim + 1];
9813 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] * normal[body * nDim + 2]; }
9818 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9824 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9831 angle = freqFactor[body] * mu2[body] * elapsedTime + liftStartAngle1[body];
9832 switch(returnMode) {
9834 if(angle >= liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9836 amplitude[body] * c_cellLengthAtLevel(maxLevel()) / mu2[body] * sin(angle) * normal[body * nDim + 0];
9838 amplitude[body] * c_cellLengthAtLevel(maxLevel()) / mu2[body] * sin(angle) * normal[body * nDim + 1];
9839 IF_CONSTEXPR(nDim == 3) {
9840 bodyData[2] = amplitude[body] * c_cellLengthAtLevel(maxLevel()) / mu2[body] * sin(angle)
9841 * normal[body * nDim + 2];
9843 }
else if(angle < liftStartAngle1[body]) {
9846 IF_CONSTEXPR(nDim == 3) bodyData[2] = 0;
9847 } else if(angle > liftEndAngle1[body]) {
9850 IF_CONSTEXPR(nDim == 3) bodyData[2] = 0;
9854 if(angle > liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9855 bodyData[0] = amplitude[body] *
cos(angle) * normal[body * nDim + 0];
9856 bodyData[1] = amplitude[body] *
cos(angle) * normal[body * nDim + 1];
9857 IF_CONSTEXPR(nDim == 3) { bodyData[2] = amplitude[body] *
cos(angle) * normal[body * nDim + 2]; }
9861 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9865 if(angle > liftStartAngle1[body] && angle <= liftEndAngle1[body]) {
9866 bodyData[0] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 0];
9867 bodyData[1] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 1];
9868 IF_CONSTEXPR(nDim == 3) {
9869 bodyData[2] = -mu2[body] * amplitude[body] * sin(angle) * normal[body * nDim + 2];
9874 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9880 IF_CONSTEXPR(nDim == 3) bodyData[2] = F0;
9886 if(!m_virtualSurgery) {
9887 TERMM(1,
"This mode cannot be used without the m_virtualSurgery flag!");
9889 switch(returnMode) {
9896 MIntScratchSpace noTimeSteps(m_noInterpolationRegions, AT_,
"noTimeSteps");
9899 for(
MInt r = 0; r < m_noInterpolationRegions; r++) {
9900 if(r >= m_approxNoInterpReg) {
9901 startTime(r) = m_interpStartTime[m_approxNoInterpReg - 1];
9902 noTimeSteps(r) = m_noInterpTimeSteps[m_approxNoInterpReg - 1];
9904 startTime(r) = m_interpStartTime[r];
9905 noTimeSteps(r) = m_noInterpTimeSteps[r];
9910 for(
MInt r = 0; r < m_noInterpolationRegions; r++) {
9911 timeStep(r) =
mMin(timeStep(r), noTimeSteps(r));
9912 alpha(r) = (F1 * timeStep(r)) / (F1 * noTimeSteps(r));
9915 if(domainId() == 0) {
9917 for(
MInt r = 0; r < m_noInterpolationRegions; r++) {
9918 cout <<
"For region " << r <<
": startTime = " << startTime(r) <<
", timeStep = " << timeStep(r)
9919 <<
", alpha = " << alpha(r) << endl;
9924 for(
MInt i = 0; i < a_noCells(); i++) {
9926 MInt regions =
mMax(0, m_cellIsInDiffRegion[cellId]);
9927 MFloat phi1 = m_correctedDistances[i][0];
9928 MFloat phi2 = m_correctedDistances[i][1];
9929 a_levelSetFunctionG(cellId, 0) = phi1 * (F1 - alpha(regions)) + phi2 * alpha(regions);
9955 if(nDim == 3) bodyData[2] = F0;
9961 mTerm(1, AT_,
"function type not implemented. Please check bodyMovementFunctions property!");
9965 if(returnMode == 1) {
9966 for(
MInt dir = 0; dir < nDim; dir++) {
9967 bodyData[dir] += initialBodyCenter[body * nDim + dir];
9972 if(rotAngle > 0 || rotAngle < 0) {
9973 MFloat tmp0 = bodyData[0] *
cos(rotAngle) + bodyData[1] * sin(rotAngle);
9974 MFloat tmp1 = bodyData[1] *
cos(rotAngle) - bodyData[0] * sin(rotAngle);
9977 bodyData[2] = bodyData[2];
10002 MBool& first = m_static_identifyBodies_first;
10003 MFloat(&initialInsidePoints)[s_maxNoEmbeddedBodies * 3] = m_static_identifyBodies_initialInsidePoints;
10005 MFloat& shiftTime = m_static_identifyBodies_shiftTime;
10010 if(m_noBodyBndryCndIds > s_maxNoEmbeddedBodies) {
10011 mTerm(1, AT_,
"Error in LsCartesianSolver<nDim>::identifyBodies. Too many embedded Bodies!");
10015 for(
MInt k = 0; k < s_maxNoEmbeddedBodies; k++) {
10016 for(
MInt i = 0; i < nDim; i++) {
10017 initialInsidePoints[k * nDim + i] = F0;
10030 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
10031 for(
MInt j = 0; j < nDim; j++) {
10032 initialInsidePoints[i * nDim + j] = Context::getSolverProperty<MFloat>(
10033 "initialInsidePoints", m_solverId, AT_, &initialInsidePoints[i * nDim + j], i * nDim + j);
10045 +
"; m_restartTimeStep = " + std::to_string(m_restartTimeStep));
10046 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
10047 for(
MInt j = 0; j < nDim; j++) {
10048 initialInsidePoints[i * nDim + j] =
10049 initialInsidePoints[i * nDim + j] + m_semiLagrange_xShift_ref[j * m_noEmbeddedBodies + i];
10057 MFloat elapsedTime = time();
10060 if(m_startSet > 0) {
10061 for(
MInt gCellId = 0; gCellId < a_noCells(); gCellId++) {
10062 a_bodyIdG(gCellId, 0) = -1;
10068 if(first || mode == 0 || !m_semiLagrange) {
10069 stack<MInt> bodyStack;
10073 for(
MInt set = m_startSet; set < m_noSets; set++) {
10074 if(!m_computeSet[set] && !m_maxLevelChange)
continue;
10075 if(!m_changedSet[set] && m_levelSetMb)
continue;
10078 for(
MInt gCellId = 0; gCellId < a_noCells(); gCellId++) {
10079 a_bodyIdG(gCellId, set) = -1;
10082 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
10083 const MInt body = m_setToBodiesTable[set][
b];
10084 MFloat bodyCenter[3] = {F0, F0, F0};
10085 computeBodyPropertiesForced(1, bodyCenter, body, time());
10086 for(
MInt i = 0; i < nDim; i++) {
10087 bodyCenter[i] += initialInsidePoints[body * nDim + i];
10091 std::array<MFloat, nDim> rotCenter{};
10092 std::array<MFloat, nDim> bodyCenter_shift{};
10093 std::array<MFloat, nDim> rotAngle{};
10094 std::copy_n(&bodyCenter[0], nDim, &bodyCenter_shift[0]);
10095 std::copy_n(&m_semiLagrange_xRot_STL[body * nDim], nDim, &rotAngle[0]);
10096 for(
MInt d = 0; d < nDim; d++) {
10097 rotAngle[d] *= -F1;
10099 computeBodyPropertiesForced(1, rotCenter.data(), body, 0.0);
10100 rotateLevelSet(1, bodyCenter, body, bodyCenter_shift.data(), rotCenter.data(), &rotAngle[0]);
10101 if(grid().azimuthalPeriodicity()) {
10102 MFloat center = grid().azimuthalCenter();
10103 MFloat angle = grid().azimuthalAngle();
10104 grid().raw().cartesianToCylindric(bodyCenter, bodyCenter_shift.data());
10106 if(bodyCenter_shift[1] > (center + F1B2 * angle)) {
10107 fac = (
MInt)((bodyCenter_shift[1] - (center - F1B2 * angle)) / angle);
10108 }
else if(bodyCenter_shift[1] < (center - F1B2 * angle)) {
10109 fac = (
MInt)((bodyCenter_shift[1] - (center + F1B2 * angle)) / angle);
10111 grid().raw().rotateCartesianCoordinates(bodyCenter, fac * angle);
10115 const MInt startCellId = getContainingCell(bodyCenter);
10117 if(startCellId > -1 && startCellId < a_noCells()) {
10118 bodyStack.push(startCellId);
10120 MInt cellsAdded = 1;
10122 while(cellsAdded) {
10125 while(!bodyStack.empty()) {
10126 const MInt currentCell = bodyStack.top();
10128 if(a_bodyIdG(currentCell, set) > -1)
continue;
10129 if(c_noChildren(currentCell) > 0 && !a_isHalo(currentCell)) {
10130 for(
MInt child = 0; child < c_noChildren(currentCell); child++) {
10131 const MInt childId = c_childId(currentCell, child);
10132 if(childId < 0)
continue;
10133 if(a_isHalo(childId))
continue;
10134 if(a_level(childId) == a_maxGCellLevel(set) && !a_isGZeroCell(childId, set)
10135 && a_levelSetFunctionG(childId, set) * ((
MFloat)m_levelSetSign[set]) >= 0)
10137 bodyStack.push(childId);
10141 a_bodyIdG(currentCell, set) = body;
10143 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10144 if(!a_hasNeighbor(currentCell, dir))
continue;
10145 const MInt nghbrId = c_neighborId(currentCell, dir);
10146 if(a_isHalo(nghbrId))
continue;
10147 if(a_bodyIdG(nghbrId, set) > -1)
continue;
10148 if(!a_isGZeroCell(nghbrId, set) && a_levelSetFunctionG(nghbrId, set) * ((
MFloat)m_levelSetSign[set]) >= 0)
10150 bodyStack.push(nghbrId);
10155 MPI_Allreduce(MPI_IN_PLACE, &cellsAdded, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"cellsAdded");
10158 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10159 for(
MInt j = 0; j < noWindowCells(i); j++) {
10160 tmp_data(windowCellId(i, j)) = a_bodyIdG(windowCellId(i, j), set);
10163 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10164 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
10165 MInt windowId = grid().azimuthalWindowCell(i, j);
10166 tmp_data(windowId) = a_bodyIdG(windowId, set);
10170 exchangeDataLS(&tmp_data(0), 1);
10172 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10173 for(
MInt j = 0; j < noHaloCells(i); j++) {
10174 const MInt haloCell = haloCellId(i, j);
10175 if(a_bodyIdG(haloCell, set) < 0) {
10176 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10177 if(a_bodyIdG(haloCell, set) > -1) {
10178 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10179 if(!a_hasNeighbor(haloCell, dir))
continue;
10180 MInt nghbrId = c_neighborId(haloCell, dir);
10181 if(a_isHalo(nghbrId))
continue;
10182 if(a_bodyIdG(nghbrId, set) > -1)
continue;
10183 if(!a_isGZeroCell(nghbrId, set)
10184 && a_levelSetFunctionG(nghbrId, set) * ((
MFloat)m_levelSetSign[set]) >= 0)
10186 bodyStack.push(nghbrId);
10192 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10193 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
10194 const MInt haloCell = grid().azimuthalHaloCell(i, j);
10195 if(a_bodyIdG(haloCell, set) < 0) {
10196 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10197 if(a_bodyIdG(haloCell, set) > -1) {
10198 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10199 if(!a_hasNeighbor(haloCell, dir)) {
10202 MInt nghbrId = c_neighborId(haloCell, dir);
10203 if(a_isHalo(nghbrId)) {
10206 if(a_bodyIdG(nghbrId, set) > -1) {
10209 if(!a_isGZeroCell(nghbrId, set)
10210 && a_levelSetFunctionG(nghbrId, set) * ((
MFloat)m_levelSetSign[set]) >= 0) {
10213 bodyStack.push(nghbrId);
10225 MInt layerCount = 1;
10232 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
10234 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10235 const MInt nghbrId = c_neighborId(cellId, dir);
10236 if(nghbrId == -1)
continue;
10237 if(a_isGZeroCell(nghbrId, set))
continue;
10238 if(maxLevel() > minLevel()) {
10239 ASSERT(a_bodyIdG(nghbrId, set) == -1 || a_bodyIdG(nghbrId, set) == a_bodyIdG(cellId, set),
10240 "Overlapping bodies in the same set not possible: gather bodies "
10241 + to_string(a_bodyIdG(nghbrId, set)) +
" " + to_string(a_bodyIdG(cellId, set))
10242 +
"in different sets! ");
10244 lastLayer.p[cnt++] = nghbrId;
10245 a_bodyIdG(nghbrId, set) = a_bodyIdG(cellId, set);
10250 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10251 for(
MInt j = 0; j < noWindowCells(i); j++) {
10252 tmp_data(windowCellId(i, j)) = a_bodyIdG(windowCellId(i, j), set);
10255 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10256 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
10257 MInt windowId = grid().azimuthalWindowCell(i, j);
10258 tmp_data(windowId) = a_bodyIdG(windowId, set);
10262 exchangeDataLS(&tmp_data(0), 1);
10264 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10265 for(
MInt j = 0; j < noHaloCells(i); j++) {
10266 const MInt haloCell = haloCellId(i, j);
10267 if(a_bodyIdG(haloCell, set) < 0) {
10268 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10269 if(a_bodyIdG(haloCell, set) > -1) {
10270 lastLayer.p[cnt++] = haloCell;
10275 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10276 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
10277 const MInt haloCell = grid().azimuthalHaloCell(i, j);
10278 if(a_bodyIdG(haloCell, set) < 0) {
10279 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10280 if(a_bodyIdG(haloCell, set) > -1) {
10281 lastLayer.p[cnt++] = haloCell;
10290 while(layerCount < m_gBandWidth + 1) {
10292 for(
MInt c = 0; c < cnt; c++) {
10293 if(a_bodyIdG(lastLayer.p[c], set) == -1)
continue;
10294 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10295 MInt nghbrId = c_neighborId(lastLayer.p[c], dir);
10296 if(nghbrId == -1)
continue;
10297 if(a_isGZeroCell(nghbrId, set))
continue;
10298 if(a_bodyIdG(nghbrId, set) > -1)
continue;
10299 temp.p[tempCnt++] = nghbrId;
10300 a_bodyIdG(nghbrId, set) = a_bodyIdG(lastLayer.p[c], set);
10305 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10306 for(
MInt j = 0; j < noWindowCells(i); j++) {
10307 tmp_data(windowCellId(i, j)) = a_bodyIdG(windowCellId(i, j), set);
10310 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10311 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
10312 MInt windowId = grid().azimuthalWindowCell(i, j);
10313 tmp_data(windowId) = a_bodyIdG(windowId, set);
10317 exchangeDataLS(&tmp_data(0), 1);
10319 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10320 for(
MInt j = 0; j < noHaloCells(i); j++) {
10321 const MInt haloCell = haloCellId(i, j);
10322 if(a_bodyIdG(haloCell, set) < 0) {
10323 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10324 if(a_bodyIdG(haloCell, set) > -1) {
10325 temp.p[tempCnt++] = haloCell;
10330 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10331 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
10332 const MInt haloCell = grid().azimuthalHaloCell(i, j);
10333 if(a_bodyIdG(haloCell, set) < 0) {
10334 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10335 if(a_bodyIdG(haloCell, set) > -1) {
10336 temp.p[tempCnt++] = haloCell;
10344 for(
MInt c = 0; c < tempCnt; c++)
10345 lastLayer.p[c] = temp.p[c];
10351 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
10352 for(
MInt j = 0; j < nDim; j++) {
10353 initialInsidePoints[i * nDim + j] =
10354 initialInsidePoints[i * nDim + j] - m_semiLagrange_xShift_ref[j * m_noEmbeddedBodies + i];
10359 shiftTime = elapsedTime;
10361 }
else if(mode == 1) {
10366 if(domainId() == 0) cerr <<
"Using fast identifyBodies-Version" << endl;
10367 MBool anyShift =
false;
10370 for(
MInt set = m_startSet; set < m_noSets; set++) {
10371 if(!m_computeSet[set])
continue;
10372 if(!m_changedSet[set] & m_levelSetMb)
continue;
10374 const MFloat length = 0.5 * c_cellLengthAtLevel(a_maxGCellLevel());
10376 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
10377 MInt body = m_setToBodiesTable[set][
b];
10378 MFloat xCurrent[3] = {F0, F0, F0};
10379 MFloat xOld[3] = {F0, F0, F0};
10380 MFloat xShift[3] = {F0, F0, F0};
10382 computeBodyPropertiesForced(1, xCurrent, body, time() + timeStep());
10383 computeBodyPropertiesForced(1, xOld, body, shiftTime);
10386 for(
MInt d = 0; d < nDim; d++) {
10387 xShift[d] = xCurrent[d] - xOld[d];
10389 MBool needShift =
false;
10390 for(
MInt d = 0; d < nDim; d++) {
10391 if(xShift[d] > length) {
10394 shiftTime = elapsedTime;
10400 if(domainId() == 0) {
10401 cerr <<
"Shifting fast identifyBodies-Version " << shiftTime <<
" " << xShift[0] <<
" " << xShift[1] <<
" "
10402 << xCurrent[0] <<
" " << xOld[0] <<
" " << xCurrent[1] <<
" " << xOld[1] << endl;
10404 for(
MInt dir = 0; dir < nDim; dir++) {
10405 if(xShift[dir] > length) {
10407 if(!c_isLeafCell(cellId))
continue;
10408 if(a_bodyIdG(cellId, set) != body)
continue;
10410 if(!a_hasNeighbor(cellId, dir))
continue;
10411 MInt nghbrId = c_neighborId(cellId, dir);
10412 if(!a_bodyIdG(nghbrId, set)) {
10413 a_bodyIdG(nghbrId, set) = body;
10423 exchangeDataLS(&(a_bodyIdG(0, 0)), m_maxNoSets);
10427 for(
MInt set = m_startSet; set < m_noSets; set++) {
10428 if(!m_computeSet[set])
continue;
10429 if(!m_changedSet[set] & m_levelSetMb)
continue;
10433 if(a_levelSetFunctionG(cellId, set) * ((
MFloat)m_levelSetSign[set]) > 0 && !a_isGZeroCell(cellId, set)) {
10434 a_bodyIdG(cellId, set) = -1;
10436 if(a_level(cellId) == a_maxGCellLevel(set)) {
10437 ASSERT(a_bodyIdG(cellId, set) > -1,
"");
10443 MInt layerCount = 1;
10450 for(
MInt id = 0;
id < a_noG0Cells(set);
id++) {
10452#if defined LS_DEBUG || !defined NDEBUG
10453 ASSERT(a_bodyIdG(cellId, set) > -1,
10454 "G0-Cell should have a valid bodyId " << to_string(c_globalId(cellId)) +
" " + to_string(set));
10455 MBool bodyFound =
false;
10456 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
10457 MInt body = m_setToBodiesTable[set][
b];
10458 if(a_bodyIdG(cellId, set) == body) {
10463 ASSERT(bodyFound,
"BodyId of the G0-Cell is not matching any of the bodies in the set!");
10469 for(
MInt c = 0; c < tempCnt; c++) {
10470 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10471 MInt nghbrId = c_neighborId(temp.p[c], dir);
10472 if(nghbrId == -1)
continue;
10473 if(a_isGZeroCell(nghbrId, set))
continue;
10474 lastLayer.p[cnt++] = nghbrId;
10475 a_bodyIdG(nghbrId, set) = a_bodyIdG(temp.p[c], set);
10480 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10481 for(
MInt j = 0; j < noWindowCells(i); j++) {
10482 tmp_data(windowCellId(i, j)) = a_bodyIdG(windowCellId(i, j), set);
10485 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10486 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
10487 MInt windowId = grid().azimuthalWindowCell(i, j);
10488 tmp_data(windowId) = a_bodyIdG(windowId, set);
10492 exchangeDataLS(&tmp_data(0), 1);
10494 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10495 for(
MInt j = 0; j < noHaloCells(i); j++) {
10496 const MInt haloCell = haloCellId(i, j);
10497 if(a_bodyIdG(haloCell, set) < 0) {
10498 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10499 if(a_bodyIdG(haloCell, set) > -1) {
10500 lastLayer.p[cnt++] = haloCell;
10505 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10506 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
10507 const MInt haloCell = grid().azimuthalHaloCell(i, j);
10508 if(a_bodyIdG(haloCell, set) < 0) {
10509 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10510 if(a_bodyIdG(haloCell, set) > -1) {
10511 lastLayer.p[cnt++] = haloCell;
10518 while(layerCount < m_gBandWidth + 1) {
10520 for(
MInt c = 0; c < cnt; c++) {
10522 ASSERT(a_bodyIdG(lastLayer.p[c], set) > -1,
"");
10523 for(
MInt dir = 0; dir < m_noDirs; dir++) {
10524 MInt nghbrId = c_neighborId(lastLayer.p[c], dir);
10525 if(nghbrId == -1)
continue;
10526 if(a_isGZeroCell(nghbrId, set))
continue;
10527 if(a_bodyIdG(nghbrId, set) > -1)
continue;
10528 temp.p[tempCnt++] = nghbrId;
10529 a_bodyIdG(nghbrId, set) = a_bodyIdG(lastLayer.p[c], set);
10534 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10535 for(
MInt j = 0; j < noWindowCells(i); j++) {
10536 tmp_data(windowCellId(i, j)) = a_bodyIdG(windowCellId(i, j), set);
10539 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10540 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
10541 MInt windowId = grid().azimuthalWindowCell(i, j);
10542 tmp_data(windowId) = a_bodyIdG(windowId, set);
10546 exchangeDataLS(&tmp_data(0), 1);
10548 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
10549 for(
MInt j = 0; j < noHaloCells(i); j++) {
10550 const MInt haloCell = haloCellId(i, j);
10551 if(a_bodyIdG(haloCell, set) < 0) {
10552 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10553 if(a_bodyIdG(haloCell, set) > -1) {
10554 temp.p[tempCnt++] = haloCell;
10559 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
10560 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
10561 const MInt haloCell = grid().azimuthalHaloCell(i, j);
10562 if(a_bodyIdG(haloCell, set) < 0) {
10563 a_bodyIdG(haloCell, set) = tmp_data(haloCell);
10564 if(a_bodyIdG(haloCell, set) > -1) {
10565 temp.p[tempCnt++] = haloCell;
10573 for(
MInt c = 0; c < tempCnt; c++)
10574 lastLayer.p[c] = temp.p[c];
10595template <MInt nDim>
10599 MInt startCellId = -1;
10603 if(a_level(cellId) != minLevel())
continue;
10604 if(inCell(cellId, point)) {
10606 while(c_noChildren(startCellId) > 0) {
10608 if(point[0] > c_coordinate(startCellId, 0)) position += 1;
10609 if(point[1] > c_coordinate(startCellId, 1)) position += 2;
10610 IF_CONSTEXPR(nDim == 3) {
10611 if(point[2] > c_coordinate(startCellId, 2)) position += 4;
10615 const MInt childId = c_childId(startCellId, position);
10616 if(childId > -1 && !a_isHalo(childId)) {
10617 startCellId = childId;
10619 return startCellId;
10622 return startCellId;
10626 ASSERT(startCellId < a_noCells(),
"");
10628 if(startCellId > -1) {
10629 ASSERT(!a_isHalo(startCellId),
"");
10632 return startCellId;
10649template <MInt nDim>
10655 MInt nghbrId2, nghbrId3;
10656 MInt d1, d2, d3, e, w, g;
10657 std::vector<MInt> diagCells;
10658 std::vector<MInt> diag2Cells;
10659 std::vector<MInt> signs;
10660 std::map<MInt, std::vector<MInt>> dirCode;
10664 ASSERT(a_level(startCell) == a_maxGCellLevel(set) || a_level(startCell) == maxLevel(),
10665 "searchCell not on maxLevel! " + to_string(startCell));
10667 if(startCell < 0)
return -1;
10668 if(inCell(startCell, point))
return startCell;
10670 for(
MInt nghbr = 0; nghbr < 2 * nDim; nghbr++) {
10671 nghbrId = c_neighborId(startCell, nghbr);
10672 if(nghbrId == -1)
continue;
10674 if(inCell(nghbrId, point))
return nghbrId;
10677 signs.resize(nDim);
10680 MInt dir[3] = {0, 2, 4};
10681 MInt oDir[6] = {2, 4, 0, 4, 0, 2};
10682 for(
MInt i = 0; i < nDim; i++) {
10683 for(
MInt j = 0; j < 2; j++) {
10685 nghbrId = c_neighborId(startCell, d1);
10686 if(nghbrId == -1)
continue;
10688 signs[e] = d1 + pow(-1, j);
10689 for(
MInt k = 0; k < 2; k++) {
10690 for(
MInt m = 0; m < 2; m++) {
10691 d2 = oDir[2 * e + k] + m;
10692 nghbrId2 = c_neighborId(nghbrId, d2);
10693 if(nghbrId2 == -1)
continue;
10694 diagCells.push_back(nghbrId2);
10696 signs[w] = d2 + pow(-1, m);
10697 for(
MInt n = 0; n < 2; n++) {
10698 d3 = dir[nDim - e - w] + n;
10699 if(a_hasNeighbor(nghbrId2, d3)) {
10701 signs[g] = d3 + pow(-1, n);
10702 nghbrId3 = c_neighborId(nghbrId2, d3);
10703 diag2Cells.push_back(nghbrId3);
10704 if(dirCode.find(nghbrId3) == dirCode.end()) dirCode.insert(pair<
MInt, vector<MInt>>(nghbrId3, signs));
10712 std::sort(diagCells.begin(), diagCells.end());
10713 auto last1 = std::unique(diagCells.begin(), diagCells.end());
10714 diagCells.erase(last1, diagCells.end());
10715 for(std::vector<MInt>::iterator it = diagCells.begin(); it != diagCells.end(); it++) {
10716 if(inCell(*it, point))
return *it;
10718 std::sort(diag2Cells.begin(), diag2Cells.end());
10719 auto last2 = std::unique(diag2Cells.begin(), diag2Cells.end());
10720 diag2Cells.erase(last2, diag2Cells.end());
10721 for(std::vector<MInt>::iterator it = diag2Cells.begin(); it != diag2Cells.end(); it++) {
10722 if(inCell(*it, point))
return *it;
10730 nghbrId = checkSecondLayerCells(diag2Cells, dirCode, point);
10732 if(a_level(nghbrId) != a_maxGCellLevel() || (!m_reconstructOldG && m_initialGCell[nghbrId] == 0)) {
10737 if(nghbrId == -1) {
10738 cerr <<
"D:" << domainId() <<
" Entire domain " << startCell <<
"/" << c_globalId(startCell) <<
" "
10739 << c_coordinate(startCell, 0) <<
" " << c_coordinate(startCell, 1) <<
" " << c_coordinate(startCell, 2) <<
" "
10740 << a_level(startCell) <<
" Point " << point[0] <<
" " << point[1] <<
" " << point[2] << endl;
10742 nghbrId = getContainingCell(point);
10745 && (a_level(nghbrId) != a_maxGCellLevel() || (!m_reconstructOldG && m_initialGCell[nghbrId] == 0))) {
10749 cerr <<
"Found " << domainId() <<
" " << nghbrId <<
"/" << c_globalId(nghbrId) <<
" " << c_coordinate(nghbrId, 0)
10750 <<
" " << c_coordinate(nghbrId, 1) <<
" " << c_coordinate(nghbrId, 2) <<
" " << a_level(nghbrId) << endl;
10751 MFloat dist = sqrt(pow(c_coordinate(nghbrId, 0) - c_coordinate(startCell, 0), 2.0)
10752 + pow(c_coordinate(nghbrId, 1) - c_coordinate(startCell, 1), 2.0)
10753 + pow(c_coordinate(nghbrId, 2) - c_coordinate(startCell, 2), 2.0))
10754 / c_cellLengthAtLevel(a_maxGCellLevel());
10755 cerr <<
"Point " << point[0] <<
" " << point[1] <<
" " << point[2] <<
" " <<
dist << endl;
10758 if(nghbrId == -1) {
10759 nghbrId = getContainingCellHalo(point);
10761 cerr <<
"D:" << domainId() <<
" Cell found in halo cell" << nghbrId;
10763 mTerm(1, AT_,
"No containing cell found... exiting!");
10831template <MInt nDim>
10838 MFloat cellHalfLength = c_cellLengthAtLevel(a_level(cellId) + 1);
10840 xmin = c_coordinate(cellId, 0) - cellHalfLength;
10841 xmax = c_coordinate(cellId, 0) + cellHalfLength;
10842 ymin = c_coordinate(cellId, 1) - cellHalfLength;
10843 ymax = c_coordinate(cellId, 1) + cellHalfLength;
10845 IF_CONSTEXPR(nDim == 2) {
10846 if(point[0] <= xmax && point[0] >= xmin && point[1] <= ymax && point[1] >= ymin) {
10853 zmin = c_coordinate(cellId, 2) - cellHalfLength;
10854 zmax = c_coordinate(cellId, 2) + cellHalfLength;
10856 if(point[0] <= xmax && point[0] >= xmin && point[1] <= ymax && point[1] >= ymin && point[2] <= zmax
10857 && point[2] >= zmin) {
10877template <MInt nDim>
10883 return static_cast<MBool>(grid().tree().hasNeighbor(cell, dim));
10886 return this->setUpInterpolationStencil(cellId, interpolationCells, point, alwaysTrue,
false);
10902template <MInt nDim>
10904 interpolationCells[position] =
cellId;
10906 IF_CONSTEXPR(nDim == 2) {
10907 MInt nghbrX, nghbrY;
10908 MInt posIncrementX, posIncrementY;
10909 MInt xNghbrDir, yNghbrDir;
10910 if(position % 2 == 0) {
10912 nghbrX = c_neighborId(cellId, xNghbrDir);
10916 nghbrX = c_neighborId(cellId, xNghbrDir);
10917 posIncrementX = -1;
10919 if(((
MInt)(position / 2)) % 2 == 0) {
10921 nghbrY = c_neighborId(cellId, yNghbrDir);
10925 nghbrY = c_neighborId(cellId, yNghbrDir);
10926 posIncrementY = -2;
10928 interpolationCells[position + posIncrementX] = nghbrX;
10929 interpolationCells[position + posIncrementY] = nghbrY;
10930 interpolationCells[position + posIncrementX + posIncrementY] = c_neighborId(nghbrX, yNghbrDir);
10933 MInt nghbrX, nghbrY, nghbrZ;
10934 MInt posIncrementX, posIncrementY, posIncrementZ;
10935 MInt xNghbrDir, yNghbrDir, zNghbrDir;
10936 if(position % 2 == 0) {
10938 nghbrX = c_neighborId(cellId, xNghbrDir);
10942 nghbrX = c_neighborId(cellId, xNghbrDir);
10943 posIncrementX = -1;
10945 if(((
MInt)(position / 2)) % 2 == 0) {
10947 nghbrY = c_neighborId(cellId, yNghbrDir);
10951 nghbrY = c_neighborId(cellId, yNghbrDir);
10952 posIncrementY = -2;
10954 if((
MInt)(position / 4) == 0) {
10956 nghbrZ = c_neighborId(cellId, zNghbrDir);
10960 nghbrZ = c_neighborId(cellId, zNghbrDir);
10961 posIncrementZ = -4;
10963 interpolationCells[position + posIncrementX] = nghbrX;
10964 interpolationCells[position + posIncrementY] = nghbrY;
10965 interpolationCells[position + posIncrementZ] = nghbrZ;
10966 interpolationCells[position + posIncrementX + posIncrementZ] = c_neighborId(nghbrX, zNghbrDir);
10967 interpolationCells[position + posIncrementX + posIncrementY] = c_neighborId(nghbrX, yNghbrDir);
10968 interpolationCells[position + posIncrementY + posIncrementZ] = c_neighborId(nghbrY, zNghbrDir);
10969 interpolationCells[position + posIncrementX + posIncrementY + posIncrementZ] =
10970 c_neighborId(c_neighborId(nghbrX, yNghbrDir), zNghbrDir);
10983template <MInt nDim>
10987 const MInt otherDir[6] = {1, 0, 3, 2, 5, 4};
10988 const MInt bcId = m_bodyBndryCndIds[body];
10991 MFloat dx[3] = {F0, F0, F0};
10994 if(m_GCtrlPntMethod == 2) {
10995 for(
MInt i = 0; i < nDim; i++) {
10996 dx[i] = m_semiLagrange_xShift_ref[i * m_noEmbeddedBodies + body];
10998 m_gCtrlPnt.CtrlPnt2_shiftSTL(bcId, dx);
11003 tmp_field[
cellId] = a_oldLevelSetFunctionG(cellId, set);
11009 if(a_level(cellId) != a_maxGCellLevel(set))
continue;
11010 if(a_bodyIdG(cellId, set) != body)
continue;
11011 ASSERT(!a_isHalo(cellId),
"");
11012 const MInt nghbrId = c_neighborId(cellId, otherDir[dir]);
11013 if(nghbrId == -1 || nghbrId == cellId) {
11014 MFloat refPoint[3] = {F0, F0, F0};
11015 for(
MInt i = 0; i < nDim; i++) {
11016 refPoint[i] = c_coordinate(cellId, i);
11018 MInt closestElement;
11019 MFloat closestPoint[3] = {F0, F0, F0};
11020 MFloat sign = determineLevelSetSignFromSTL(refPoint, set);
11021 if(m_levelSetSign[set] < 0) sign *= -1.0;
11022 const MFloat phi = sign * computeDistanceFromSTL(refPoint, &closestElement, closestPoint, set);
11023 a_oldLevelSetFunctionG(cellId, set) = phi;
11025 a_oldLevelSetFunctionG(cellId, set) = tmp_field[nghbrId];
11030 if(m_GCtrlPntMethod == 2) {
11031 for(
MInt i = 0; i < nDim; i++) {
11032 dx[i] = -m_semiLagrange_xShift_ref[i * m_noEmbeddedBodies + body];
11034 m_gCtrlPnt.CtrlPnt2_shiftSTL(bcId, dx);
11048template <MInt nDim>
11053 return static_cast<MFloat>(a_oldLevelSetFunctionG(cellId, set));
11057 return static_cast<MFloat>(c_coordinate(cellId,
id));
11060 return this->
template interpolateFieldData<true>(&interpolationCells[0], &point[0], referenceSet, scalarField,
11070template <MInt nDim>
11075 return static_cast<MFloat>(a_levelSetFunctionG(cellId, set));
11079 return static_cast<MFloat>(c_coordinate(cellId,
id));
11082 return this->
template interpolateFieldData<true>(&interpolationCells[0], &point[0], referenceSet, scalarField,
11108template <MInt nDim>
11120 if(m_noSets < 2)
return;
11122 const MFloat eps1 = c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim);
11123 const MFloat eps2 = c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * m_gapDeltaMin;
11125 if(mode == 1 || mode == 2) {
11130 for(
MInt region = 0; region < m_noGapRegions; region++) {
11131 m_minGapWidthDt1[region] = m_minGapWidth[region];
11132 m_minGapWidth[region] = std::numeric_limits<MFloat>::max();
11137 MFloat currentWidth = std::numeric_limits<MFloat>::max();
11140 a_levelSetFunctionG(cellId, 0) = a_levelSetFunctionG(cellId, 1);
11141 a_bodyIdG(cellId, 0) = a_bodyIdG(cellId, 1);
11142 a_secondBodyId(cellId) = -1;
11143 for(
MInt set = 2; set < m_noSets; set++) {
11144 MFloat phi0 = a_levelSetFunctionG(cellId, 0);
11145 MFloat phi1 = a_levelSetFunctionG(cellId, set);
11146 MInt body0 = a_bodyIdG(cellId, 0);
11147 MInt body1 = a_bodyIdG(cellId, set);
11148 MInt body2 = a_secondBodyId(cellId);
11149 MInt body3 = a_bodyIdG(cellId, set);
11152 if(phi0 >= F0 && phi1 >= F0) {
11158 if(body2 == -1 && body3 > -1) body2 = body3;
11160 phi0 =
mMin(phi0, phi1);
11161 }
else if(phi0 <= F0 && phi1 <= F0) {
11162 if(abs(phi1) > abs(phi0)) {
11166 if(body2 == -1 && body3 > -1) body2 = body3;
11168 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
11169 }
else if(phi0 * phi1 <= F0) {
11173 if(body2 == -1 && body3 > -1) body2 = body3;
11179 ASSERT(phi0 <= phi1,
"");
11181 cerr <<
"WHAT THE FUCK! " << phi0 << phi1 << endl;
11184 a_levelSetFunctionG(cellId, 0) = phi0;
11185 a_bodyIdG(cellId, 0) = body0;
11186 a_secondBodyId(cellId) = body2;
11189 if(a_secondBodyId(cellId) == a_bodyIdG(cellId, 0)) {
11190 a_secondBodyId(cellId) = -1;
11192 ASSERT(a_secondBodyId(cellId) < m_noBodyBndryCndIds, to_string(cellId) +
" " + to_string(a_secondBodyId(cellId)));
11194 a_secondBodyId(cellId) < 0
11195 || (m_bodyToSetTable[a_secondBodyId(cellId)] > -1 && m_bodyToSetTable[a_secondBodyId(cellId)] < m_noSets),
11199 distBody1[
cellId] = a_levelSetFunctionG(cellId, 0);
11202 if(a_secondBodyId(cellId) > -1) {
11203 distBody2[
cellId] = a_levelSetFunctionG(cellId, m_bodyToSetTable[a_secondBodyId(cellId)]);
11205 distBody2[
cellId] = m_outsideGValue;
11209 if(a_secondBodyId(cellId) > -1 && a_bodyIdG(cellId, 0) > -1 && fabs(distBody1[cellId]) < m_outsideGValue
11210 && fabs(distBody2[cellId]) < m_outsideGValue) {
11211 if(m_gapInitMethod == 0) {
11214 sumBodiesDist[
cellId] = fabs(distBody1[cellId]) + fabs(distBody2[cellId]);
11220 if(m_gapInitMethod == 0) {
11221 sumBodiesDist[
cellId] = -m_outsideGValue;
11223 sumBodiesDist[
cellId] = -2 * m_outsideGValue;
11228 if(m_gapInitMethod == 0) {
11232 if(a_levelSetFunctionG(cellId, 0) > F0) {
11233 a_gapWidth(cellId) = sumBodiesDist[
cellId];
11234 }
else if(fabs(a_levelSetFunctionG(cellId, 0)) < eps1) {
11235 a_gapWidth(cellId) = sumBodiesDist[
cellId];
11237 a_gapWidth(cellId) = -m_outsideGValue;
11240 a_gapWidth(cellId) = sumBodiesDist[
cellId];
11244 const MBool isInsideGap = (fabs(a_gapWidth(cellId)) <= eps2 && a_potentialGapCell(cellId) > 0) ?
true :
false;
11247 if(m_gapInitMethod > 0 && mode == 1) {
11249 if(a_secondBodyId(cellId) > -1 && a_bodyIdG(cellId, 0) > -1 && fabs(distBody1[cellId]) < m_outsideGValue
11250 && fabs(distBody2[cellId]) < m_outsideGValue) {
11253 sumBodiesDist[
cellId] = 2 * m_outsideGValue;
11256 if(a_potentialGapCell(cellId) && sumBodiesDist[
cellId] <= eps2 && isInsideGap) {
11257 MInt regionId = a_potentialGapCellClose(cellId) - 2;
11258 ASSERT(regionId >= 0 && regionId < m_noGapRegions, to_string(regionId));
11273 if(currentWidth < m_minGapWidth[regionId]) {
11274 m_minGapWidth[regionId] = currentWidth;
11282 if(m_closeGaps && m_gapInitMethod > 0 && mode == 1) {
11283 MPI_Allreduce(MPI_IN_PLACE, &m_minGapWidth[0], m_noGapRegions, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
11284 "MPI_IN_PLACE",
"m_minGapWidth[0]");
11286 for(
MInt region = 0; region < m_noGapRegions; region++) {
11287#if defined LS_DEBUG || !defined NDEBUG
11288 if(domainId() == 0 && m_minGapWidth[region] < 10 * m_outsideGValue) {
11289 cerr <<
"-->Min-Gap-Width at " <<
globalTimeStep <<
" for region " << region <<
" is "
11290 << m_minGapWidth[region] <<
" . Limit for Closure is: " << eps2 << endl;
11293 if(domainId() == 0 && m_minGapWidth[region] < 0) {
11294 cerr <<
"Caution: overlapping levelSet-bodies in region " << region <<
" !" << endl;
11297 if(m_minGapWidth[region] < -eps2) {
11298 MFloat dif = -(m_minGapWidth[region] + eps2);
11299 if(domainId() == 0) cerr <<
"Caution: temporary increase in gapDeltaMin, from " << m_gapDeltaMin;
11300 m_gapDeltaMin = m_gapDeltaMin + 1.5 * dif;
11301 if(domainId() == 0) cerr <<
" to " << m_gapDeltaMin << endl;
11302 ASSERT(m_noGapRegions == 1,
"ERROR: Increased gapDeltaMin not yet implemented for multiple-Gap-Regions!");
11307 m_gapDeltaMin = m_gapDeltaMinOrig;
11313 }
else if(mode == 0) {
11315 a_levelSetFunctionG(cellId, 0) = a_levelSetFunctionG(cellId, 1);
11316 for(
MInt set = 2; set < m_noSets; set++) {
11317 MFloat phi0 = a_levelSetFunctionG(cellId, 0);
11318 MFloat phi1 = a_levelSetFunctionG(cellId, set);
11321 if(phi0 >= F0 && phi1 >= F0) {
11322 phi0 =
mMin(phi0, phi1);
11323 }
else if(phi0 <= F0 && phi1 <= F0) {
11324 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
11325 }
else if(phi0 * phi1 <= F0) {
11333 a_levelSetFunctionG(cellId, 0) = phi0;
11337 mTerm(1, AT_,
"Unknown mode in buildCollectedLevelSet()");
11341template <MInt nDim>
11345 grid().findEqualLevelNeighborsParDiagonal(
false);
11349 if(m_cellIsInDiffRegion !=
nullptr) {
11350 cout <<
"Deallocate m_cellIsInDiffRegion" << endl;
11353 if(m_correctedDistances !=
nullptr) {
11354 cout <<
"Deallocate m_correctedDistance" << endl;
11358 mAlloc(m_cellIsInDiffRegion, a_noCells(),
"m_cellIsInDiffRegion", -2, AT_);
11359 mAlloc(m_correctedDistances, a_noCells(), (m_maxNoSets - m_startSet),
"m_correctedDistances", F0, AT_);
11360 MFloatScratchSpace boundingBox(m_noInterpolationRegions * m_noDirs, AT_,
"boundingBox");
11367 m_geometry->getBoundingBox(globalBoundingBox.getPointer());
11375 if(!c_isLeafCell(cellId))
continue;
11376 MFloat phi1 = a_levelSetFunctionG(cellId, 1);
11377 MFloat phi2 = a_levelSetFunctionG(cellId, 2);
11378 MFloat deltaPhi = phi1 - phi2;
11379 if((fabs(deltaPhi) < eps)) {
11382 m_cellIsInDiffRegion[
cellId] = -1;
11383 MBool reachedMinLevel =
false;
11385 while(!reachedMinLevel) {
11386 if(c_parentId(parentId) > -1) {
11387 parentId = c_parentId(parentId);
11388 if(m_cellIsInDiffRegion[parentId] < -1) {
11389 m_cellIsInDiffRegion[parentId] = -1;
11391 reachedMinLevel =
true;
11394 reachedMinLevel =
true;
11395 ASSERT(a_level(parentId) == minLevel(),
"This should not happen!");
11403 m_noInterpolationRegions = 0;
11404 MBool foundAllRegions =
false;
11405 while(!foundAllRegions) {
11407 for(
MInt d = 0; d < nDim; d++) {
11408 pointCoord(d) = globalBoundingBox(d + nDim) + 10.0 * c_cellLengthAtLevel(minLevel());
11414 for(
MInt c = 0; c < grid().noLocalPartitionCells(); c++) {
11415 MInt cellId = grid().localPartitionCellLocalIds(c);
11416 if(cellId < 0)
continue;
11418 if(m_cellIsInDiffRegion[cellId] == -1) {
11419 for(
MInt d = 0; d < nDim; d++) {
11420 pointCoord(d) = c_coordinate(cellId, d);
11421 cout <<
"Writing point for cell for domain " << domainId() <<
" and region " << m_noInterpolationRegions
11422 <<
": " << pointCoord(d) << endl;
11429 for(
MInt d = 0; d < nDim; d++) {
11430 allPointCoords(domainId(), d) = pointCoord(d);
11432 MPI_Allgather(MPI_IN_PLACE, nDim, MPI_DOUBLE, &allPointCoords[0], nDim, MPI_DOUBLE, mpiComm(), AT_,
"MPI_IN_PLACE",
11439 foundAllRegions =
true;
11440 for(
MInt i = 0; i < noDomains(); i++) {
11441 MBool startPoint =
true;
11442 for(
MInt d = 0; d < nDim; d++) {
11443 if(allPointCoords(i, d) > globalBoundingBox(d + nDim)) startPoint =
false;
11446 for(
MInt d = 0; d < nDim; d++) {
11447 pointCoord(d) = allPointCoords(i, d);
11449 foundAllRegions =
false;
11453 if(foundAllRegions) {
11458 MInt startCell = -1;
11459 for(
MInt i = 0; i < a_noCells(); i++) {
11460 if(a_isHalo(i))
continue;
11461 if(c_parentId(i) > -1)
continue;
11462 if(m_cellIsInDiffRegion[i] != -1)
continue;
11464 MFloat halfLength = grid().cellLengthAtLevel(a_level(i)) * F1B2;
11467 for(
MInt d = 0; d < nDim; d++) {
11468 if(abs(c_coordinate(i, d) - pointCoord(d)) <= halfLength) cnt++;
11472 cout <<
"START Cell Found on process " << domainId() << endl;
11473 ASSERT(a_level(startCell) == minLevel(),
"This should not happen!!!");
11480 if(startCell > -1) {
11481 regionGrowing(startCell, m_noInterpolationRegions);
11485 if(noDomains() > 1) {
11487 MIntScratchSpace noSendWindowPerDomain(noNeighborDomains(), AT_,
"noSendWindowPerDomain");
11488 MIntScratchSpace noReceiveHaloPerDomain(noNeighborDomains(), AT_,
"noReceiveHaloPerDomain");
11489 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11490 noSendWindowPerDomain[d] = noWindowCells(d);
11491 ASSERT(noSendWindowPerDomain[d] >= 0,
"noSendWindowPerDomain[d] < 0");
11493 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11494 noReceiveHaloPerDomain[d] = noHaloCells(d);
11495 ASSERT(noReceiveHaloPerDomain[d] >= 0,
"noReceiveHaloPerDomain[d] < 0");
11499 MInt allReceive = 0;
11500 vector<MInt> offsetsSend;
11501 vector<MInt> offsetsReceive;
11502 for(
MInt dom = 0; dom < noNeighborDomains(); dom++) {
11503 offsetsSend.push_back(allSend);
11504 offsetsReceive.push_back(allReceive);
11505 allSend += noSendWindowPerDomain[dom];
11506 allReceive += noReceiveHaloPerDomain[dom];
11509 MInt noChanges = 1;
11510 MInt noIterations = 0;
11511 while(noChanges != 0) {
11517 MPI_Request* mpi_request_;
11518 mAlloc(mpi_request_, noNeighborDomains(),
"mpi_request_", AT_);
11520 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11521 if(noSendWindowPerDomain[d] > 0) {
11522 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++) {
11523 sndBufWin[offsetsSend[d] + c] = m_cellIsInDiffRegion[windowCellId(d, c)];
11525 MPI_Issend(&(sndBufWin[offsetsSend[d]]), noSendWindowPerDomain[d], MPI_INT, neighborDomain(d), 0, mpiComm(),
11526 &mpi_request_[d], AT_,
"(sndBufWin[offsetsSend[d]])");
11529 MPI_Status status_;
11530 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11531 if(noReceiveHaloPerDomain[d] > 0) {
11532 MPI_Recv(&(rcvBufHalo[offsetsReceive[d]]), noReceiveHaloPerDomain[d], MPI_INT, neighborDomain(d), 0,
11533 mpiComm(), &status_, AT_,
"(rcvBufHalo[offsetsReceive[d]])");
11537 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11538 if(noReceiveHaloPerDomain[d] > 0 && noSendWindowPerDomain[d] > 0) {
11539 MPI_Wait(&mpi_request_[d], &status_, AT_);
11543 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11544 if(noReceiveHaloPerDomain[d] > 0) {
11545 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
11546 const MInt halo = haloCellId(d, c);
11547 if(c_parentId(halo) > -1)
continue;
11548 ASSERT(a_level(halo) == minLevel(),
"This should not happen!!!!");
11549 if((rcvBufHalo[c + offsetsReceive[d]] == m_noInterpolationRegions)
11550 && (m_cellIsInDiffRegion[halo] == -1)) {
11551 regionGrowing(halo, m_noInterpolationRegions);
11558 MPI_Allreduce(MPI_IN_PLACE, &noChanges, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"noChanges");
11562 cout <<
"NO CHANGES " << noIterations <<
" " << m_noInterpolationRegions << endl;
11564 m_noInterpolationRegions++;
11567 cout <<
"m_noInterpolationRegions " << m_noInterpolationRegions << endl;
11574 if(c_parentId(cellId) > -1)
continue;
11575 ASSERT(m_cellIsInDiffRegion[cellId] != -1,
"It seems like some minLevel cells were skipped!");
11576 if(m_cellIsInDiffRegion[cellId] < 0)
continue;
11577 for(
MInt c = 0; c < c_noChildren(cellId); c++) {
11578 if(c_childId(cellId, c) < 0)
continue;
11579 setChildRegions(c_childId(cellId, c), m_cellIsInDiffRegion[cellId]);
11583 if(noDomains() > 1) {
11585 MIntScratchSpace noSendWindowPerDomain(noNeighborDomains(), AT_,
"noSendWindowPerDomain");
11586 MIntScratchSpace noReceiveHaloPerDomain(noNeighborDomains(), AT_,
"noReceiveHaloPerDomain");
11587 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11588 noSendWindowPerDomain[d] = noWindowCells(d);
11589 ASSERT(noSendWindowPerDomain[d] >= 0,
"noSendWindowPerDomain[d] < 0");
11591 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11592 noReceiveHaloPerDomain[d] = noHaloCells(d);
11593 ASSERT(noReceiveHaloPerDomain[d] >= 0,
"noReceiveHaloPerDomain[d] < 0");
11597 MInt allReceive = 0;
11598 vector<MInt> offsetsSend;
11599 vector<MInt> offsetsReceive;
11600 for(
MInt dom = 0; dom < noNeighborDomains(); dom++) {
11601 offsetsSend.push_back(allSend);
11602 offsetsReceive.push_back(allReceive);
11603 allSend += noSendWindowPerDomain[dom];
11604 allReceive += noReceiveHaloPerDomain[dom];
11610 MPI_Request* mpi_request_;
11611 mAlloc(mpi_request_, noNeighborDomains(),
"mpi_request_", AT_);
11613 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11614 if(noSendWindowPerDomain[d] > 0) {
11615 for(
MInt c = 0; c < noSendWindowPerDomain[d]; c++) {
11616 sndBufWin[offsetsSend[d] + c] = m_cellIsInDiffRegion[windowCellId(d, c)];
11618 MPI_Issend(&(sndBufWin[offsetsSend[d]]), noSendWindowPerDomain[d], MPI_INT, neighborDomain(d), 0, mpiComm(),
11619 &mpi_request_[d], AT_,
"(sndBufWin[offsetsSend[d]])");
11622 MPI_Status status_;
11623 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11624 if(noReceiveHaloPerDomain[d] > 0) {
11625 MPI_Recv(&(rcvBufHalo[offsetsReceive[d]]), noReceiveHaloPerDomain[d], MPI_INT, neighborDomain(d), 0, mpiComm(),
11626 &status_, AT_,
"(rcvBufHalo[offsetsReceive[d]])");
11630 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11631 if(noReceiveHaloPerDomain[d] > 0 && noSendWindowPerDomain[d] > 0) {
11632 MPI_Wait(&mpi_request_[d], &status_, AT_);
11636 for(
MInt d = 0; d < noNeighborDomains(); d++) {
11637 if(noReceiveHaloPerDomain[d] > 0) {
11638 for(
MInt c = 0; c < noReceiveHaloPerDomain[d]; c++) {
11639 const MInt halo = haloCellId(d, c);
11640 m_cellIsInDiffRegion[halo] = rcvBufHalo[c + offsetsReceive[d]];
11650 m_refinedCells.clear();
11652 if(!c_isLeafCell(cellId))
continue;
11653 if(!a_isHalo(cellId)) {
11654 if(m_cellIsInDiffRegion[cellId] >= 0) {
11655 m_refinedCells.insert(make_pair(cellId, 0));
11661 MInt noRefinedBandCells = (signed)m_refinedCells.size();
11662 MPI_Allreduce(MPI_IN_PLACE, &noRefinedBandCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
11663 "noRefinedBandCells");
11666 cerr <<
"Reinitialisation of " << noRefinedBandCells <<
" cells " << endl;
11667 if(noRefinedBandCells > 0) {
11670 constructGFieldFromSTL(4);
11672 exchangeDataLS(&(a_oldLevelSetFunctionG(0, 0)), m_maxNoSets);
11675 for(
auto& m_refinedCell : m_refinedCells) {
11677 ASSERT(!a_isHalo(cellId),
"");
11678 for(
MInt setI = m_startSet; setI < m_noSets; setI++) {
11679 a_levelSetFunctionG(cellId, setI) = a_oldLevelSetFunctionG(cellId, setI);
11683 for(
MInt lvl = maxLevel() - 1; lvl >= minLevel(); lvl--) {
11684 for(
MInt cell = 0; cell < a_noCells(); cell++) {
11685 for(
MInt set = 1; set < m_maxNoSets; set++) {
11686 if(a_level(cell) != lvl)
continue;
11687 MFloat levelSetCoarse = F0;
11688 if(c_noChildren(cell) > 0) {
11689 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
11690 if(c_childId(cell, child) < 0)
continue;
11691 levelSetCoarse += a_levelSetFunctionG(c_childId(cell, child), set);
11693 a_levelSetFunctionG(cell, set) = levelSetCoarse / (
MFloat)c_noChildren(cell);
11699 exchangeLevelSet();
11701 m_refinedCells.clear();
11707 MFloat phi1 = a_levelSetFunctionG(cellId, 1);
11708 MFloat phi2 = a_levelSetFunctionG(cellId, 2);
11709 m_correctedDistances[
cellId][0] = phi1;
11710 m_correctedDistances[
cellId][1] = phi2;
11713 MFloat xCurrent[3] = {F0, F0, F0};
11714 for(
MInt set = m_startSet; set < m_noSets; set++) {
11715 if(!m_computeSet_backup[set])
continue;
11716 for(
MInt b = 0;
b < m_noBodiesInSet[set];
b++) {
11717 const MInt body = m_setToBodiesTable[set][
b];
11718 computeBodyPropertiesForced(1, xCurrent, body, time() + timeStep());
11723template <MInt nDim>
11727 if(m_cellIsInDiffRegion[cellId] == -1) {
11728 m_cellIsInDiffRegion[
cellId] = region;
11730 for(
MInt n = 0; n < IPOW3[nDim] - 1; n++) {
11731 if(grid().neighborList(cellId, n) < 0)
continue;
11732 if(m_cellIsInDiffRegion[grid().neighborList(cellId, n)] != -1)
continue;
11733 regionGrowing(grid().neighborList(cellId, n), region);
11738template <MInt nDim>
11742 if(m_cellIsInDiffRegion[cellId] == -1) {
11743 m_cellIsInDiffRegion[
cellId] = region;
11745 for(
MInt c = 0; c < c_noChildren(cellId); c++) {
11746 if(c_childId(cellId, c) < 0)
continue;
11747 setChildRegions(c_childId(cellId, c), region);
11771template <MInt nDim>
11778 ASSERT(m_buildCollectedLevelSetFunction,
"");
11782 noCells = a_noCells();
11784 noCells = a_noBandCells(0);
11786 for(
MInt i = 0; i < noCells; i++) {
11791 cellId = a_bandCellId(i, 0);
11793 if(a_nearGapG(cellId) > 0 && a_potentialGapCellClose(cellId))
continue;
11794 a_levelSetFunctionG(cellId, 0) = a_levelSetFunctionG(cellId, 1);
11796 for(
MInt set = 2; set < m_noSets; set++) {
11797 MFloat phi0 = a_levelSetFunctionG(cellId, 0);
11798 MFloat phi1 = a_levelSetFunctionG(cellId, set);
11800 if(phi0 >= F0 && phi1 >= F0) {
11801 phi0 =
mMin(phi0, phi1);
11802 }
else if(phi0 <= F0 && phi1 <= F0) {
11803 phi0 = -sqrt(phi0 * phi0 + phi1 * phi1);
11804 }
else if(phi0 * phi1 <= F0) {
11812 a_levelSetFunctionG(cellId, 0) = phi0;
11830template <MInt nDim>
11834 if(!m_closeGaps)
return;
11840 stack<MInt> gapStack;
11843 const MFloat eps = c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * m_gapDeltaMin;
11845 const MFloat eps2 = c_cellLengthAtLevel(a_maxGCellLevel(0)) * (5.0 / 4.0 * sqrt(nDim)) * m_gapDeltaMin;
11846 const MFloat eps3 = (m_gapInitMethod < 2)
11847 ? c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * (1.5 + m_gapDeltaMin)
11848 : c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * (2.5 + m_gapDeltaMin);
11850 MInt maxNoLayers =
mMax(6, m_gBandWidth);
11860 m_noOldGapCells = m_noGapCells;
11862 MInt gapCellCounter = 0;
11863 MInt cellsAdded = 1;
11866 isInsideGap(cellId) =
false;
11868 if((fabs(a_gapWidth(cellId)) <= eps && a_potentialGapCell(cellId) > 0)
11869 && a_inBandG(cellId, 0)) {
11870 isInsideGap(cellId) =
true;
11872 isInsideGapTmp(cellId) =
false;
11873 a_nearGapG(cellId) =
false;
11879 for(
MInt region = 0; region < m_noGapRegions; region++) {
11880 forceNoGaps[region] =
false;
11881 surpressingGaps[region] = 0;
11882 if(m_forceNoGaps > 0) {
11885 const MFloat elapsedTime = time();
11887 if(((m_gapSign[region] < F0 && (cad > m_gapAngleOpen[region] || cad < m_gapAngleClose[region]))
11888 || (m_gapSign[region] > F0 && cad > m_gapAngleOpen[region] && cad < m_gapAngleClose[region]))
11889 && m_forceNoGaps == 1) {
11890 forceNoGaps[region] =
true;
11891 }
else if(m_forceNoGaps == 2
11892 && ((cad > m_gapAngleOpen[region] && cad < m_gapAngleClose[region])
11893 || (cad > m_gapAngleOpen[region + 1] && cad < m_gapAngleClose[region + 1]))) {
11894 forceNoGaps[region] =
true;
11900 for(
MInt id = 0;
id < a_noBandCells(0);
id++) {
11902 if(isInsideGap(cellId)) {
11903 const MInt region = a_potentialGapCellClose(cellId) - 2;
11904 if(m_forceNoGaps > 0 && forceNoGaps[region]) {
11905 surpressingGaps[region]++;
11908 gapStack.push(cellId);
11909 isInsideGapTmp(cellId) =
true;
11911 gapCells.p[gapCellCounter++] =
cellId;
11912 a_nearGapG(cellId) =
true;
11916 if(m_forceNoGaps > 0) {
11917#if defined LS_DEBUG || !defined NDEBUG
11919 MPI_Allreduce(MPI_IN_PLACE, &surpressingGaps, m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
11920 "surpressingGaps");
11921 if(domainId() == 0) {
11922 for(
MInt region = 0; region < m_noGapRegions; region++) {
11923 if(surpressingGaps[region] > 0)
11924 cerr <<
"Surpressing " << surpressingGaps[region] <<
" gap-Cells in region " << region << endl;
11931 while(cellsAdded) {
11934 if(gapCellCounter) {
11935 while(!gapStack.empty()) {
11936 MInt gCellId = gapStack.top();
11938 for(
MInt dir = 0; dir < m_noDirs; dir++) {
11939 MInt nghbrId = c_neighborId(gCellId, dir);
11940 if(nghbrId == -1)
continue;
11941 if(a_isHalo(nghbrId))
continue;
11942 if(!a_potentialGapCell(nghbrId))
continue;
11944 if(m_gapInitMethod == 0) {
11945 if(abs(a_gapWidth(nghbrId)) <= eps2 && a_gapWidth(nghbrId) >= F0 && !isInsideGapTmp(nghbrId)) {
11946 gapCells.p[gapCellCounter++] = nghbrId;
11947 isInsideGapTmp(nghbrId) =
true;
11949 a_nearGapG(nghbrId) =
true;
11950 gapStack.push(nghbrId);
11955 const MInt region = a_potentialGapCellClose(nghbrId) - 2;
11956 if(m_forceNoGaps > 0 && forceNoGaps[region])
continue;
11959 if(a_gapWidth(nghbrId) >= F0 && !isInsideGapTmp(nghbrId) && a_gapWidth(nghbrId) <= eps3) {
11962 gapCells.p[gapCellCounter++] = nghbrId;
11963 isInsideGapTmp(nghbrId) =
true;
11965 a_nearGapG(nghbrId) =
true;
11966 gapStack.push(nghbrId);
11974 MPI_Allreduce(MPI_IN_PLACE, &cellsAdded, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"cellsAdded");
11977 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
11978 for(
MInt j = 0; j < noWindowCells(i); j++) {
11979 tmp_data(windowCellId(i, j)) = isInsideGapTmp(windowCellId(i, j));
11982 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
11983 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
11984 MInt windowId = grid().azimuthalWindowCell(i, j);
11985 tmp_data(windowId) = isInsideGapTmp(windowId);
11989 exchangeDataLS(&tmp_data(0), 1);
11991 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
11992 for(
MInt j = 0; j < noHaloCells(i); j++) {
11993 const MInt haloCell = haloCellId(i, j);
11994 if(!isInsideGapTmp(haloCell)) {
11995 isInsideGapTmp(haloCell) = tmp_data(haloCell);
11996 if(isInsideGapTmp(haloCell)) {
11998 gapCells.p[gapCellCounter++] = haloCell;
11999 a_nearGapG(haloCell) =
true;
12000 gapStack.push(haloCell);
12005 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12006 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
12007 const MInt haloCell = grid().azimuthalHaloCell(i, j);
12008 if(!isInsideGapTmp(haloCell)) {
12009 isInsideGapTmp(haloCell) = tmp_data(haloCell);
12010 if(isInsideGapTmp(haloCell)) {
12012 gapCells.p[gapCellCounter++] = haloCell;
12013 a_nearGapG(haloCell) =
true;
12014 gapStack.push(haloCell);
12022 if(m_gapInitMethod == 0) {
12023 MPI_Allreduce(MPI_IN_PLACE, &gapCellCounter, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"gapCellCounter");
12026 if(gapCellCounter) {
12027 gapCellCounter = 0;
12028 MInt layerCount = 2;
12031 for(
MInt id = 0;
id < a_noBandCells(0);
id++) {
12033 if(a_nearGapG(cellId)) {
12034 gapCells.p[gapCellCounter++] =
cellId;
12038 while(layerCount < maxNoLayers) {
12039 MInt layerCells = 0;
12040 for(
MInt gc = 0; gc < gapCellCounter; gc++) {
12041 MInt gCellId = gapCells.p[gc];
12042 for(
MInt dir = 0; dir < m_noDirs; dir++) {
12043 if(!a_hasNeighbor(gCellId, dir))
continue;
12044 MInt nghbrId = c_neighborId(gCellId, dir);
12045 if(a_isHalo(nghbrId))
continue;
12046 if(!a_nearGapG(nghbrId)) {
12047 lastLayer.p[layerCells++] = nghbrId;
12048 a_nearGapG(nghbrId) = layerCount;
12055 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12056 for(
MInt j = 0; j < noWindowCells(i); j++) {
12057 tmp_data(windowCellId(i, j)) = a_nearGapG(windowCellId(i, j));
12060 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12061 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
12062 MInt windowId = grid().azimuthalWindowCell(i, j);
12063 tmp_data(windowId) = a_nearGapG(windowId);
12067 exchangeDataLS(&tmp_data(0), 1);
12069 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12070 for(
MInt j = 0; j < noHaloCells(i); j++) {
12071 const MInt haloCell = haloCellId(i, j);
12072 if(!a_nearGapG(haloCell)) {
12073 a_nearGapG(haloCell) = tmp_data(haloCell);
12074 if(a_nearGapG(haloCell)) {
12075 lastLayer.p[layerCells++] = haloCell;
12081 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12082 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
12083 const MInt haloCell = grid().azimuthalHaloCell(i, j);
12084 if(!a_nearGapG(haloCell)) {
12085 a_nearGapG(haloCell) = tmp_data(haloCell);
12086 if(a_nearGapG(haloCell)) {
12087 lastLayer.p[layerCells++] = haloCell;
12094 for(
MInt lc = 0; lc < layerCells; lc++) {
12095 gapCells.p[lc] = lastLayer.p[lc];
12097 gapCellCounter = layerCells;
12118template <MInt nDim>
12125 const MFloat eps2 = (m_gapInitMethod < 2)
12126 ? c_cellLengthAtLevel(a_maxGCellLevel(0)) * (5.0 / 4.0 * sqrt(nDim)) * m_gapDeltaMin * 0.51
12127 : c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * m_gapDeltaMin;
12129 if(gapCellsExist()) {
12130 for(
MInt id = 0;
id < a_noBandCells(0);
id++) {
12132 a_levelSetFunctionG(cellId, 0) -= eps2;
12134 for(
MInt id = 0;
id < a_noBandCells(1);
id++) {
12136 if(a_inBandG(cellId, 0))
continue;
12137 a_levelSetFunctionG(cellId, 0) -= eps2;
12153template <MInt nDim>
12157 MInt noGapCells = m_noGapCells;
12158 MPI_Allreduce(MPI_IN_PLACE, &noGapCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"noGapCells");
12173template <MInt nDim>
12177 return m_noGapCells;
12193template <MInt nDim>
12200 const MFloat eps2 = (m_gapInitMethod < 2)
12201 ? c_cellLengthAtLevel(a_maxGCellLevel(0)) * (5.0 / 4.0 * sqrt(nDim)) * m_gapDeltaMin * 0.51
12202 : c_cellLengthAtLevel(a_maxGCellLevel(0)) * sqrt(nDim) * m_gapDeltaMin;
12205 if(gapCellsExist()) {
12206 for(
MInt id = 0;
id < a_noBandCells(0);
id++) {
12208 a_levelSetFunctionG(cellId, 0) += eps2;
12211 for(
MInt id = 0;
id < a_noBandCells(1);
id++) {
12213 if(a_inBandG(cellId, 0))
continue;
12214 a_levelSetFunctionG(cellId, 0) += eps2;
12229template <MInt nDim>
12236 if(!m_levelSetMb) {
12237 for(
MInt set = 0; set < m_noSets; set++)
12238 m_computeSet[set] = m_computeSet_tmp[set];
12241 if(m_buildCollectedLevelSetFunction) {
12242 setUpPotentialGapCells();
12250 if(m_maxNoSets > 1 || m_GFieldInitFromSTL) {
12252 for(
MInt set = 0; set < m_noSets; set++) {
12253 if(m_noBodiesInSet[set] > 0) body = m_setToBodiesTable[set][0];
12255 a_bodyIdG(cellId, set) = body;
12259 for(
MInt set = 0; set < m_noSets; set++) {
12261 a_bodyIdG(cellId, set) = 0;
12282template <MInt nDim>
12286 if(!m_closeGaps)
return;
12289 MBool& first = m_static_setUpPotentialGapCells_first;
12290 MFloat(&normal)[s_maxNoEmbeddedBodies * 3] = m_static_setUpPotentialGapCells_normal;
12291 MFloat(¢er)[s_maxNoEmbeddedBodies * 3] = m_static_setUpPotentialGapCells_center;
12292 MFloat(&radius)[s_maxNoEmbeddedBodies] = m_static_setUpPotentialGapCells_radius;
12293 MFloat(&height)[s_maxNoEmbeddedBodies] = m_static_setUpPotentialGapCells_height;
12294 MFloat(&normalClose)[s_maxNoEmbeddedBodies * 3] = m_static_setUpPotentialGapCells_normalClose;
12295 MFloat(¢erClose)[s_maxNoEmbeddedBodies * 3] = m_static_setUpPotentialGapCells_centerClose;
12296 MFloat(&radiusClose)[s_maxNoEmbeddedBodies] = m_static_setUpPotentialGapCells_radiusClose;
12297 MFloat(&heightClose)[s_maxNoEmbeddedBodies] = m_static_setUpPotentialGapCells_heightClose;
12298 MInt(&bodyClose)[s_maxNoEmbeddedBodies] = m_static_setUpPotentialGapCells_bodyClose;
12299 MInt& noGapRegionsClose = m_static_setUpPotentialGapCells_noGapRegionsClose;
12301 MFloat rVec[3], hVec[3];
12303 if(m_noBodyBndryCndIds > s_maxNoEmbeddedBodies) {
12304 mTerm(1, AT_,
"Error: Too many embedded Bodies!");
12308 for(
MInt body = 0; body < s_maxNoEmbeddedBodies; body++) {
12309 for(
MInt dir = 0; dir < nDim; dir++) {
12310 normal[body * nDim + dir] = F0;
12311 center[body * nDim + dir] = F0;
12312 normalClose[body * nDim + dir] = F0;
12313 centerClose[body * nDim + dir] = F0;
12315 radius[body] = 1.0;
12316 height[body] = 1.0;
12317 radiusClose[body] = 1.0;
12318 heightClose[body] = 1.0;
12319 normal[body * nDim + 0] = 1.0;
12320 normalClose[body * nDim + 0] = 1.0;
12321 bodyClose[body] = -1;
12336 for(
MInt i = 0; i < m_noGapRegions; i++) {
12337 for(
MInt j = 0; j < nDim; j++) {
12338 normal[i * nDim + j] = Context::getSolverProperty<MFloat>(
"gapRegionNormals", m_solverId, AT_,
12339 &normal[i * nDim + j], i * nDim + j);
12353 for(
MInt i = 0; i < m_noGapRegions; i++) {
12354 for(
MInt j = 0; j < nDim; j++) {
12355 center[i * nDim + j] = Context::getSolverProperty<MFloat>(
"gapRegionCenters", m_solverId, AT_,
12356 ¢er[i * nDim + j], i * nDim + j);
12367 for(
MInt i = 0; i < m_noGapRegions; i++)
12368 radius[i] = Context::getSolverProperty<MFloat>(
"gapRegionRadii", m_solverId, AT_, &radius[i], i);
12371 for(
MInt i = 0; i < m_noGapRegions; i++)
12372 height[i] = Context::getSolverProperty<MFloat>(
"gapRegionHeights", m_solverId, AT_, &height[i], i);
12386 noGapRegionsClose = 0;
12387 noGapRegionsClose = Context::getSolverProperty<MInt>(
"noGapRegionsClose", m_solverId, AT_, &noGapRegionsClose);
12388 ASSERT(noGapRegionsClose <= m_noEmbeddedBodies,
"");
12390 for(
MInt i = 0; i < noGapRegionsClose; i++)
12391 for(
MInt j = 0; j < nDim; j++)
12392 normalClose[i * nDim + j] = Context::getSolverProperty<MFloat>(
"gapRegionNormalsClose", m_solverId, AT_,
12393 &normalClose[i * nDim + j], i * nDim + j);
12395 for(
MInt i = 0; i < noGapRegionsClose; i++)
12396 for(
MInt j = 0; j < nDim; j++)
12397 centerClose[i * nDim + j] = Context::getSolverProperty<MFloat>(
"gapRegionCentersClose", m_solverId, AT_,
12398 ¢erClose[i * nDim + j], i * nDim + j);
12409 for(
MInt i = 0; i < noGapRegionsClose; i++)
12410 radiusClose[i] = Context::getSolverProperty<MFloat>(
"gapRegionRadiiClose", m_solverId, AT_, &radiusClose[i], i);
12424 for(
MInt i = 0; i < noGapRegionsClose; i++)
12425 heightClose[i] = Context::getSolverProperty<MFloat>(
"gapRegionHeightsClose", m_solverId, AT_, &heightClose[i], i);
12439 for(
MInt i = 0; i < m_noGapRegions; i++) {
12440 bodyClose[i] = Context::getSolverProperty<MInt>(
"gapRegionBodyClose", m_solverId, AT_, &bodyClose[i], i);
12441 ASSERT(bodyClose[i] + 1 <= m_noEmbeddedBodies,
"");
12447 ASSERT(m_closeGaps,
"");
12451 for(
MInt gCellId = 0; gCellId < a_noCells(); gCellId++) {
12453 a_potentialGapCell(gCellId) = 0;
12454 a_potentialGapCellClose(gCellId) = 0;
12456 if(a_level(gCellId) == a_maxGCellLevel(0)) {
12457 for(
MInt region = 0; region < m_noGapRegions; region++) {
12460 for(
MInt dir = 0; dir < nDim; dir++) {
12461 rVec[dir] = c_coordinate(gCellId, dir) - center[region * nDim + dir];
12462 hCur += rVec[dir] * normal[region * nDim + dir];
12464 for(
MInt dir = 0; dir < nDim; dir++) {
12465 hVec[dir] = hCur * normal[region * nDim + dir];
12466 rVec[dir] -= hVec[dir];
12467 rCur += rVec[dir] * rVec[dir];
12470 if(rCur < radius[region] && abs(hCur) < height[region]) {
12473 MInt gapRegionId = region + 1;
12474 a_potentialGapCell(gCellId) = gapRegionId;
12478 for(
MInt region = 0; region < noGapRegionsClose; region++) {
12481 for(
MInt dir = 0; dir < nDim; dir++) {
12482 rVec[dir] = c_coordinate(gCellId, dir) - centerClose[region * nDim + dir];
12483 hCur += rVec[dir] * normalClose[region * nDim + dir];
12485 for(
MInt dir = 0; dir < nDim; dir++) {
12486 hVec[dir] = hCur * normalClose[region * nDim + dir];
12487 rVec[dir] -= hVec[dir];
12488 rCur += rVec[dir] * rVec[dir];
12491 if(rCur < radiusClose[region] && abs(hCur) < heightClose[region]) {
12492 if(region >= m_noGapRegions) {
12493 a_potentialGapCellClose(gCellId) = m_G0regionId;
12494 a_potentialGapCell(gCellId) = 0;
12496 MInt closeRegionId = region + 1;
12497 if(bodyClose[region] > -1) {
12498 closeRegionId = bodyClose[region] + 1;
12500 a_potentialGapCellClose(gCellId) = closeRegionId;
12501 a_potentialGapCell(gCellId) = closeRegionId + m_noGapRegions;
12512template <MInt nDim>
12520 std::ignore = datasize;
12523 MIntScratchSpace receiveData(grid().noNeighborDomains(), AT_,
"receiveData");
12527 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12529 sendData.p[i] = sendBufferSize[i];
12530 MPI_Issend(&sendData.p[i], 1, MPI_INT, grid().neighborDomain(i), tag, mpiComm(), &mpi_request[i], AT_,
12535 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12537 MPI_Recv(&receiveData.p[i], (
MInt)1, MPI_INT, grid().neighborDomain(i), tag, mpiComm(), &status, AT_,
12538 "receiveData.p[i]");
12539 receiveBufferSize[i] = receiveData.p[i];
12542 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12543 MPI_Wait(&mpi_request[i], &status, AT_);
12547 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12548 if(sendBufferSize[i] == 0) {
12551 MPI_Issend(m_intSendBuffers[i], sendBufferSize[i], MPI_INT, grid().neighborDomain(i), tag, mpiComm(),
12552 &mpi_request[i], AT_,
"m_intSendBuffers[i]");
12555 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12556 if(receiveBufferSize[i] == 0) {
12559 MPI_Recv(m_intReceiveBuffers[i], receiveBufferSize[i], MPI_INT, grid().neighborDomain(i), tag, mpiComm(), &status,
12560 AT_,
"m_intReceiveBuffers[i]");
12562 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12563 MPI_Wait(&mpi_request[i], &status, AT_);
12568 std::ignore = sendBufferSize;
12569 std::ignore = receiveBufferSize;
12573 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12574 const MInt bufSizeW = noWindowCells(i) * datasize;
12575 if(bufSizeW == 0)
continue;
12576 MPI_Issend(m_intSendBuffers[i], bufSizeW, MPI_INT, grid().neighborDomain(i), 0, mpiComm(), &mpi_request[i], AT_,
12577 "m_intSendBuffers[i]");
12582 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12583 const MInt bufSizeH = noHaloCells(i) * datasize;
12584 if(bufSizeH == 0)
continue;
12585 MPI_Recv(m_intReceiveBuffers[i], bufSizeH, MPI_INT, grid().neighborDomain(i), 0, mpiComm(), &status, AT_,
12586 "m_intReceiveBuffers[i]");
12589 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12590 const MInt bufSizeW = noWindowCells(i) * datasize;
12591 const MInt bufSizeH = noHaloCells(i) * datasize;
12593 if(bufSizeW == 0 || bufSizeH == 0) {
12597 MPI_Wait(&mpi_request[i], MPI_STATUS_IGNORE, AT_);
12606template <MInt nDim>
12607template <
typename T>
12617 mpiSndReqGlob.fill(MPI_REQUEST_NULL);
12625 for(
MInt i = 0; i < grid().noDomains(); i++) {
12626 if(domainId() == i)
continue;
12627 sendData.p[i] = sendBufferSize[i];
12628 MPI_Issend(&sendData.p[i], 1, MPI_INT, i, tag, mpiComm(), &mpiSndReqGlob[i], AT_,
"sendData.p[i]");
12632 for(
MInt i = 0; i < grid().noDomains(); i++) {
12633 if(domainId() == i)
continue;
12634 MPI_Recv(&receiveData.p[i], 1, MPI_INT, i, tag, mpiComm(), &status, AT_,
"receiveData.p[i]");
12635 receiveBufferSize[i] = receiveData.p[i];
12637 for(
MInt i = 0; i < grid().noDomains(); i++) {
12638 if(domainId() == i)
continue;
12639 MPI_Wait(&mpiSndReqGlob[i], &status, AT_);
12643 for(
MInt i = 0; i < grid().noDomains(); i++) {
12644 if(domainId() == i)
continue;
12645 if(sendBufferSize[i] == 0)
continue;
12646 ind = sndOffs[i] * offset;
12647 MPI_Issend(&sendBuffer[ind], sendBufferSize[i], DTYPE, i, (tag + 1), mpiComm(), &mpiSndReqGlob[i], AT_,
12648 "sendBuffer[ind]");
12651 for(
MInt i = 0; i < grid().noDomains(); i++) {
12652 if(domainId() == i)
continue;
12653 if(receiveBufferSize[i] == 0)
continue;
12654 ind = rcvOffs[i] * offset;
12655 MPI_Recv(&receiveBuffer[ind], receiveBufferSize[i], DTYPE, i, (tag + 1), mpiComm(), &status, AT_,
12656 "receiveBuffer[ind]");
12658 for(
MInt i = 0; i < grid().noDomains(); i++) {
12659 if(domainId() == i)
continue;
12660 MPI_Wait(&mpiSndReqGlob[i], &status, AT_);
12664 mpiRcvReqGlob.fill(MPI_REQUEST_NULL);
12666 for(
MInt i = 0; i < grid().noDomains(); i++) {
12667 receiveBufferSize[i] = offset * (rcvOffs[i + 1] - rcvOffs[i]);
12671 for(
MInt i = 0; i < grid().noDomains(); i++) {
12672 if(domainId() == i)
continue;
12673 if(sendBufferSize[i] == 0)
continue;
12674 ind = sndOffs[i] * offset;
12682 MPI_Isend(&sendBuffer[ind], sendBufferSize[i], DTYPE, i, (tag + 1), mpiComm(), &mpiSndReqGlob[i], AT_,
12683 "sendBuffer[ind]");
12687 for(
MInt i = 0; i < grid().noDomains(); i++) {
12688 if(domainId() == i)
continue;
12689 if(receiveBufferSize[i] == 0)
continue;
12690 ind = rcvOffs[i] * offset;
12697 MPI_Irecv(&receiveBuffer[ind], receiveBufferSize[i], DTYPE, i, (tag + 1), mpiComm(), &mpiRcvReqGlob[i], AT_,
12698 "receiveBuffer[ind]");
12700 for(
MInt i = 0; i < grid().noDomains(); i++) {
12701 if(domainId() == i)
continue;
12702 MPI_Wait(&mpiSndReqGlob[i], MPI_STATUS_IGNORE, AT_);
12703 MPI_Wait(&mpiRcvReqGlob[i], MPI_STATUS_IGNORE, AT_);
12715template <MInt nDim>
12719 if(grid().noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0)
return;
12721 exchangeDataLS(&(a_levelSetFunctionG(0, 0)), m_maxNoSets);
12722 if(!m_combustion) {
12723 exchangeDataLS(&(a_bodyIdG(0, 0)), m_maxNoSets);
12726 if(m_semiLagrange) {
12727 exchangeDataLS(&(a_oldLevelSetFunctionG(0, 0)), m_maxNoSets);
12735template <MInt nDim>
12739 if(grid().noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0)
return;
12741 exchangeDataLS(&(a_levelSetFunctionG(0, 0)), m_maxNoSets);
12748template <MInt nDim>
12752 if(grid().noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0)
return;
12754 MInt sendBufferCounter = 0;
12755 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12756 sendBufferCounter = 0;
12757 for(
MInt j = 0; j < noWindowCells(i); j++) {
12758 memcpy((
void*)&m_gSendBuffers[i][sendBufferCounter],
12759 (
void*)&dataField[IDX_LSSET(windowCellId(i, j), firstset)],
12760 dataBlockSize *
sizeof(
MFloat));
12761 sendBufferCounter += dataBlockSize;
12765 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12766 const MInt bufSize = noWindowCells(i) * dataBlockSize;
12767 if(bufSize == 0)
continue;
12768 MPI_Issend(m_gSendBuffers[i], bufSize, MPI_DOUBLE, grid().neighborDomain(i), 0, mpiComm(), &mpi_request[i], AT_,
12769 "m_gSendBuffers[i]");
12773 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12774 const MInt bufSize = noHaloCells(i) * dataBlockSize;
12775 if(bufSize == 0)
continue;
12776 MPI_Recv(m_gReceiveBuffers[i], bufSize, MPI_DOUBLE, grid().neighborDomain(i), 0, mpiComm(), &status, AT_,
12777 "m_gReceiveBuffers[i]");
12780 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12781 const MInt bufSizeW = noWindowCells(i) * dataBlockSize;
12782 const MInt bufSizeH = noHaloCells(i) * dataBlockSize;
12783 if(bufSizeH == 0 || bufSizeW == 0) {
12786 MPI_Wait(&mpi_request[i], &status, AT_);
12789 MInt receiveBufferCounter = 0;
12790 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12791 receiveBufferCounter = 0;
12792 for(
MInt j = 0; j < noHaloCells(i); j++) {
12793 memcpy((
void*)&dataField[IDX_LSSET(haloCellId(i, j), firstset)],
12794 (
void*)&m_gReceiveBuffers[i][receiveBufferCounter],
12795 dataBlockSize *
sizeof(
MFloat));
12796 receiveBufferCounter += dataBlockSize;
12800 if(grid().azimuthalPeriodicity()) {
12801 this->exchangeAzimuthalPer(&dataField[0], dataBlockSize, firstset);
12809template <MInt nDim>
12813 if(grid().noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0)
return;
12815 if(!m_closeGaps)
return;
12818 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12819 for(
MInt j = 0; j < noWindowCells(i); j++) {
12820 tmp_data[windowCellId(i, j)] = a_nearGapG(windowCellId(i, j));
12823 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12824 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
12825 MInt windowId = grid().azimuthalWindowCell(i, j);
12826 tmp_data(windowId) = a_nearGapG(windowId);
12830 exchangeDataLS(&tmp_data[0], 1);
12832 for(
MInt i = 0; i < grid().noNeighborDomains(); i++) {
12833 for(
MInt j = 0; j < noHaloCells(i); j++) {
12834 a_nearGapG(haloCellId(i, j)) = tmp_data[haloCellId(i, j)];
12837 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12838 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
12839 const MInt haloCell = grid().azimuthalHaloCell(i, j);
12840 a_nearGapG(haloCell) = tmp_data[haloCell];
12854template <MInt nDim>
12858 MBool tmpFalse =
false;
12859 MBool tmpTrue =
true;
12861 m_referenceLength = F1;
12872 m_referenceLength = Context::getSolverProperty<MFloat>(
"referenceLength", m_solverId, AT_, &m_referenceLength);
12874 m_referenceVelocity = F1;
12885 m_referenceVelocity =
12886 Context::getSolverProperty<MFloat>(
"referenceVelocity", m_solverId, AT_, &m_referenceVelocity);
12888 if(m_levelSetMb || m_levelSetFv) {
12892 const MFloat Ma = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
12893 const MFloat gammaMinusOne = 1.4 - 1.0;
12894 const MFloat TInfinity = 1.0 / (1.0 + 0.5 * gammaMinusOne *
POW2(Ma));
12895 m_referenceVelocity = sqrt(TInfinity);
12909 m_virtualSurgery =
false;
12910 m_virtualSurgery = Context::getSolverProperty<MBool>(
"virtualSurgery", m_solverId, AT_, &m_virtualSurgery);
12922 m_sphereRadiusLimit = 5.0;
12923 m_sphereRadiusLimit = Context::getSolverProperty<MFloat>(
"sphereRadiusLimit", m_solverId, AT_, &m_sphereRadiusLimit);
12925 if(m_virtualSurgery) {
12934 m_approxNoInterpReg = Context::getSolverProperty<MInt>(
"approxNoInterpRegions", m_solverId, AT_);
12936 if(m_approxNoInterpReg <= 0) {
12937 stringstream errorMessage;
12938 errorMessage <<
"ERROR: Invalid number of interpolation regions. Set approxNoInterpRegions > 0!!!";
12939 mTerm(1, AT_, errorMessage.str());
12950 mAlloc(m_interpStartTime, m_approxNoInterpReg,
"m_interpStartTime", -1, AT_);
12951 for(
MInt i = 0; i < m_approxNoInterpReg; i++) {
12952 m_interpStartTime[i] = Context::getSolverProperty<MInt>(
"interpStartTimes", m_solverId, AT_, i);
12955 stringstream errorMessage;
12956 errorMessage <<
"ERROR: Array length of interpStartTimes and approxNoInterpRegions do not match!!";
12957 mTerm(1, AT_, errorMessage.str());
12969 mAlloc(m_noInterpTimeSteps, m_approxNoInterpReg,
"m_noInterpTimeSteps", -1, AT_);
12970 for(
MInt i = 0; i < m_approxNoInterpReg; i++) {
12971 m_noInterpTimeSteps[i] = Context::getSolverProperty<MInt>(
"noInterpTimeSteps", m_solverId, AT_, i);
12974 stringstream errorMessage;
12975 errorMessage <<
"ERROR: Array length of noInterpTimeSteps and approxNoInterpRegions do not match!!";
12976 mTerm(1, AT_, errorMessage.str());
12985 m_flameSpeed = 0.0;
12986 m_flameSpeed = Context::getSolverProperty<MFloat>(
"flameSpeed", m_solverId, AT_, &m_flameSpeed);
12988 m_jetHalfWidth = 0.5;
12989 m_radiusFlameTube = 0.5;
12990 m_yOffsetFlameTube = 0.04;
12991 m_xOffsetFlameTube = 0.0;
12992 m_marksteinLength = 0.0;
12993 m_marksteinLength = Context::getSolverProperty<MFloat>(
"marksteinLength", m_solverId, AT_, &m_marksteinLength);
12994 m_marksteinLengthPercentage = F1;
12995 m_marksteinLengthPercentage =
12996 Context::getSolverProperty<MFloat>(
"marksteinLengthPercentage", m_solverId, AT_, &m_marksteinLengthPercentage);
12997 m_marksteinLength *= m_marksteinLengthPercentage;
12999 m_xOffsetFlameTube = Context::getSolverProperty<MFloat>(
"xOffsetFlameTube", m_solverId, AT_, &m_xOffsetFlameTube);
13000 m_xOffsetFlameTube2 = Context::getSolverProperty<MFloat>(
"xOffsetFlameTube2", m_solverId, AT_, &m_xOffsetFlameTube);
13001 m_yOffsetFlameTube = Context::getSolverProperty<MFloat>(
"yOffsetFlameTube", m_solverId, AT_, &m_yOffsetFlameTube);
13002 m_yOffsetFlameTube2 = Context::getSolverProperty<MFloat>(
"yOffsetFlameTube2", m_solverId, AT_, &m_yOffsetFlameTube);
13003 m_radiusFlameTube = Context::getSolverProperty<MFloat>(
"radiusFlameTube", m_solverId, AT_, &m_radiusFlameTube);
13004 m_radiusFlameTube2 = Context::getSolverProperty<MFloat>(
"radiusFlameTube2", m_solverId, AT_, &m_radiusFlameTube);
13007 m_trackMovingBndry =
true;
13008 m_trackMbStart = -1;
13009 m_trackMbEnd = numeric_limits<MInt>::max();
13011 m_trackMovingBndry = Context::getSolverProperty<MBool>(
"trackMovingBndry", m_solverId, AT_, &m_trackMovingBndry);
13012 m_trackMbStart = Context::getSolverProperty<MInt>(
"trackMbStart", m_solverId, AT_, &m_trackMbStart);
13013 m_trackMbEnd = Context::getSolverProperty<MInt>(
"trackMbEnd", m_solverId, AT_, &m_trackMbEnd);
13016 m_constructGField =
true;
13017 m_constructGField = Context::getSolverProperty<MBool>(
"constructGField", m_solverId, AT_, &m_constructGField);
13020 m_realRadiusFlameTube = 0.5;
13021 m_realRadiusFlameTube =
13022 Context::getSolverProperty<MFloat>(
"realRadiusFlameTube", m_solverId, AT_, &m_realRadiusFlameTube);
13036 m_forcing = Context::getSolverProperty<MBool>(
"forcing", m_solverId, AT_, &m_forcing);
13038 m_flameRadiusOffset = F0;
13039 m_flameRadiusOffset = Context::getSolverProperty<MFloat>(
"flameRadiusOffset", m_solverId, AT_, &m_flameRadiusOffset);
13041 m_twoFlames =
false;
13042 m_twoFlames = Context::getSolverProperty<MBool>(
"twoFlames", m_solverId, AT_, &tmpFalse);
13044 m_initialFlameHeight = F1;
13045 m_initialFlameHeight =
13046 Context::getSolverProperty<MFloat>(
"initialFlameHeight", m_solverId, AT_, &m_initialFlameHeight);
13048 m_initialCondition = Context::getSolverProperty<MInt>(
"initialCondition", m_solverId, AT_);
13061 m_jetHalfLength = 4.165;
13062 m_jetHalfLength = Context::getSolverProperty<MFloat>(
"jetHalfLength", m_solverId, AT_, &m_jetHalfLength);
13064 m_filterFlameTubeEdgesDistance = -9999.9;
13065 m_filterFlameTubeEdgesDistance = Context::getSolverProperty<MFloat>(
"filterFlameTubeEdgesDistance", m_solverId, AT_,
13066 &m_filterFlameTubeEdgesDistance);
13068 m_filterFlameTubeEdges = Context::getSolverProperty<MBool>(
"filterFlameTubeEdges", m_solverId, AT_, &tmpFalse);
13070 m_noReactionCells = 0.026367201;
13071 m_noReactionCells = Context::getSolverProperty<MFloat>(
"noReactionCells", m_solverId, AT_, &m_noReactionCells);
13074 m_dampingDistanceFlameBase = 0.259;
13075 m_dampingDistanceFlameBase =
13076 Context::getSolverProperty<MFloat>(
"dampingDistanceFlameBase", m_solverId, AT_, &m_dampingDistanceFlameBase);
13078 m_dampingDistanceFlameBaseExtVel = 0.05;
13079 m_dampingDistanceFlameBaseExtVel = Context::getSolverProperty<MFloat>(
"dampingDistanceFlameBaseExtVel", m_solverId,
13080 AT_, &m_dampingDistanceFlameBaseExtVel);
13082 m_useCorrectedBurningVelocity = 0;
13083 m_useCorrectedBurningVelocity =
13084 Context::getSolverProperty<MBool>(
"useCorrectedBurningVelocity", m_solverId, AT_, &m_useCorrectedBurningVelocity);
13087 m_plenum = Context::getSolverProperty<MBool>(
"plenum", m_solverId, AT_, &tmpFalse);
13089 m_timeStepMethod = Context::getSolverProperty<MInt>(
"timeStepMethod", m_solverId, AT_);
13090 m_cfl = Context::getSolverProperty<MFloat>(
"cfl", m_solverId, AT_);
13093 m_steadyFlameLength = -F1;
13105 m_steadyFlameLength = Context::getSolverProperty<MFloat>(
"steadyFlameLength", m_solverId, AT_, &m_steadyFlameLength);
13107 m_maxNoCells = maxNoGridCells();
13122 m_maxNoSets = Context::getSolverProperty<MInt>(
"maxNoLevelSets", m_solverId, AT_, &m_maxNoSets);
13125 m_STLReinitMode = 2;
13141 m_STLReinitMode = Context::getSolverProperty<MInt>(
"GFieldFromSTLReinitMode", m_solverId, AT_, &m_STLReinitMode);
13143 m_noSets = m_maxNoSets;
13145 m_buildCollectedLevelSetFunction =
false;
13146 m_determineG0CellsMode = 0;
13147 m_noBodyBndryCndIds = 1;
13148 m_closeGaps =
false;
13151 m_noEmbeddedBodies = 1;
13154 mAlloc(m_levelSetSign, m_maxNoSets,
"m_levelSetSign", 1, AT_);
13155 mAlloc(m_computeSet, m_maxNoSets,
"m_computeSet",
true, AT_);
13156 mAlloc(m_computeSet_tmp, m_maxNoSets,
"m_computeSet_tmp",
true, AT_);
13157 mAlloc(m_computeSet_backup, m_maxNoSets,
"m_computeSet_backup",
true, AT_);
13158 mAlloc(m_changedSet, m_maxNoSets,
"m_changedSet",
true, AT_);
13160 if(this->m_adaptation) {
13162 m_initialRefinement =
true;
13176 for(
MInt i = 0; i < m_noSets; i++) {
13177 m_levelSetSign[i] = Context::getSolverProperty<MInt>(
"levelSetSign", m_solverId, AT_, &m_levelSetSign[i], i);
13189 for(
MInt i = 0; i < m_noSets; i++) {
13190 m_computeSet_tmp[i] = Context::getSolverProperty<MBool>(
"computeSet", m_solverId, AT_, &m_computeSet_tmp[i], i);
13191 m_computeSet_backup[i] = Context::getSolverProperty<MBool>(
"computeSet", m_solverId, AT_, &m_computeSet_tmp[i], i);
13205 m_GFieldInitFromSTL = tmpFalse;
13206 m_GFieldInitFromSTL = Context::getSolverProperty<MBool>(
"GFieldInitFromSTL", m_solverId, AT_, &m_GFieldInitFromSTL);
13218 m_GFieldFromSTLInitCheck = Context::getSolverProperty<MBool>(
"GFieldFromSTLInitCheck", m_solverId, AT_, &tmpFalse);
13220 if(m_GFieldInitFromSTL) {
13232 m_GWithReConstruction = Context::getSolverProperty<MBool>(
"levelSetWithSTLCorrection", m_solverId, AT_, &tmpFalse);
13235 m_reconstructBand = Context::getSolverProperty<MInt>(
"reconstructBand", m_solverId, AT_, &m_reconstructBand);
13238 if(m_maxNoSets > 1) {
13251 m_buildCollectedLevelSetFunction = Context::getSolverProperty<MBool>(
"buildCollectedLevelSetFunction", m_solverId,
13252 AT_, &m_buildCollectedLevelSetFunction);
13255 MInt movingBndryCndId = 3006;
13268 movingBndryCndId = Context::getSolverProperty<MInt>(
"movingBndryCndId", m_solverId, AT_, &movingBndryCndId);
13270 m_noEmbeddedBodies = 1;
13283 m_noEmbeddedBodies = Context::getSolverProperty<MInt>(
"noEmbeddedBodies", m_solverId, AT_, &m_noEmbeddedBodies);
13284 m_noBodyBndryCndIds = m_noEmbeddedBodies;
13286 if(m_noBodyBndryCndIds > 0) {
13287 mAlloc(m_bodyBndryCndIds, m_noBodyBndryCndIds,
"m_bodyBndryCndIds", movingBndryCndId, AT_);
13303 if(m_noBodyBndryCndIds > 0) {
13304 mAlloc(m_bodyBndryCndIds, m_noBodyBndryCndIds,
"m_bodyBndryCndIds", 0, AT_);
13306 for(
MInt i = 0; i < m_noBodyBndryCndIds; i++) {
13307 m_bodyBndryCndIds[i] = Context::getSolverProperty<MInt>(
"bodyBndryCndIds", m_solverId, AT_, i);
13309 if(m_noBodyBndryCndIds > 1) {
13310 m_noEmbeddedBodies = m_noBodyBndryCndIds;
13315 if((m_GFieldInitFromSTL && useBodyToSetTable) || m_maxNoSets > 1) {
13316 setUpBodyToSetTable();
13331 m_highOrderDeltaFunction = Context::getSolverProperty<MBool>(
"highOrderDeltaFunction", m_solverId, AT_, &tmpFalse);
13345 m_fourthOrderNormalCurvatureComputation =
13346 Context::getSolverProperty<MBool>(
"fourthOrderNormalCurvatureComputation", m_solverId, AT_, &tmpFalse);
13348 if(m_combustion && m_fourthOrderNormalCurvatureComputation) {
13349 stringstream errorMessage;
13350 errorMessage <<
"ERROR: fourthOrderNormalCurvatureCompuatation should not be used, pockets are not correctly "
13351 "generated ... exiting";
13352 mTerm(1, AT_, errorMessage.str());
13367 m_curvatureDamp = Context::getSolverProperty<MBool>(
"curvatureDamp", m_solverId, AT_, &tmpFalse);
13369 m_curvatureDampFactor = F3;
13381 m_curvatureDampFactor =
13382 Context::getSolverProperty<MFloat>(
"curvatureDampFactor", m_solverId, AT_, &m_curvatureDampFactor);
13396 m_sharpDamp = Context::getSolverProperty<MBool>(
"sharpDamp", m_solverId, AT_, &tmpFalse);
13408 m_useLocalMarksteinLength = Context::getSolverProperty<MBool>(
"useLocalMarksteinLength", m_solverId, AT_, &tmpFalse);
13422 m_hyperbolicCurvature = Context::getSolverProperty<MBool>(
"hyperbolicCurvature", m_solverId, AT_, &tmpFalse);
13441 m_gRKMethod = Context::getSolverProperty<MInt>(
"gRKMethod", m_solverId, AT_);
13462 m_levelSetDiscretizationScheme = Context::getSolverProperty<MString>(
"levelSetDiscretizationScheme", m_solverId, AT_);
13471 m_LsRotate =
false;
13472 m_LsRotate = Context::getSolverProperty<MBool>(
"LsRotate", m_solverId, AT_, &m_LsRotate);
13475 m_reconstructOldG = Context::getSolverProperty<MBool>(
"reconstructOldG", m_solverId, AT_, &m_reconstructOldG);
13477 m_reconstructOldG =
false;
13491 m_gBandWidth = Context::getSolverProperty<MInt>(
"gBandWidth", m_solverId, AT_);
13504 m_gShadowWidth = Context::getSolverProperty<MInt>(
"gShadowWidth", m_solverId, AT_);
13516 if(m_levelSetRans) {
13517 m_gShadowWidthRans = Context::getSolverProperty<MInt>(
"gShadowWidthRans", m_solverId, AT_);
13531 m_gInnerBound = Context::getSolverProperty<MInt>(
"gInnerBound", m_solverId, AT_);
13533 ASSERT(m_gInnerBound >= 2,
"Should be at least 2!");
13549 TERMM(1,
"Warning: maxGCellLevel has only one set! Use maxRfnmntLvl instead!");
13552 m_gCellLevelJump =
true;
13554 ASSERT(m_semiLagrange && !m_LsRotate,
"");
13557 mAlloc(m_maxGCellLevel, m_maxNoSets,
"m_maxGCellLevel", 0, AT_);
13561 for(
MInt set = 0; set < m_maxNoSets; set++) {
13562 m_maxGCellLevel[set] = Context::getSolverProperty<MInt>(
"maxGCellLevel", m_solverId, AT_, set);
13563 ASSERT(m_maxGCellLevel[set] <= maxRefinementLevel() && m_maxGCellLevel[set] >= minLevel(),
"");
13567 mAlloc(m_maxGCellLevel, 1,
"m_maxGCellLevel", 0, AT_);
13568 m_maxGCellLevel[0] = Context::getSolverProperty<MInt>(
"maxRfnmntLvl", m_solverId, AT_);
13570 ASSERT(m_maxGCellLevel[0] == maxRefinementLevel(),
13571 "maxGCellLevel " + to_string(m_maxGCellLevel[0]) +
" maxLevel " + to_string(maxRefinementLevel()));
13574 m_maxLevelChange =
false;
13575 if(
globalTimeStep > 0 && m_restartFile && isActive() && maxLevel() != maxRefinementLevel()) {
13576 m_maxLevelChange =
true;
13577 if(domainId() == 0) {
13578 cerr <<
"MaxLevel is " << maxLevel() <<
" and maxRefinementLevel is " << maxRefinementLevel()
13579 <<
" => temporarily reduction of m_maxGCellLevel to MaxLevel!" << endl;
13581 m_maxGCellLevel[0] = maxLevel();
13584 if(this->m_noSensors > 0) {
13585 if(
globalTimeStep > 0 && m_restartFile && isActive() && this->m_adaptation
13586 && maxLevel() > this->m_maxSensorRefinementLevel[0]) {
13587 m_maxLevelChange =
true;
13588 if(domainId() == 0) {
13589 cerr <<
"MaxLevel is " << maxLevel() <<
" and maxSensorLevel is " << this->m_maxSensorRefinementLevel[0]
13590 <<
" => temporarily increase of m_maxGCellLevel to MaxLevel!" << endl;
13592 ASSERT(m_maxGCellLevel[0] == maxLevel(),
"");
13596 m_gCellDistance = c_cellLengthAtLevel(m_maxGCellLevel[0]);
13597 m_FgCellDistance = F1 / m_gCellDistance;
13598 m_log <<
"smallest gCell length " << m_gCellDistance << endl;
13600 m_outsideGValue = (
MFloat)(2 * m_gBandWidth * m_gCellDistance);
13601 m_log <<
"Outside G value: " << m_outsideGValue << endl;
13603 m_computeExtVel = 1;
13630 m_computeExtVel = Context::getSolverProperty<MInt>(
"computeExtVel", m_solverId, AT_, &m_computeExtVel);
13632 m_smoothExtVel =
true;
13644 m_smoothExtVel = Context::getSolverProperty<MBool>(
"smoothExtVel", m_solverId, AT_, &tmpTrue);
13646 m_extVelIterations = 10000;
13656 m_extVelIterations = Context::getSolverProperty<MInt>(
"extVelIterations", m_solverId, AT_, &m_extVelIterations);
13669 m_extVelConvergence = Context::getSolverProperty<MFloat>(
"extVelConvergence", m_solverId, AT_);
13681 m_extVelCFL = Context::getSolverProperty<MFloat>(
"extVelCFL", m_solverId, AT_, &m_extVelCFL);
13709 m_reinitMethod = Context::getSolverProperty<MString>(
"reinitMethod", m_solverId, AT_);
13711 m_noGapRegions = 0;
13712 m_gapInitMethod = 2;
13715 if(m_buildCollectedLevelSetFunction) {
13728 m_gapReinitMethod = Context::getSolverProperty<MString>(
"gapReinitMethod", m_solverId, AT_, &m_reinitMethod);
13740 m_closeGaps = Context::getSolverProperty<MBool>(
"closeGaps", m_solverId, AT_, &m_closeGaps);
13752 m_determineG0CellsMode =
13753 Context::getSolverProperty<MBool>(
"determineG0Mode", m_solverId, AT_, &m_determineG0CellsMode);
13768 m_noGapRegions = Context::getSolverProperty<MInt>(
"noGapRegions", m_solverId, AT_, &m_noGapRegions);
13770 ASSERT(m_noGapRegions > 0,
"");
13787 m_G0regionId = Context::getSolverProperty<MInt>(
"G0regionId", m_solverId, AT_, &m_G0regionId);
13804 m_gapInitMethod = Context::getSolverProperty<MInt>(
"gapInitMethod", 0, AT_, &m_gapInitMethod);
13818 m_forceNoGaps = Context::getSolverProperty<MInt>(
"forceNoGaps", m_solverId, AT_, &m_forceNoGaps);
13820 if(m_forceNoGaps == 1) {
13822 mAlloc(m_gapAngleClose, m_noGapRegions,
"m_gapAngleClose", F0, AT_);
13823 mAlloc(m_gapAngleOpen, m_noGapRegions,
"m_gapAngleOpen", F0, AT_);
13824 mAlloc(m_gapSign, m_noGapRegions,
"m_gapSign", F1, AT_);
13826 for(
MInt i = 0; i < m_noGapRegions; i++) {
13827 m_gapAngleClose[i] =
13828 Context::getSolverProperty<MFloat>(
"gapAngleClose", m_solverId, AT_, &m_gapAngleClose[i], i);
13829 m_gapAngleOpen[i] =
13830 Context::getSolverProperty<MFloat>(
"gapAngleOpen", m_solverId, AT_, &m_gapAngleClose[i], i);
13831 if(m_gapAngleClose[i] < 0.0) {
13832 m_gapAngleClose[i] = 720 + m_gapAngleClose[i];
13834 if(m_gapAngleOpen[i] < 0.0) {
13835 m_gapAngleOpen[i] = 720 + m_gapAngleOpen[i];
13837 if(m_gapAngleOpen[i] > m_gapAngleClose[i]) {
13841 }
else if(m_forceNoGaps == 2) {
13843 ASSERT(m_noGapRegions == 1,
"Mode only intended for 1 gap-region!");
13845 mAlloc(m_gapAngleClose, m_noGapRegions + 1,
"m_gapAngleClose", F0, AT_);
13846 mAlloc(m_gapAngleOpen, m_noGapRegions + 1,
"m_gapAngleOpen", F0, AT_);
13847 mAlloc(m_gapSign, m_noGapRegions + 1,
"m_gapSign", F1, AT_);
13851 for(
MInt i = 0; i < m_noGapRegions + 1; i++) {
13852 m_gapAngleClose[i] =
13853 Context::getSolverProperty<MFloat>(
"gapAngleClose", m_solverId, AT_, &m_gapAngleClose[i], i);
13854 m_gapAngleOpen[i] =
13855 Context::getSolverProperty<MFloat>(
"gapAngleOpen", m_solverId, AT_, &m_gapAngleClose[i], i);
13856 if(m_gapAngleClose[i] < 0.0) {
13857 m_gapAngleClose[i] = 720 + m_gapAngleClose[i];
13859 if(m_gapAngleOpen[i] < 0.0) {
13860 m_gapAngleOpen[i] = 720 + m_gapAngleOpen[i];
13862 if(m_gapAngleOpen[i] > m_gapAngleClose[i]) {
13867 mAlloc(m_gapAngleClose, m_noGapRegions,
"m_gapAngleClose", F0, AT_);
13868 mAlloc(m_gapAngleOpen, m_noGapRegions,
"m_gapAngleOpen", F0, AT_);
13869 mAlloc(m_gapSign, m_noGapRegions,
"m_gapSign", F1, AT_);
13873 m_gapDeltaMin = F1;
13874 m_gapDeltaMinOrig = F1;
13886 m_gapDeltaMin = Context::getSolverProperty<MFloat>(
"deltaMin", m_solverId, AT_, &m_gapDeltaMin);
13888 m_gapDeltaMinOrig = m_gapDeltaMin;
13900 m_gReinitIterations = Context::getSolverProperty<MInt>(
"gReinitIterations", m_solverId, AT_);
13902 m_minReinitializationSteps = m_gReinitIterations;
13912 m_minReinitializationSteps =
13913 Context::getSolverProperty<MInt>(
"minReinitializationSteps", m_solverId, AT_, &m_minReinitializationSteps);
13915 m_maintenanceIterations = m_gReinitIterations;
13927 m_maintenanceIterations =
13928 Context::getSolverProperty<MInt>(
"maintenanceIterations", m_solverId, AT_, &m_maintenanceIterations);
13942 m_guaranteeReinit = Context::getSolverProperty<MBool>(
"guaranteeReinit", m_solverId, AT_, &tmpFalse);
13944 if(!m_guaranteeReinit && m_closeGaps) {
13945 ASSERT(m_gapDeltaMin < 1.00000001, "Reinitialisation is required if deltaMin > 1 is used!
");
13959 m_reinitCFL = Context::getSolverProperty<MFloat>("reinitCFL
", m_solverId, AT_);
13961 m_intermediateReinitIterations = 1;
13972 m_intermediateReinitIterations = Context::getSolverProperty<MInt>("intermediateReinitIterations
", m_solverId, AT_,
13973 &m_intermediateReinitIterations);
13985 m_reinitConvergence = Context::getSolverProperty<MFloat>("reinitConvergence
", m_solverId, AT_);
13986 m_reinitConvergenceReset = m_reinitConvergence;
13988 m_reinitThreshold = F0;
14003 m_reinitThreshold = Context::getSolverProperty<MFloat>("reinitThreshold
", m_solverId, AT_, &m_reinitThreshold);
14005 m_reinitThresholdAvg = F0;
14019 m_reinitThresholdAvg =
14020 Context::getSolverProperty<MFloat>("reinitThresholdAvg
", m_solverId, AT_, &m_reinitThresholdAvg);
14022 m_omegaReinit = F1;
14032 m_omegaReinit = Context::getSolverProperty<MFloat>("omegaReinit
", m_solverId, AT_, &m_omegaReinit);
14034 m_relaxationFactor = 0.5;
14046 m_relaxationFactor = Context::getSolverProperty<MFloat>("relaxationFactor
", m_solverId, AT_, &m_relaxationFactor);
14048 m_levelSetTestCase = 0;
14081 m_levelSetTestCase = Context::getSolverProperty<MInt>("levelSetTestCase
", m_solverId, AT_, &m_levelSetTestCase);
14083 m_levelSetBoundaryCondition = m_levelSetTestCase;
14101 m_levelSetBoundaryCondition =
14102 Context::getSolverProperty<MInt>("levelSetBoundaryCondition
", m_solverId, AT_, &m_levelSetBoundaryCondition);
14116 m_levelSetBC = Context::getSolverProperty<MString>("levelSetBC
", m_solverId, AT_, &m_levelSetBC);
14118 // only relevant for m_levelSetBoundaryCondition = 1751600!
14119 m_noHaloLayers = 1;
14131 m_noHaloLayers = Context::getSolverProperty<MInt>("noHaloLayers
", m_solverId, AT_, &m_noHaloLayers);
14133 if(m_fourthOrderNormalCurvatureComputation) {
14134 ASSERT(m_noHaloLayers > 1, "Not enough halo layer
for fourth order curvature computation
");
14137 m_reinitInterval = 1;
14149 m_reinitInterval = Context::getSolverProperty<MInt>("reinitInterval
", m_solverId, AT_, &m_reinitInterval);
14160 m_maintainOuterBandLayers = Context::getSolverProperty<MBool>("maintainOuterBandLayers
", m_solverId, AT_, &tmpFalse);
14189 m_writeReinitializationStatistics =
14190 Context::getSolverProperty<MBool>("writeReinitializationStatistics
", m_solverId, AT_, &tmpFalse);
14203 m_interpolateFlowFieldToFlameFront =
14204 Context::getSolverProperty<MBool>("interpolateFlowFieldToFlameFront
", m_solverId, AT_, &tmpFalse);
14218 m_writeOutAllLevelSetFunctions =
14219 Context::getSolverProperty<MBool>("writeOutAllLevelSetFunctions
", m_solverId, AT_, &tmpFalse);
14232 m_writeOutAllExtensionVelocities =
14233 Context::getSolverProperty<MBool>("writeOutAllExtensionVelocities
", m_solverId, AT_, &tmpFalse);
14245 m_writeOutAllCurvatures = Context::getSolverProperty<MBool>("writeOutAllCurvatures
", m_solverId, AT_, &tmpFalse);
14258 m_writeOutAllCorrectedBurningVelocity =
14259 Context::getSolverProperty<MBool>("writeOutAllCorrectedBurningVelocity
", m_solverId, AT_, &tmpFalse);
14271 m_writeOutAllFlameSpeeds = Context::getSolverProperty<MBool>("writeOutAllFlameSpeeds
", m_solverId, AT_, &tmpFalse);
14285 m_writeOutAllNormalVectors =
14286 Context::getSolverProperty<MBool>("writeOutAllNormalVectors
", m_solverId, AT_, &tmpFalse);
14288 if(string2enum(m_reinitMethod) == HCR2_FULLREINIT) {
14289 // output info min iteration
14290 MInt minIteration = m_gBandWidth / m_reinitCFL;
14291 m_log << "reinitMethod:
HCR2_FULLREINIT -> full reinitialization guaranteed after
" << minIteration << " iterations
"
14296 // compute minimum iterations to transport the velocity to the band cells
14297 MInt minIteration = m_gBandWidth / m_extVelCFL;
14298 m_log << "number of minimum iterations necessary to extend velocity field on band
" << minIteration << endl;
14299 m_log << "number of iterations set to extend velocity field on band
" << m_extVelIterations << endl;
14309 m_engineSetup = Context::getSolverProperty<MBool>("engineSetup
", m_solverId, AT_, &m_engineSetup);
14312 mAlloc(m_outerBandWidth, maxRefinementLevel() + 1, "m_outerBandWidth
", 0, AT_);
14313 m_outerBandWidth[maxRefinementLevel()] = m_gShadowWidth;
14314 for(MInt lvl = maxRefinementLevel() - 1; lvl >= 0; lvl--) {
14315 MInt dif = (maxRefinementLevel() - lvl);
14316 m_outerBandWidth[lvl] = (m_outerBandWidth[lvl + 1] / 2) + 1 + dif;
14318 } else if(m_combustion) {
14319 mAlloc(m_outerBandWidth, maxRefinementLevel() + 1, "m_outerBandWidth
", 0, AT_);
14320 m_outerBandWidth[maxRefinementLevel()] = m_gShadowWidth;
14321 for(MInt lvl = maxRefinementLevel() - 1; lvl >= 0; lvl--) {
14322 MInt factor = IPOW2((maxRefinementLevel() - lvl));
14323 MInt currentWidth = m_gShadowWidth / factor;
14324 if(currentWidth * factor < m_gShadowWidth) {
14327 m_outerBandWidth[lvl] = currentWidth;
14329 } else if(m_engineSetup) {
14330 mAlloc(m_outerBandWidth, maxRefinementLevel() + 1, "m_outerBandWidth
", 0, AT_);
14331 m_outerBandWidth[maxRefinementLevel()] = m_gShadowWidth + 2;
14332 for(MInt lvl = maxRefinementLevel() - 1; lvl >= 0; lvl--) {
14333 MInt val = m_outerBandWidth[lvl + 1] / 2;
14334 if(val * 2 < m_outerBandWidth[lvl + 1]) {
14337 m_outerBandWidth[lvl] = val;
14339 } else if(m_levelSetRans) {
14340 mAlloc(m_outerBandWidth, maxRefinementLevel(), "m_outerBandWidth
", 0, AT_);
14341 m_outerBandWidth[maxRefinementLevel() - 1] = m_gShadowWidthRans;
14342 for(MInt i = maxRefinementLevel() - 2; i >= 0; i--) {
14343 m_outerBandWidth[i] = (m_outerBandWidth[i + 1] / 2) + 1;
14346 mAlloc(m_outerBandWidth, maxRefinementLevel(), "m_outerBandWidth
", 0, AT_);
14347 m_outerBandWidth[maxRefinementLevel() - 1] = m_gShadowWidth;
14348 for(MInt i = maxRefinementLevel() - 2; i >= 0; i--) {
14349 m_outerBandWidth[i] = (m_outerBandWidth[i + 1] / 2) + 1;
14353 m_refineDiagonals = true;
14364 if(m_LsRotate) m_refineDiagonals = false;
14365 m_refineDiagonals = Context::getSolverProperty<MBool>("refineDiagonals
", m_solverId, AT_, &m_refineDiagonals);
14367 m_bodyIdOutput = m_semiLagrange;
14377 m_bodyIdOutput = Context::getSolverProperty<MBool>("bodyIdOutput
", m_solverId, AT_, &m_bodyIdOutput);
14380 if(m_noInitGFieldFromSTLBndCndIds + m_noBodyBndryCndIds > 0) {
14381 mAlloc(m_initGFieldFromSTLBndCndIds, m_noInitGFieldFromSTLBndCndIds + m_noBodyBndryCndIds,
14382 "m_initGFieldFromSTLBndCndIds
", -1, AT_);
14384 MInt defaultValue = -1;
14385 for(MInt i = 0; i < m_noBodyBndryCndIds; i++) {
14386 m_initGFieldFromSTLBndCndIds[i] = m_bodyBndryCndIds[i];
14388 m_noInitGFieldFromSTLBndCndIds += m_noBodyBndryCndIds;
14389 for(MInt i = m_noBodyBndryCndIds; i < m_noInitGFieldFromSTLBndCndIds; i++) {
14390 m_initGFieldFromSTLBndCndIds[i] = Context::getSolverProperty("GFieldInitFromSTLBndCndIds
", m_solverId, AT_,
14391 &defaultValue, i - m_noBodyBndryCndIds);
14404 if(Context::propertyExists("LsGeometryChange
", m_solverId)) {
14405 m_forceAdaptation = true;
14407 mAlloc(m_geometryChange, m_noSets, "geometryChange
", false, AT_);
14409 MBool anychange = false;
14410 for(MInt set = 0; set < m_noSets; set++) {
14411 m_geometryChange[set] =
14412 Context::getSolverProperty<MBool>("LsGeometryChange
", m_solverId, AT_, &m_geometryChange[set], set);
14413 if(m_geometryChange[set]) {
14415 if(domainId() == 0) {
14416 cerr << "Changing geometry of set
" << set << " upon restart!
" << endl;
14422 mDeallocate(m_geometryChange);
14423 ASSERT(m_geometryChange == nullptr, "");
14427 m_periodicMovement = false;
14428 if(Context::propertyExists("periodicMovement
", m_solverId)) {
14429 m_periodicMovement = Context::getSolverProperty<MBool>("periodicMovement
", m_solverId, AT_, &m_periodicMovement);
14430 m_periodicDirection = Context::getSolverProperty<MInt>("periodicDirection
", m_solverId, AT_, &m_periodicDirection);
14440 m_weightBaseCell = 1.0;
14441 m_weightBaseCell = Context::getSolverProperty<MFloat>("weightBaseCell
", solverId(), AT_, &m_weightBaseCell);
14451 m_weightLeafCell = 1.0;
14452 m_weightLeafCell = Context::getSolverProperty<MFloat>("weightLeafCell
", solverId(), AT_, &m_weightLeafCell);
14462 m_weightBandCell = 1.0;
14463 m_weightBandCell = Context::getSolverProperty<MFloat>("weightBandCell
", solverId(), AT_, &m_weightBandCell);
14474 m_weightMulitSolverFactor = 1.0;
14475 m_weightMulitSolverFactor =
14476 Context::getSolverProperty<MFloat>("weightMulitSolverFactor
", solverId(), AT_, &m_weightMulitSolverFactor);
14486 m_limitWeights = false;
14487 m_limitWeights = Context::getSolverProperty<MBool>("limitDLBWeights
", solverId(), AT_, &m_limitWeights);
14498 m_weightLevelSet = true;
14499 m_weightLevelSet = Context::getSolverProperty<MBool>("weightLevelSet
", solverId(), AT_, &m_weightLevelSet);
14505template <MInt nDim>
14506void LsCartesianSolver<nDim>::preTimeStep() {
14509 if(m_combustion || m_freeSurface) {
14510 exchangeAllLevelSetData();
14512 setGCellBndryProperty();
14514 updateBndryCellList();
14516 if(string2enum(m_levelSetBC) == PERIODIC) {
14517 computeNormalVectorsPeriodic();
14519 computeCurvaturePeriodic();
14521 computeNormalVectors();
14523 computeCurvature();
14525 // constructExtensionVelocity(); //this is now done in the coupler
14526 } else if(!m_levelSetMb) {
14527 setGCellBndryProperty();
14529 if(!m_semiLagrange) {
14530 computeNormalVectors();
14532 computeCurvature();
14534 determinePropagationSpeed();
14537 } else if(m_levelSetMb) {
14538 if(m_constructGField != 0) return;
14542 static MBool firstRun = true;
14545 for(MInt set = 0; set < m_noSets; set++) {
14546 m_computeSet[set] = m_computeSet_tmp[set];
14547 m_changedSet[set] = true;
14552 for(MInt set = 0; set < m_noSets; set++) {
14553 ASSERT(m_computeSet[set] == m_computeSet_backup[set], "ERROR in m_computeSet
");
14556 m_time += timeStep();
14571template <MInt nDim>
14572void LsCartesianSolver<nDim>::buildMultipleLevelSet(const MInt mode) {
14575 if(!m_buildCollectedLevelSetFunction) return;
14577 NEW_TIMER_GROUP_STATIC(buildMultipleLevelSet, "MultipleLevelset
");
14578 NEW_TIMER_STATIC(t_multiLevelSet, "Total time - multiple-levelset
", buildMultipleLevelSet);
14579 NEW_SUB_TIMER_STATIC(t_c1, "identifyBodies
", t_multiLevelSet);
14580 NEW_SUB_TIMER_STATIC(t_c2, "collectedLevelSet
", t_multiLevelSet);
14581 NEW_SUB_TIMER_STATIC(t_c3, "gapHandling
", t_multiLevelSet);
14582 NEW_SUB_TIMER_STATIC(t_c4, "gapCells
", t_multiLevelSet);
14583 NEW_SUB_TIMER_STATIC(t_c5, "gapReInit
", t_multiLevelSet);
14584 NEW_SUB_TIMER_STATIC(t_c6, "Tube0
", t_multiLevelSet);
14585 NEW_SUB_TIMER_STATIC(t_c7, "curv+normal
", t_multiLevelSet);
14587 RECORD_TIMER_START(t_multiLevelSet);
14591 // initialisation version
14594 // TODO labels:LS,TIMERS update default to faster shifting version after further testing!
14595 RECORD_TIMER_START(t_c1);
14597 RECORD_TIMER_STOP(t_c1);
14600 RECORD_TIMER_START(t_c2);
14601 // generares the coorect collected levelSet!
14602 // the bodies need to be identified before!
14603 buildCollectedLevelSet(mode);
14605 buildLevelSetTube(0);
14606 RECORD_TIMER_STOP(t_c2);
14608 RECORD_TIMER_START(t_c3);
14610 RECORD_TIMER_STOP(t_c3);
14612 RECORD_TIMER_START(t_c4);
14613 // if gaps exist, solve this
14614 if(m_closeGaps && gapCellsExist()) {
14615 // levelSet value reduction for G0-Band cells
14616 levelSetGapCorrect();
14618 RECORD_TIMER_START(t_c6);
14619 buildLevelSetTube(0);
14620 RECORD_TIMER_STOP(t_c6);
14622 setBandNewArrivals(0);
14624 RECORD_TIMER_START(t_c7);
14625 if(m_guaranteeReinit) {
14626 computeNormalVectors(0);
14627 computeCurvature(0);
14629 RECORD_TIMER_STOP(t_c7);
14631 RECORD_TIMER_START(t_c5);
14632 if(m_guaranteeReinit) {
14633 levelSetReinitialization(0);
14635 RECORD_TIMER_STOP(t_c5);
14637 // levelSet value increase for G0-Band cells
14638 levelSetGapRecorrect();
14640 reBuildCollectedLevelSet(1);
14642 RECORD_TIMER_START(t_c6);
14643 buildLevelSetTube(0);
14644 RECORD_TIMER_STOP(t_c6);
14646 setBandNewArrivals(0);
14649 RECORD_TIMER_STOP(t_c4);
14651 exchangeAllLevelSetData();
14653 if(!m_semiLagrange) {
14654 computeNormalVectors(0);
14655 computeCurvature(0);
14656 exchangeAllLevelSetData();
14659 RECORD_TIMER_STOP(t_multiLevelSet);
14666template <MInt nDim>
14667MBool LsCartesianSolver<nDim>::_levelSetSolutionStep() {
14670 if(m_freeSurface) {
14671 updateBndryCellList();
14672 return levelSetSolver();
14674 } else if(m_combustion) {
14675 updateBndryCellList();
14676 applyLevelSetBoundaryConditions();
14677 return levelSetSolver();
14679 } else if(!m_levelSetMb && m_semiLagrange) {
14680 applyLevelSetBoundaryConditions();
14681 return semiLagrangeTimeStep();
14683 } else if(!m_levelSetMb) {
14684 applyLevelSetBoundaryConditions();
14685 return levelSetSolver();
14687 } else if(m_levelSetMb) {
14688 ASSERT(!m_constructGField, "");
14689 ASSERT(m_semiLagrange, "");
14690 return semiLagrangeTimeStep();
14701template <MInt nDim>
14702MBool LsCartesianSolver<nDim>::finalizeLevelSet_(const MInt t_levelSet, const MInt t_output) {
14705 // Necessary to avoid 'unused-parameter' warning when timers are disabled
14706 static_cast<void>(t_levelSet);
14707 static_cast<void>(t_output);
14709 NEW_SUB_TIMER_STATIC(t_levelSetGGrid, "GGrid
", t_levelSet);
14710 NEW_SUB_TIMER_STATIC(t_levelSetFastGGrid, "FastGGrid
", t_levelSet);
14711 NEW_SUB_TIMER_STATIC(t_levelSetCR, "CR
", t_levelSet);
14713 RECORD_TIMER_START(t_levelSetGGrid);
14714 buildLevelSetTube();
14715 setBandNewArrivals();
14716 RECORD_TIMER_STOP(t_levelSetGGrid);
14718 // reinitializes the level set function
14719 RECORD_TIMER_START(t_levelSetCR);
14720 levelSetReinitialization();
14721 RECORD_TIMER_STOP(t_levelSetCR);
14723 RECORD_TIMER_START(t_levelSetFastGGrid);
14724 fastBuildLevelSetTubeCG();
14725 RECORD_TIMER_STOP(t_levelSetFastGGrid);
14728 determineMinMaxMeanInterfacePosition();
14736template <MInt nDim>
14737MBool LsCartesianSolver<nDim>::solutionStep() {
14740 if(m_constructGField) return true;
14742 if(!m_trackMovingBndry || globalTimeStep < m_trackMbStart || globalTimeStep > m_trackMbEnd) {
14746 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
14747 m_firstSolutionExchange = true;
14748 MBool timeStepCompleted = _levelSetSolutionStep();
14749 exchangeLeafDataLS<true>();
14750 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
14752 return timeStepCompleted;
14759template <MInt nDim>
14760void LsCartesianSolver<nDim>::finalizeLevelSet() {
14763 RECORD_TIMER_START(m_timers[Timers::Finalize]);
14765 if(m_combustion || m_freeSurface) {
14766 buildLevelSetTube();
14767 setBandNewArrivals();
14769 // rebuilds the tube and reinitializes the level set function
14770 levelSetReinitialization();
14772 } else if(m_semiLagrange) {
14773 if(m_constructGField) {
14779 // for the individual sets
14780 RECORD_TIMER_START(m_timers[Timers::BuildTube]);
14781 buildLevelSetTube();
14782 RECORD_TIMER_STOP(m_timers[Timers::BuildTube]);
14784 RECORD_TIMER_START(m_timers[Timers::SetBand]);
14785 setBandNewArrivals();
14786 RECORD_TIMER_STOP(m_timers[Timers::SetBand]);
14788 // for the collected levelset
14789 RECORD_TIMER_START(m_timers[Timers::BuildMultiple]);
14790 buildMultipleLevelSet();
14791 RECORD_TIMER_STOP(m_timers[Timers::BuildMultiple]);
14796 buildLevelSetTube();
14798 setBandNewArrivals();
14800 computeNormalVectors();
14802 computeCurvature();
14804 levelSetReinitialization();
14806 buildMultipleLevelSet();
14809 RECORD_TIMER_STOP(m_timers[Timers::Finalize]);
14816template <MInt nDim>
14817void LsCartesianSolver<nDim>::determinePeriodicDistance() {
14820 // Determine local minimum ans maximum
14821 MFloat minPos = std::numeric_limits<MFloat>::max();
14822 MFloat maxPos = std::numeric_limits<MFloat>::lowest();
14823 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14824 if(a_isHalo(cellId)) continue;
14825 MInt level = a_level(cellId);
14826 MFloat cellHalfLength = 0.5 * c_cellLengthAtLevel(level);
14827 if(c_coordinate(cellId, m_periodicDirection) - cellHalfLength < minPos) {
14828 minPos = c_coordinate(cellId, m_periodicDirection) - cellHalfLength;
14830 if(c_coordinate(cellId, m_periodicDirection) + cellHalfLength > maxPos) {
14831 maxPos = c_coordinate(cellId, m_periodicDirection) + cellHalfLength;
14835 // Exchange global minimum and maximum
14836 MPI_Allreduce(MPI_IN_PLACE, &maxPos, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "maxPos
", "1
");
14837 MPI_Allreduce(MPI_IN_PLACE, &minPos, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "minPos
", "1
");
14839 m_periodicDistance = maxPos - minPos;
14846template <MInt nDim>
14847void LsCartesianSolver<nDim>::initLocalizedLevelSetCG() {
14851 m_log << "Initializing local levelset CG
" << endl;
14852 if(domainId() == 0) {
14853 cerr << "Initializing local levelset CG
" << endl;
14858 // initialise minGapWidth and minGapWidthDt1#
14860 m_minGapWidth.clear();
14861 m_minGapWidthDt1.clear();
14862 for(MInt region = 0; region < m_noGapRegions; region++) {
14863 m_minGapWidth.push_back(std::numeric_limits<MFloat>::max());
14864 m_minGapWidthDt1.push_back(std::numeric_limits<MFloat>::max());
14868 if(m_GFieldInitFromSTL) initializeGControlPoint();
14870 for(MInt set = 0; set < m_noSets; set++)
14871 std::vector<MInt>().swap(m_bandCells[set]);
14873 if(m_semiLagrange) {
14874 initializeIntegrationScheme_semiLagrange();
14876 initializeIntegrationScheme();
14879 if(!m_initFromRestartFile) {
14880 // Iteration 1: (on minLevel-/boundingBoxLevel-basis)
14881 //------------------------------------------------
14882 // a) create G-Base-Grid
14883 // if( domainId()==0 ) { cerr << "G grid initialization: Iteration-1
" << endl; }
14885 createBaseGgridCG();
14887 // c) initialize the G-field on minLevel-/boundingBoxLevel-basis
14888 if(m_GFieldInitFromSTL) {
14889 constructGFieldFromSTL(1);
14891 initializeGField();
14894 // d) determine G-cell-properties
14895 if(m_buildCollectedLevelSetFunction) {
14896 buildCollectedLevelSet(0);
14899 determineG0Cells();
14902 //------------------------------------------------
14903 // if( domainId()==0 ) { cerr << "G grid initialization: Iteration-4
" << endl; }
14906 // a) refine or coarsen g0 cells!
14907 m_log << "createGgridCG is starting
" << endl;
14909 m_log << "createGgridCG is done
" << endl;
14911 // b) initialize again
14912 // if( m_GFieldInitFromSTL ) constructGFieldFromSTL(1);
14913 if(m_GFieldInitFromSTL) {
14914 determineG0Cells();
14915 determineBandCells();
14916 m_log << "Initialize G Field from stl data...
";
14917 constructGFieldFromSTL(3);
14918 m_log << "ok
" << endl;
14919 for(MInt set = 0; set < m_noSets; set++) {
14920 std::vector<MInt>().swap(m_bandCells[set]);
14923 initializeGField();
14926 // c) determine G-cell-properties
14927 if(m_buildCollectedLevelSetFunction) {
14928 buildCollectedLevelSet(0);
14931 m_log << "Determine G cells in Gamma...
";
14932 determineG0Cells();
14933 m_log << "ok
" << endl;
14935 m_log << "Determine the narrow computation band...
";
14936 determineBandCells();
14937 m_log << "ok
" << endl;
14939 m_log << "Update G boundary cell list...
";
14940 updateBndryCellList();
14941 m_log << "ok
" << endl;
14943 m_log << "smallest gCell length
" << m_gCellDistance << endl;
14945 m_log << "Reset outside cells...
";
14946 resetOutsideCells();
14947 m_log << "ok
" << endl;
14949 if(domainId() == 0) {
14950 cerr << "G grid Reinitialization
" << endl;
14954 if(m_GFieldInitFromSTL) {
14955 constructGFieldFromSTL(0);
14958 // collected level-set function
14959 if(m_buildCollectedLevelSetFunction) {
14960 buildCollectedLevelSet(0);
14963 // claudia: check if this is really necessary here...
14964 if(m_GFieldInitFromSTL) {
14965 resetOutsideCells();
14968 if(m_levelSetRans) {
14969 constructGFieldFromSTL(1);
14970 updateAllLowerGridLevels();
14971 // initialization output for checking purpose
14972 if(m_GFieldFromSTLInitCheck) {
14973 writeRestartLevelSetFileCG(1, "restartLSGridCG_init
", "restartLSCG_init
");
14978// usefull-debug-output:
14980 MInt globalTimeStep_temp = globalTimeStep;
14981 globalTimeStep = 0;
14982 writeRestartLevelSetFileCG(1, "restartLSGridCG_debug_0
", "restartLSCG_debug_0
");
14983 globalTimeStep = globalTimeStep_temp;
14986 // if(m_initialRefinement) return;
14988 // initialize fields...
14989 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14990 for(MInt set = 0; set < m_maxNoSets; set++) {
14991 if(!m_semiLagrange) {
14992 for(MInt d = 0; d < nDim; d++) {
14993 a_extensionVelocityG(cellId, d, set) = F0;
14996 a_oldLevelSetFunctionG(cellId, set) = a_levelSetFunctionG(cellId, set);
14999 if(m_maxNoSets > 1 && m_closeGaps) {
15000 a_potentialGapCell(cellId) = 0;
15001 a_potentialGapCellClose(cellId) = 0;
15006 // initialization output for checking purpose
15007 if(m_GFieldFromSTLInitCheck) {
15008 writeRestartLevelSetFileCG(1, "restartLSGridCG_init
", "restartLSCG_init
");
15011 exchangeAllLevelSetData();
15013 if(m_virtualSurgery) {
15014 initializeCollectedLevelSet(0);
15017 m_log << "*** G grid initialization finished ***
" << endl;
15019 } else { // initFromRestartFile
15021 if(domainId() == 0) {
15022 cerr << " By loading localized level-set file:
";
15024 stringstream levelSetFileName;
15025 levelSetFileName << restartDir() << "restartLSCG_init
";
15026 if(!m_useNonSpecifiedRestartFile) levelSetFileName << "_0
";
15027 levelSetFileName << ParallelIo::fileExt();
15030 if(domainId() == 0) {
15031 cerr << (levelSetFileName.str()).c_str() << endl;
15034 noCells = loadLevelSetGridFlowVarsParCG((levelSetFileName.str()).c_str());
15036 ASSERT(a_noCells() == noCells, " size of collector is not noCells:
" << a_noCells() << " noCells:
" << noCells);
15038 generateListOfGExchangeCellsCG();
15040 for(MInt set = 0; set < m_noSets; set++) {
15041 std::vector<MInt>().swap(m_bandCells[set]);
15044 determineG0Cells();
15048 determineG0Cells();
15050 // set g_properties[0,1]
15051 determineBandCells();
15053 setGCellBndryProperty();
15055 if(m_levelSetRans) {
15056 updateAllLowerGridLevels();
15059 updateBndryCellList();
15061 m_log << "Reset outside cells...
";
15062 resetOutsideCells();
15063 m_log << "ok
" << endl;
15065 // initialize fields...
15066 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15067 if(m_maxNoSets > 1 && m_closeGaps) {
15068 a_potentialGapCell(cellId) = 0;
15069 a_potentialGapCellClose(cellId) = 0;
15074 determineMinMaxMeanInterfacePosition();
15075 computeZeroLevelSetArcLength();
15078 if(m_initialRefinement) return;
15080 if(m_GFieldFromSTLInitCheck) {
15081 writeRestartLevelSetFileCG(1, "restartLSGridCG_reinit
", "restartLSCG_reinit
");
15084 exchangeAllLevelSetData();
15093template <MInt nDim>
15094void LsCartesianSolver<nDim>::createBaseGgridCG() {
15097 MBool& firstRun = m_static_createBaseGgrid_firstRun;
15099 // assure that the function is only called once,
15100 // otherwise cells are added multiple-times!
15101 if(!firstRun) return;
15104 m_log << "createBaseGgridCG
" << endl;
15106 if(minLevel() == 0) {
15107 mTerm(1, AT_, "minLevel() is 0
");
15110 // establish a base g cell grid
15111 for(MInt fc = 0; fc < grid().tree().size(); fc++) {
15112 a_appendCollector();
15113 m_cells.erase(a_noCells() - 1);
15116 generateListOfGExchangeCellsCG();
15124// this function does some sanity assert checks
15125template <MInt nDim>
15126void LsCartesianSolver<nDim>::testCellsCG() {
15129 if(!g_multiSolverGrid) {
15130 for(MInt gridCellId = 0; gridCellId < grid().raw().treeb().size(); gridCellId++) {
15131 ASSERT(grid().tree().solver2grid(gridCellId) == gridCellId, "");
15132 ASSERT(grid().tree().grid2solver(gridCellId) == gridCellId, "");
15136 for(MInt gc = 0; gc < a_noCells(); gc++) {
15137 ASSERT(grid().tree().grid2solver(grid().tree().solver2grid(gc)) == gc,
15138 "proxy-grid map is incorrect: gc, grid().tree().solver2grid(gc),
"
15139 "grid().tree().grid2solver(grid().tree().solver2grid(gc)):
"
15140 << gc << " ,
" << grid().tree().solver2grid(gc) << " ,
"
15141 << grid().tree().grid2solver(grid().tree().solver2grid(gc)));
15152template <MInt nDim>
15153void LsCartesianSolver<nDim>::createGgridCG(MBool initRegrid) {
15156 m_log << "Reset lsSolver-regrid trigger at timestep:
" << globalTimeStep << " init regrid:
" << initRegrid << endl;
15158 vector<MInt> lastLayer;
15161 // MIntScratchSpace sendBufferSize(grid().noNeighborDomains(), AT_, "sendBufferSize
");
15162 // MIntScratchSpace receiveBufferSize(grid().noNeighborDomains(), AT_, "receiveBufferSize
");
15164 MBoolScratchSpace inShadowLayer(a_noCells(), AT_, "inShadowLayer
");
15165 MBoolScratchSpace tmp_data(a_noCells(), AT_, "tmp_data
");
15167 MBool newVersion = false;
15169 if(newVersion) startSet = m_startSet;
15171 // 1) reset regrid property for all cells
15172 // set inShadowLayer property for all G0-cells
15173 for(MInt gc = 0; gc < a_noCells(); gc++) {
15174 MBool isGZero = false;
15175 for(MInt set = startSet; set < m_noSets; set++) {
15176 if(/*newVersion &&*/ !m_computeSet_backup[set]) continue;
15177 if(a_isGZeroCell(gc, set)) {
15182 inShadowLayer[gc] = isGZero;
15183 a_regridTriggerG(gc) = false;
15187 for(MInt set = startSet; set < m_noSets; set++) { // m_startSet
15188 if(newVersion && !m_computeSet_backup[set]) continue;
15189 for(MInt id = 0; id < a_noG0Cells(set); id++) {
15190 const MInt currentCellId = a_G0CellId(id, set);
15191 MBool alreadyAdded = false;
15192 // loop over prevoius sets and check if the cell was already a G0 cell there
15193 // to avaoid double entries!
15195 for(MInt s = set - 1; s >= startSet; s--) { // m_startSet
15196 if(newVersion && !m_computeSet_backup[s]) continue;
15197 if(a_isGZeroCell(currentCellId, s)) {
15198 alreadyAdded = true;
15203 if(!alreadyAdded) {
15204 lastLayer.emplace_back(currentCellId);
15209 // 4. cover shadow band locally in the domain
15211 while(itCount < m_gShadowWidth) {
15212 // ii. build the next layer
15214 for(MInt c = 0; c < (signed)lastLayer.size(); c++) {
15215 const MInt cellId = lastLayer[c];
15216 for(MInt d = 0; d < m_noDirs; d++) {
15217 if(a_hasNeighbor(cellId, d) == 0) continue;
15218 const MInt nghbrId = c_neighborId(cellId, d);
15219 if(!inShadowLayer[nghbrId]) {
15220 tmp.emplace_back(nghbrId);
15221 if(itCount > m_gShadowWidth - m_gInnerBound) {
15222 a_regridTriggerG(nghbrId) = true;
15225 inShadowLayer[nghbrId] = true;
15229 // exchange next layer with neighboring domains
15230 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
15231 for(MInt j = 0; j < noWindowCells(i); j++) {
15232 tmp_data(windowCellId(i, j)) = inShadowLayer(windowCellId(i, j));
15235 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
15236 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
15237 MInt windowId = grid().azimuthalWindowCell(i, j);
15238 tmp_data(windowId) = inShadowLayer(windowId);
15242 exchangeDataLS(&tmp_data(0), 1);
15244 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
15246 // check, if received data size matches expected size:
15247 if(!(receiveBufferSize.p[i] == noHaloCells(i))) {
15248 stringstream errorMessage{};
15249 errorMessage << "this was not expected to happen: wrong number of halo information, buf=
"
15250 << receiveBufferSize.p[i] << "noGHaloCells=
" << noHaloCells(i) << ", shadow layer
";
15251 m_log << errorMessage.str() << endl;
15252 cerr << errorMessage.str() << endl;
15255 for(MInt j = 0; j < noHaloCells(i); j++) {
15256 const MInt haloCell = haloCellId(i, j);
15257 if(!inShadowLayer[haloCell]) {
15258 inShadowLayer[haloCell] = tmp_data(haloCell);
15259 if(inShadowLayer[haloCell]) {
15260 tmp.emplace_back(haloCell);
15261 if(itCount > m_gShadowWidth - m_gInnerBound) {
15262 a_regridTriggerG(haloCell) = true;
15268 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
15269 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
15270 const MInt haloCell = grid().azimuthalHaloCell(i, j);
15271 if(!inShadowLayer[haloCell]) {
15272 inShadowLayer[haloCell] = tmp_data(haloCell);
15273 if(inShadowLayer[haloCell]) {
15274 tmp.emplace_back(haloCell);
15275 if(itCount > m_gShadowWidth - m_gInnerBound) {
15276 a_regridTriggerG(haloCell) = true;
15284 // continue to the next layer
15286 for(MInt c = 0; c < (signed)tmp.size(); c++) {
15287 lastLayer.emplace_back(tmp[c]);
15292 m_log << itCount << " layers built -
";
15294 if(initRegrid) return;
15296 // 4. update G on all coarse grid cells
15297 // assign the value of the first child cell to the parentId that exists
15298 // TODO labels:LS delete this update of lower-gridLevels!
15299 // once updateLowerGridLevels is called in prepareRestart
15300 // otherwise this changes the testcases on lower grid levels
15301 for(MInt level = maxRefinementLevel() - 1; level > minLevel() - 1; level--) {
15302 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15303 if(a_level(cellId) == level) {
15304 for(MInt ch = 0; ch < IPOW2(nDim); ch++) {
15305 if(c_childId(cellId, ch) < 0) continue;
15306 for(MInt set = 0; set < m_noSets; set++) {
15307 if(level >= a_maxGCellLevel(set)) continue;
15308 a_levelSetFunctionG(cellId, set) = a_levelSetFunctionG(c_childId(cellId, ch), set);
15309 if(m_semiLagrange) {
15310 a_oldLevelSetFunctionG(cellId, set) = a_oldLevelSetFunctionG(c_childId(cellId, ch), set);
15319 // set bodyId for multiple sets but without collected Levelset!
15320 if(!m_buildCollectedLevelSetFunction && !m_combustion && !m_freeSurface) {
15321 if(m_maxNoSets > 1 || m_GFieldInitFromSTL) {
15323 for(MInt set = 0; set < m_noSets; set++) {
15324 if(m_noBodiesInSet[set] > 0) {
15325 body = m_setToBodiesTable[set][0];
15327 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15328 a_bodyIdG(cellId, set) = body;
15332 for(MInt set = 0; set < m_noSets; set++) {
15333 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15334 a_bodyIdG(cellId, set) = 0;
15346template <MInt nDim>
15347void LsCartesianSolver<nDim>::generateListOfGExchangeCellsCG() {
15350 // Initialize Halo- and Window-Cells
15351 for(MInt gCell = 0; gCell < a_noCells(); gCell++) {
15352 a_isHalo(gCell) = false;
15353 a_isWindow(gCell) = false;
15356 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
15357 for(MInt j = 0; j < noHaloCells(i); j++) {
15358 a_isHalo(haloCellId(i, j)) = true;
15360 for(MInt j = 0; j < noWindowCells(i); j++) {
15361 a_isWindow(windowCellId(i, j)) = true;
15365 // Mark azimuthal periodic exchange halos
15366 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
15367 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
15368 a_isHalo(grid().azimuthalHaloCell(i, j)) = true;
15371 for(MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
15372 a_isHalo(grid().azimuthalUnmappedHaloCell(i)) = true;
15385template <MInt nDim>
15386void LsCartesianSolver<nDim>::buildLevelSetTube(MInt mode) {
15389 // timer-for mode 1:
15390 NEW_TIMER_GROUP_STATIC(buildLevelSet, "Level Set - build tube
");
15391 NEW_TIMER_STATIC(t_levelSetTube, "Total time - build tube
", buildLevelSet);
15392 NEW_SUB_TIMER_STATIC(t_a1, "updateLowerGridLevels
", t_levelSetTube);
15393 NEW_SUB_TIMER_STATIC(t_a2, "determineG0Cells
", t_levelSetTube);
15394 NEW_SUB_TIMER_STATIC(t_a3, "determineBandCells
", t_levelSetTube);
15395 NEW_SUB_TIMER_STATIC(t_a4, "regridCheck
", t_levelSetTube);
15396 NEW_SUB_TIMER_STATIC(t_a5, "createGGrid
", t_levelSetTube);
15397 NEW_SUB_TIMER_STATIC(t_a6, "group
", t_levelSetTube);
15398 NEW_SUB_TIMER_STATIC(t_a7, "updateBnd
", t_levelSetTube);
15399 NEW_SUB_TIMER_STATIC(t_a8, "resetOutside
", t_levelSetTube);
15401 // time for mode 0:
15402 NEW_TIMER_GROUP_STATIC(buildLevelSetZero, "Zero Level Set - build tube
");
15403 NEW_TIMER_STATIC(t_levelSetTubeZero, "Total time - build tube zero
", buildLevelSetZero);
15404 NEW_SUB_TIMER_STATIC(t_b1, "determineG0Cells
", t_levelSetTubeZero);
15405 NEW_SUB_TIMER_STATIC(t_b2, "determineBandCells
", t_levelSetTubeZero);
15406 NEW_SUB_TIMER_STATIC(t_b3, "resetOutside
", t_levelSetTubeZero);
15409 RECORD_TIMER_START(t_levelSetTubeZero);
15411 RECORD_TIMER_START(t_levelSetTube);
15415 // if in the complete global domain, there are no G0 cells present, currently no LVS is computed...
15418 status = mMin(1, a_noG0Cells(0));
15419 for(MInt set = 1; set < m_noSets; set++) {
15420 status = mMin(status, a_noG0Cells(set));
15425 RECORD_TIMER_START(t_a1);
15428 // TODO labels:LS uncomment the below and all lines with
15429 // avoid updateLowerGridLevels
15430 // and update testcases accordingly! The leafCell computation doesn't need the lower levels!
15431 // but testcases fail otherwise!
15432 // if(!m_levelSetMb) {
15433 updateLowerGridLevels(mode);
15436 RECORD_TIMER_STOP(t_a1);
15440 RECORD_TIMER_START(t_b1);
15442 RECORD_TIMER_START(t_a2);
15444 determineG0Cells(mode);
15446 RECORD_TIMER_STOP(t_b1);
15448 RECORD_TIMER_STOP(t_a2);
15452 RECORD_TIMER_START(t_b2);
15454 RECORD_TIMER_START(t_a3);
15456 determineBandCells(mode);
15458 RECORD_TIMER_STOP(t_b2);
15460 RECORD_TIMER_STOP(t_a3);
15464 // check if the level set status changed (i,e, an interface appeared or disappeared)
15465 // only check, if not called for gap closing and other operations on the collected level-set function [mode 0]
15467 RECORD_TIMER_START(t_a4);
15468 regrid = (MInt)regridLevelSet();
15470 MInt newStatus = mMin(1, a_noG0Cells(0));
15471 for(MInt set = 1; set < m_noSets; set++) {
15472 newStatus = mMin(newStatus, a_noG0Cells(set));
15475 MPI_Allreduce(MPI_IN_PLACE, &status, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE
", "status
");
15476 MPI_Allreduce(MPI_IN_PLACE, &newStatus, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE
", "newStatus
");
15477 MPI_Allreduce(MPI_IN_PLACE, ®rid, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE
", "regrid
");
15479 if(m_reconstructOldG) {
15480 MPI_Allreduce(MPI_IN_PLACE, &m_rotatingReinitTrigger, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE
",
15481 "m_rotatingReinitTrigger
");
15482 if(m_rotatingReinitTrigger) {
15483 reconstructOldGField();
15487 if(regrid != 0) m_log << "body-movement caused regridding
" << endl;
15489 if(newStatus != status) {
15491 m_log << "changed number of G0-cells from
" << status << " to
" << newStatus << " caused regridding
" << endl;
15494 RECORD_TIMER_STOP(t_a4);
15498 m_forceAdaptation = true;
15499 // This should force a global mesh-adaptation though the grid-controller at the next time-Step!
15501 if(domainId() == 0) {
15502 cerr << "LS-
Solver is forcing
a mesh-adaptation at time step
" << globalTimeStep << " ...
";
15505 m_log << "LS-
Solver is forcing
a mesh-adaptation at time step
" << globalTimeStep << endl;
15506 m_reinitConvergence = m_reinitConvergenceReset; // this prevents a double reduction of the reinit criterion which
15507 // can appearently happen in the unified run loop
15508 m_reinitConvergence = m_reinitConvergence / F3;
15510 m_log << "reinitConvergence is temporarily decreased by
a factor of 3
" << m_reinitConvergence << endl;
15512 if(!m_levelSetMb || (!this->m_adaptation && m_levelSetMb)) {
15513 determineG0Cells();
15515 // reset m_computeSet, since if cells are deleted, G0Cells etc. have to be updated for all sets!
15516 for(MInt set = 0; set < m_noSets; set++) {
15517 m_computeSet_tmp[set] = m_computeSet[set];
15518 m_computeSet[set] = true;
15519 m_changedSet[set] = true;
15522 for(MInt set = 0; set < m_noSets; set++)
15523 std::vector<MInt>().swap(m_bandCells[set]);
15525 RECORD_TIMER_START(t_a5);
15527 RECORD_TIMER_STOP(t_a5);
15529 RECORD_TIMER_START(t_a6);
15530 determineG0Cells();
15531 determineBandCells();
15533 // use updateLowerGridLevels instead of levelSetRestriction, it is more accurate!
15535 levelSetRestriction();
15537 updateLowerGridLevels(mode);
15539 RECORD_TIMER_STOP(t_a6);
15541 RECORD_TIMER_START(t_a7);
15542 setGCellBndryProperty();
15543 updateBndryCellList();
15544 RECORD_TIMER_STOP(t_a7);
15546 // reset m_computeSet, since if cells are deleted, G0Cells etc. had to be updated for all sets!
15547 for(MInt set = 0; set < m_noSets; set++) {
15548 m_computeSet[set] = m_computeSet_tmp[set];
15551 if(domainId() == 0) cerr << " finished.
" << endl;
15555 if(!m_levelSetMb) {
15556 // TODO labels:LS,TIMERS fix timers for different modes
15557 /* RECORD_TIMER_START(t_a7); */
15558 updateBndryCellList();
15559 /* RECORD_TIMER_STOP(t_a7); */
15563 RECORD_TIMER_START(t_b3);
15565 RECORD_TIMER_START(t_a8);
15567 resetOutsideCells(mode);
15569 RECORD_TIMER_STOP(t_b3);
15571 RECORD_TIMER_STOP(t_a8);
15575 RECORD_TIMER_STOP(t_levelSetTubeZero);
15577 RECORD_TIMER_STOP(t_levelSetTube);
15586template <MInt nDim>
15587void LsCartesianSolver<nDim>::fastBuildLevelSetTubeCG() {
15591 NEW_TIMER_GROUP(fastBuildLevelSet, "Level Set - build tube
");
15592 NEW_TIMER(t_levelSet, "Total time - build tube
", fastBuildLevelSet);
15593 NEW_SUB_TIMER(t_updateL, "updateLowerGridLevels
", t_levelSet);
15594 NEW_SUB_TIMER(t_detBand, "determineBandCells
", t_levelSet);
15595 NEW_SUB_TIMER(t_detG0, "determineG0Cells
", t_levelSet);
15598 RECORD_TIMER_START(t_levelSet);
15600 RECORD_TIMER_START(t_updateL);
15601 updateLowerGridLevels();
15602 RECORD_TIMER_STOP(t_updateL);
15604 RECORD_TIMER_START(t_detBand);
15605 determineG0Cells();
15606 RECORD_TIMER_STOP(t_detBand);
15608 RECORD_TIMER_START(t_detG0);
15609 determineBandCells();
15610 RECORD_TIMER_STOP(t_detG0);
15612 updateBndryCellList(); // Stephan
15614 RECORD_TIMER_STOP(t_levelSet);
15621template <MInt nDim>
15622void LsCartesianSolver<nDim>::restartLocalizedLevelSetCG() {
15624 stringstream fileName;
15628 m_log << " Restarting localized level-set...
" << endl;
15629 if(domainId() == 0) {
15630 cerr << " Restarting localized level-set...
" << endl;
15633 // initialise minGapWidth and minGapWidthDt1
15635 m_minGapWidth.clear();
15636 m_minGapWidthDt1.clear();
15637 for(MInt region = 0; region < m_noGapRegions; region++) {
15638 m_minGapWidth.push_back(std::numeric_limits<MFloat>::max());
15639 m_minGapWidthDt1.push_back(std::numeric_limits<MFloat>::max());
15643 if(m_GFieldInitFromSTL) initializeGControlPoint();
15645 for(MInt set = 0; set < m_noSets; set++)
15646 std::vector<MInt>().swap(m_bandCells[set]);
15648 if(m_semiLagrange) {
15649 initializeIntegrationScheme_semiLagrange();
15651 initializeIntegrationScheme();
15654 // TODO labels:LS,toremove run_unified remove this, globalTimeStep should not be set by the solver
15655 if(!m_levelSetMb) globalTimeStep = m_restartTimeStep;
15657 stringstream levelSetFileName;
15658 if(!g_multiSolverGrid) {
15659 levelSetFileName << restartDir() << "restartLSCG
";
15661 levelSetFileName << restartDir() << "restartLSCG_
" << m_solverId;
15663 if(!m_useNonSpecifiedRestartFile) levelSetFileName << "_
" << m_restartTimeStep;
15664 levelSetFileName << ParallelIo::fileExt();
15665 if(domainId() == 0) {
15666 cerr << " Loading
" << (levelSetFileName.str()).c_str() << endl;
15669 noCells = loadLevelSetGridFlowVarsParCG((levelSetFileName.str()).c_str());
15670 ASSERT(a_noCells() == noCells && noCells == grid().tree().size(),
15671 " size of collector is not noCells:
" << a_noCells() << " noCells:
" << noCells);
15673 generateListOfGExchangeCellsCG();
15677 // set g0 cells on the base grid
15678 determineG0Cells();
15680 for(MInt set = 0; set < m_noSets; set++) {
15681 std::vector<MInt>().swap(m_bandCells[set]);
15682 // very important trigger: determineG0Cells will reset inBand, inGamma,... for all cells
15685 determineG0Cells();
15687 determineBandCells();
15689 exchangeLevelSet();
15691 setGCellBndryProperty();
15693 updateBndryCellList();
15695 resetOutsideCells();
15697 exchangeAllLevelSetData();
15699 if(m_virtualSurgery && isActive()) {
15700 initializeCollectedLevelSet(2);
15703 if(m_levelSetRans) {
15704 updateAllLowerGridLevels();
15707 // initialize fields...
15708 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15709 if(m_maxNoSets > 1 && m_closeGaps) {
15710 a_potentialGapCell(cellId) = 0;
15711 a_potentialGapCellClose(cellId) = 0;
15716 determineMinMaxMeanInterfacePosition();
15717 computeZeroLevelSetArcLength();
15726template <MInt nDim>
15727MInt LsCartesianSolver<nDim>::loadLevelSetGridFlowVarsParCG(const MChar* fileName) {
15731 IF_CONSTEXPR(nDim != 2 && nDim != 3) {
15732 cerr << " In global function loadGridFlowVarsPar: wrong number of dimensions !
" << endl;
15737 using namespace maia::parallel_io;
15738 ParallelIo data(fileName, PIO_READ, mpiComm());
15741 // set level set time
15742 data.getAttribute(&m_time, "levelSetTime
");
15746 MInt noGridCell = grid().tree().size();
15747 MInt noInternalGCells = 0;
15749 for(MInt i = 0; i < noGridCell; i++) {
15751 if(grid().tree().hasProperty(i, Cell::IsHalo)) {
15754 ++noInternalGCells;
15757 MFloatScratchSpace tmpFloat(noCells, AT_, "tmpFloat
");
15758 MLongScratchSpace tmpInt(noCells, AT_, "tmpInt
");
15759 tmpFloat.fill(-2.0);
15762 vector<MString> variableNames = data.getDatasetNames(1);
15763 MString dataVarName;
15766 // This should be the same for all the variables
15767 ParallelIo::size_type dimLen = noInternalGCells;
15768 ParallelIo::size_type start = grid().domainOffset(domainId()) - grid().raw().m_32BitOffset;
15769 // set offset for all read operations
15770 data.setOffset(dimLen, start);
15772 data.getAttribute(&dataVarName, "name
", variableNames[0]);
15773 ASSERT(dataVarName == "G
" || dataVarName == "G_0
", "ERROR retsart-file, wrong Variable-name ordering
");
15774 data.readArray(&tmpFloat[0], variableNames[0]);
15776 dataVarName.clear();
15778 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15779 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15780 if("regrid
" == dataVarName) {
15786 data.readArray(&tmpInt[0], variableNames[dataVarId]);
15788 // exchange G0-values to get correct values on halo cells!
15789 // otherwise halo cells will not be detected as g cells
15790 exchangeDataLS(&tmpFloat[0], 1);
15791 exchangeDataLS(&tmpInt[0], 1);
15793 for(MInt i = 0; i < noGridCell; ++i) {
15794 a_appendCollector();
15796 a_regridTriggerG(i) = tmpInt[i];
15797 a_levelSetFunctionG(i, 0) = tmpFloat[i];
15800 if(m_maxNoSets > 1) {
15801 for(MInt set = 1; set < m_noSets; set++) {
15802 dataVarName.clear();
15804 string tmps = "G_
" + to_string(set);
15805 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15806 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15807 if(tmps == dataVarName) {
15812 if(dataVarId == -1)
15813 mTerm(1, AT_, "ERROR: More levelsets specified in the properties file than existing in the restart-file!
");
15815 data.readArray(&tmpFloat[0], variableNames[dataVarId]);
15816 for(MInt i = 0; i < noGridCell; ++i) {
15817 a_levelSetFunctionG(i, set) = tmpFloat[i];
15822 if(m_semiLagrange && m_maxNoSets == 1) {
15823 dataVarName.clear();
15825 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15826 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15827 if("oldG
" == dataVarName) {
15832 data.readArray(&tmpFloat[0], variableNames[dataVarId]);
15833 for(MInt i = 0; i < noGridCell; ++i) {
15834 a_oldLevelSetFunctionG(i, 0) = tmpFloat[i];
15836 } else if(m_semiLagrange && m_maxNoSets > 1) {
15837 for(MInt set = 0; set < m_noSets; set++) {
15838 string tmps = "oldG_
" + to_string(set);
15839 dataVarName.clear();
15841 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15842 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15843 if(tmps == dataVarName) {
15848 data.readArray(&tmpFloat[0], variableNames[dataVarId]);
15849 for(MInt i = 0; i < noGridCell; ++i) {
15850 a_oldLevelSetFunctionG(i, set) = tmpFloat[i];
15856 if(m_semiLagrange) {
15858 if(!m_reconstructOldG) {
15860 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
15861 body = m_bodiesToCompute[b];
15863 string tmps = "containingCell_
" + to_string(body);
15864 dataVarName.clear();
15866 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15867 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15868 if(tmps == dataVarName) {
15873 data.readArray(&tmpInt[0], variableNames[dataVarId]);
15875 for(MInt i = 0; i < noGridCell; ++i) {
15876 a_containingCell(i, b) = tmpInt[i];
15878 globalToLocalIdsContainingCells();
15881 dataVarName.clear();
15883 for(MInt i = 0; i < (signed)variableNames.size(); ++i) {
15884 data.getAttribute(&dataVarName, "name
", variableNames[i]);
15885 if("initialGCell
" == dataVarName) {
15890 data.readArray(&tmpInt[0], variableNames[dataVarId]);
15891 for(MInt i = 0; i < noGridCell; ++i) {
15892 m_initialGCell[i] = tmpInt[i];
15896 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
15897 for(MInt j = 0; j < nDim; j++) {
15898 MInt id = i * nDim + j;
15899 string tmps = "SL_xRot_
" + to_string(id);
15900 data.readScalar(&m_semiLagrange_xRot_ref[id], tmps.c_str());
15904 if(m_reconstructOldG) {
15905 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
15906 for(MInt j = 0; j < nDim; j++) {
15907 MInt id = i * nDim + j;
15908 string tmps = "SL_xRot_STL
" + to_string(id);
15909 data.readScalar(&m_semiLagrange_xRot_STL[id], tmps.c_str());
15913 std::copy_n(&m_semiLagrange_xRot_ref[0], nDim * m_noEmbeddedBodies, &m_semiLagrange_xRot_STL[0]);
15917 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
15918 for(MInt j = 0; j < nDim; j++) {
15919 MInt id = i * nDim + j;
15920 string tmps = "SL_xShift_
" + to_string(id);
15921 data.readScalar(&m_semiLagrange_xShift_ref[id], tmps.c_str());
15926 if(m_noGapRegions > 0) {
15927 for(MInt i = 0; i < m_noGapRegions; i++) {
15928 string tmps = "deltaMin_
" + to_string(i);
15929 data.readScalar(&m_minGapWidth[i], tmps.c_str());
15934 // generate the window and halo cells of the level set
15935 generateListOfGExchangeCellsCG();
15936 // exchange to get correct values for halo cells
15938 exchangeAllLevelSetData();
15940 return a_noCells();
15948template <MInt nDim>
15949void LsCartesianSolver<nDim>::writeRestartLevelSetFileCG(MBool writeRestart,
15950 const MString& levelSetFileNameGGrid,
15951 const MString& levelSetFileNameGSol) {
15952 if(m_restartInterval == -1) return;
15953 if(((globalTimeStep % m_restartInterval) == 0 && globalTimeStep > m_restartTimeStep) || writeRestart) {
15954 if(domainId() == 0) {
15956 cerr << "Writing levelset CG restart file at time step
" << globalTimeStep << " ...
" << endl;
15958 writeRestart = true;
15960 if(!writeRestart) return;
15962 std::ignore = levelSetFileNameGGrid;
15963 stringstream gridFile;
15964 stringstream gridFilePath;
15965 gridFile << "grid_
" << globalTimeStep << ".Netcdf
";
15966 gridFilePath << outputDir() << "grid_
" << globalTimeStep << ".Netcdf
";
15967 MIntScratchSpace recalcIds(grid().raw().treeb().size(), AT_, "recalcIds
");
15969 grid().raw().saveGrid((gridFilePath.str()).c_str(), recalcIds.begin());
15971 ASSERT(m_currentFileName.empty(), "");
15972 m_currentFileName = levelSetFileNameGSol;
15974 writeRestartFile(true, false, (gridFile.str()).c_str(), recalcIds.begin());
15976 m_currentFileName.clear();
15983template <MInt nDim>
15984MBool LsCartesianSolver<nDim>::levelSetAdaptationTrigger() {
15988 MIntScratchSpace globalRegrid(1, AT_, "globalRegrid
");
15989 MIntScratchSpace regrid(1, AT_, "regrid
");
15990 MIntScratchSpace globalStatus(1, AT_, "globalStatus
");
15991 MIntScratchSpace status(1, AT_, "status
");
15992 MIntScratchSpace newStatus(1, AT_, "newStatus
");
15994 // if in the complete global domain, there are no G0 cells present, currently no LVS is computed...
15995 status.p[0] = mMin(1, a_noG0Cells(0));
15996 for(MInt set = 1; set < m_noSets; set++) {
15997 status.p[0] = mMin(status.p[0], a_noG0Cells(set));
15999 MPI_Allreduce(status.getPointer(), globalStatus.getPointer(), 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
16000 "status.getPointer()
", "globalStatus.getPointer()
");
16001 status.p[0] = globalStatus.p[0];
16003 // required here, since determineG0Cells may rely on lower grid levels...
16004 updateLowerGridLevels(mode);
16005 determineG0Cells(mode);
16006 determineBandCells(mode);
16007 updateBndryCellList();
16009 // check if the level set status changed (i,e, an interface appeared or disappeared)
16010 // only check, if not called for gap closing and other operations on the collected level-set function [mode 0]
16011 regrid.p[0] = (MInt)regridLevelSet();
16012 newStatus.p[0] = mMin(1, a_noG0Cells(0));
16013 for(MInt set = 1; set < m_noSets; set++) {
16014 newStatus.p[0] = mMin(newStatus.p[0], a_noG0Cells(set));
16017 MPI_Allreduce(newStatus.getPointer(), globalStatus.getPointer(), 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
16018 "newStatus.getPointer()
", "globalStatus.getPointer()
");
16019 newStatus.p[0] = globalStatus.p[0];
16021 MPI_Allreduce(regrid.getPointer(), globalRegrid.getPointer(), 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
16022 "regrid.getPointer()
", "globalRegrid.getPointer()
");
16023 regrid.p[0] = globalRegrid.p[0];
16025 if(newStatus.p[0] != status.p[0]) regrid.p[0] = true;
16028 return regrid.p[0];
16035template <MInt nDim>
16036void LsCartesianSolver<nDim>::refineCell(const MInt gridCellId) {
16037 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
16039 for(MInt child = 0; child < grid().m_maxNoChilds; child++) {
16040 const MInt childId = grid().raw().treeb().child(gridCellId, child);
16042 if(childId == -1) continue;
16044 // @ansgar_pls_adapt2 test this for ls solver!
16045 // --> this sort of skip at least causes one assert in compactCells to fail (see testcase
16046 // LS/2D_twoLsBlock_slottedDisk_different_rotations_single with partitionCellMaxNoOffspring=1
16047 // Skip if cell is a partition level ancestor and its child was not newly created
16048 if(!grid().raw().a_hasProperty(childId, Cell::WasNewlyCreated)
16049 && grid().raw().a_hasProperty(gridCellId, Cell::IsPartLvlAncestor)) {
16053 if(!g_multiSolverGrid) ASSERT(grid().raw().a_hasProperty(childId, Cell::WasNewlyCreated), "");
16055 // If solver is inactive all cells musst be halo cells!
16056 if(!isActive()) ASSERT(grid().raw().a_isHalo(childId), "");
16058 if(grid().azimuthalPeriodicity()) {
16059 // Solver flag will be set in proxy
16060 // The cartesianGrid does not know the geometry, therefore it needs to be checked
16061 // that the child actually is inside the geometry
16062 if(grid().checkOutsideGeometry(childId) == 1) {
16063 grid().raw().setSolver(childId, solverId(), false);
16068 // If child exists in grid but is not located inside solver geometry
16069 if(!grid().solverFlag(childId, solverId())) continue;
16071 const MInt solverChildId = this->createCellId(childId);
16073 if(!g_multiSolverGrid) ASSERT(solverChildId == childId, "");
16075 // avoid faulty initialisation of childs
16076 for(MInt set = m_startSet; set < m_noSets; set++) {
16077 a_inBandG(solverChildId, set) = a_inBandG(solverCellId, set);
16080 for(MInt set = 0; set < m_noSets; set++) {
16081 a_levelSetFunctionG(solverChildId, set) = a_levelSetFunctionG(solverCellId, set);
16082 if(m_semiLagrange) {
16083 a_oldLevelSetFunctionG(solverChildId, set) = a_oldLevelSetFunctionG(solverCellId, set);
16085 if(m_levelSetMb) a_bodyIdG(solverChildId, set) = a_bodyIdG(solverCellId, set);
16088 if(!a_isHalo(solverCellId) && globalTimeStep > 0) {
16089 if(m_virtualSurgery) {
16090 if((a_levelSetFunctionG(solverCellId, 1) * a_levelSetFunctionG(solverCellId, 2)) < 0) {
16091 m_refinedCells.insert(make_pair(solverCellId, 0));
16094 MInt cellAdded = 0;
16095 for(MInt set = m_startSet; set < m_noSets; set++) {
16096 if(a_inBandG(solverCellId, set)) {
16097 if(!m_computeSet_backup[set] || m_maxLevelChange) {
16099 if(cellAdded > 1) {
16100 auto it0 = m_refinedCells.find(solverChildId);
16101 ASSERT(it0 != m_refinedCells.end(), "");
16102 m_refinedCells.erase(it0);
16103 m_refinedCells.insert(make_pair(solverChildId, 0));
16105 m_refinedCells.insert(make_pair(solverChildId, set));
16109 if(m_computeSet_backup[set]) {
16110 // tested only for m_maxLevelChange, in this case the levelSet is interpolated
16111 // and the old-levelSet is reconstructed to maintain mass-conservation!
16112 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
16113 MFloat cellPos[3] = {c_coordinate(solverChildId, 0), c_coordinate(solverChildId, 1),
16114 c_coordinate(solverChildId, nDim - 1)};
16115 const MInt position = setUpLevelSetInterpolationStencil(solverCellId, interpolationCells, cellPos);
16116 if(position > -1) {
16117 if(!m_maxLevelChange) {
16118 a_oldLevelSetFunctionG(solverChildId, set) = interpolateOldLevelSet(interpolationCells, cellPos, set);
16120 a_levelSetFunctionG(solverChildId, set) = interpolateLevelSet(interpolationCells, cellPos, set);
16129 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16130 a_containingCell(solverChildId, b) = -1;
16131 if(!m_reconstructOldG) {
16132 a_containingDomain(solverChildId, b) = -1;
16133 m_initialGCell[solverChildId] = 0;
16144template <MInt nDim>
16145void LsCartesianSolver<nDim>::removeChilds(const MInt gridCellId) {
16146 // If solver is inactive cell musst never be a internal cell
16148 ASSERT(grid().raw().a_isHalo(gridCellId), "");
16151 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
16153 for(MInt set = 0; set < m_noSets; set++) {
16154 a_inBandG(solverCellId, set) = false;
16158 ASSERT(solverCellId > -1 && solverCellId < m_cells.size(), "solverCellId is:
" << solverCellId);
16159 if(!g_multiSolverGrid) ASSERT(solverCellId == gridCellId, "");
16161 for(MInt set = 0; set < m_noSets; set++) {
16162 a_levelSetFunctionG(solverCellId, set) = F0;
16163 if(m_semiLagrange) {
16164 a_oldLevelSetFunctionG(solverCellId, set) = F0;
16167 MInt noChildren = 0;
16169 for(MInt c = 0; c < grid().m_maxNoChilds; c++) {
16170 MInt childId = c_childId(solverCellId, c);
16171 if(childId < 0) continue;
16173 for(MInt set = 0; set < m_noSets; set++) {
16174 a_levelSetFunctionG(solverCellId, set) += a_levelSetFunctionG(childId, set);
16175 if(m_semiLagrange) {
16176 a_oldLevelSetFunctionG(solverCellId, set) += a_oldLevelSetFunctionG(childId, set);
16181 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16182 a_containingCell(childId, b) = -1;
16183 if(!m_reconstructOldG) {
16184 a_containingDomain(childId, b) = -1;
16185 if(!a_isHalo(childId) && m_initialGCell[childId] == 1) {
16186 MInt parentId = c_parentId(childId);
16187 cerr << c_globalId(childId) << ",
" << c_globalId(parentId) << ",
" << a_level(childId) << ",
"
16188 << a_isHalo(childId) << ",
" << a_isHalo(parentId) << endl;
16189 mTerm(1, AT_, "Initial G cell is deleted!
");
16194 for(MInt set = m_startSet; set < m_noSets; set++) {
16195 a_inBandG(solverCellId, set) = a_inBandG(solverCellId, set) || a_inBandG(childId, set);
16198 this->removeCellId(childId);
16200 for(MInt set = 0; set < m_noSets; set++) {
16201 a_levelSetFunctionG(solverCellId, set) /= noChildren;
16202 if(m_semiLagrange) {
16203 a_oldLevelSetFunctionG(solverCellId, set) /= noChildren;
16207 if(m_maxLevelChange && globalTimeStep > 0 && !a_isHalo(solverCellId)) {
16208 MInt cellAdded = 0;
16209 for(MInt set = m_startSet; set < m_noSets; set++) {
16210 if(a_inBandG(solverCellId, set)) {
16212 if(cellAdded > 1) {
16213 auto it0 = m_refinedCells.find(solverCellId);
16214 ASSERT(it0 != m_refinedCells.end(), "");
16215 m_refinedCells.erase(it0);
16216 m_refinedCells.insert(make_pair(solverCellId, 0));
16218 m_refinedCells.insert(make_pair(solverCellId, set));
16224 if(!g_multiSolverGrid) {
16225 ASSERT((grid().raw().treeb().size() - m_cells.size()) <= grid().m_maxNoChilds, "");
16232template <MInt nDim>
16233void LsCartesianSolver<nDim>::removeCell(const MInt gridCellId) {
16234 // If solver is inactive cell musst never be a internal cell
16236 ASSERT(grid().raw().a_isHalo(gridCellId), "");
16239 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
16241 ASSERT(gridCellId > -1 && gridCellId < grid().raw().treeb().size() && solverCellId > -1
16242 && solverCellId < m_cells.size() && grid().tree().solver2grid(solverCellId) == gridCellId,
16245 this->removeCellId(solverCellId);
16248// this function should be moved to Solver as soon as cartesiansolver.h has been removed!!!
16249// this function should be moved to Solver as soon as cartesiansolver.h has been removed!!!
16250// this function should be moved to Solver as soon as cartesiansolver.h has been removed!!!
16251template <MInt nDim>
16252void LsCartesianSolver<nDim>::resizeGridMap() {
16253 grid().resizeGridMap(m_cells.size());
16260template <MInt nDim>
16261void LsCartesianSolver<nDim>::swapCells(const MInt cellId0, const MInt cellId1) {
16262 const MInt size = m_cells.size();
16264 m_cells.erase(size);
16265 m_cells.copy(cellId0, size);
16266 m_cells.copy(cellId1, cellId0);
16267 m_cells.copy(size, cellId1);
16268 m_cells.erase(size);
16269 m_cells.size(size);
16272 // cellId1 is moved ahead
16273 if(m_reconstructOldG) {
16274 // Property is already been swapped
16275 if(m_swapIds.find(cellId1) == m_swapIds.end()) m_swapIds[cellId1] = cellId0;
16277 if(m_initialGCell[cellId1] == 1) m_swapIds[cellId1] = cellId0;
16278 std::swap(m_initialGCell[cellId0], m_initialGCell[cellId1]);
16279 m_initialGCell[cellId1] = 0;
16283 if(!m_refinedCells.empty()) {
16284 auto it0 = m_refinedCells.find(cellId0);
16285 auto it1 = m_refinedCells.find(cellId1);
16286 if(it0 != m_refinedCells.end() && it1 != m_refinedCells.end()) {
16287 std::swap(it0->second, it1->second);
16288 } else if(it0 != m_refinedCells.end()) {
16289 MInt set = it0->second;
16290 m_refinedCells.erase(it0);
16291 m_refinedCells.insert(make_pair(cellId1, set));
16292 } else if(it1 != m_refinedCells.end()) {
16293 MInt set = it1->second;
16294 m_refinedCells.erase(it1);
16295 m_refinedCells.insert(make_pair(cellId0, set));
16300 if(!m_oldG0Cells.empty()) {
16301 auto it0 = m_oldG0Cells.find(cellId0);
16302 auto it1 = m_oldG0Cells.find(cellId1);
16303 if(it0 != m_oldG0Cells.end() && it1 != m_oldG0Cells.end()) {
16304 std::swap(it0->second, it1->second);
16305 } else if(it0 != m_oldG0Cells.end()) {
16306 const MInt set = it0->second;
16307 m_oldG0Cells.erase(it0);
16308 m_oldG0Cells.insert(make_pair(cellId1, set));
16309 } else if(it1 != m_oldG0Cells.end()) {
16310 const MInt set = it1->second;
16311 m_oldG0Cells.erase(it1);
16312 m_oldG0Cells.insert(make_pair(cellId0, set));
16322template <MInt nDim>
16323void LsCartesianSolver<nDim>::swapProxy(const MInt cellId0, const MInt cellId1) {
16324 grid().swapGridIds(cellId0, cellId1);
16332template <MInt nDim>
16333void LsCartesianSolver<nDim>::setCellWeights(MFloat* solverCellWeight) {
16335 const MInt noCellsGrid = grid().raw().treeb().size();
16336 const MInt offset = noCellsGrid * solverId();
16338 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
16339 const MInt gridCellId = grid().tree().solver2grid(cellId);
16340 const MInt id = gridCellId + offset;
16341 solverCellWeight[id] = 0.0;
16342 if(a_isHalo(cellId)) continue;
16343 solverCellWeight[id] = m_weightBaseCell * m_weightMulitSolverFactor;
16344 if(c_noChildren(cellId) > 0) continue;
16345 solverCellWeight[id] = m_weightLeafCell * m_weightMulitSolverFactor;
16346 for(MInt set = m_startSet; set < m_noSets; set++) {
16347 if(!m_computeSet[set]) continue;
16348 if(a_inBandG(cellId, set)) {
16349 solverCellWeight[id] = m_weightBandCell * m_weightMulitSolverFactor;
16355// ---------------------------------------------------------------------------------------------
16362template <MInt nDim>
16363MBool LsCartesianSolver<nDim>::prepareRestart(MBool writeRestart, MBool& writeGridRestart) {
16366 writeGridRestart = false;
16368 if(((globalTimeStep % m_restartInterval) == 0) || writeRestart) {
16369 writeRestart = true;
16371 if(m_adaptationSinceLastRestart) {
16372 writeGridRestart = true;
16375 // update updateLowerGridLevels before a restart!
16376 // avoid updateLowerGridLevels
16377 // if(m_levelSetMb && isActive()) {
16378 // updateLowerGridLevels();
16382 return writeRestart;
16390template <MInt nDim>
16391void LsCartesianSolver<nDim>::reIntAfterRestart(MBool doneRestart) {
16395 m_adaptationSinceLastRestart = false;
16403template <MInt nDim>
16404void LsCartesianSolver<nDim>::writeRestartFile(const MBool writeRestart, const MBool writeBackup,
16405 const MString gridFileName, MInt* recalcIdTree) {
16408 m_currentGridFileName = gridFileName;
16411 saveRestartFile(writeBackup, &recalcIdTree[0]);
16419template <MInt nDim>
16420void LsCartesianSolver<nDim>::saveRestartFile(const MBool writeBackup, MInt* recalcIds) {
16423 if(domainId() == 0) {
16424 cerr << "Writing levelset restart file
for solver
" << m_solverId << " at time step
" << globalTimeStep << " ...
";
16427 MBool debugOutput = false;
16429 debugOutput = true;
16433#if defined LS_DEBUG
16434 for(MInt body = 0; body < m_noEmbeddedBodies; body++) {
16435 const MInt bcId = m_bodyBndryCndIds[body];
16436 stringstream controlfile;
16437 controlfile << "Ctrl_Body_
" << body << "_
" << globalTimeStep << ".stl
";
16438 m_gCtrlPnt.CtrlPnt2_CtrlPntToSTL((controlfile.str()).c_str(), bcId);
16443 MInt noInternalCellIds;
16444 std::vector<MInt> recalcIdsSolver(0);
16445 std::vector<MInt> reOrderedCells(0);
16446 this->calcRecalcCellIdsSolver(recalcIds, noCells, noInternalCellIds, recalcIdsSolver, reOrderedCells);
16449 if(m_LsRotate && !m_reconstructOldG) noIdVars += 1;
16450 MInt noDbVars = m_maxNoSets;
16451 if(m_semiLagrange) noDbVars += m_maxNoSets;
16452 if(m_semiLagrange && m_bodyIdOutput) noDbVars += m_maxNoSets;
16453 if(m_LsRotate && !m_reconstructOldG) noDbVars += m_noBodiesToCompute;
16455 noDbVars = noDbVars + 4;
16457 const MInt noIdParams = 0;
16458 MInt noDbParams = m_semiLagrange ? nDim * m_noEmbeddedBodies : 0;
16459 noDbParams = noDbParams + (MInt)m_noGapRegions;
16460 if(m_LsRotate) noDbParams += (2 * nDim * m_noBodiesToCompute);
16461 MIntScratchSpace idVariables(noCells * noIdVars, AT_, "idVariables
");
16462 MFloatScratchSpace dbVariables(noCells * noDbVars, AT_, "dbVariables
");
16463 MIntScratchSpace idParameters(noIdParams, AT_, "idParameters
");
16464 MFloatScratchSpace dbParameters(noDbParams, AT_, "dbParameters
");
16465 vector<MString> dbVariablesName;
16466 vector<MString> idVariablesName;
16467 vector<MString> dbParametersName;
16468 vector<MString> idParametersName;
16469 vector<MString> name;
16471 MFloatScratchSpace levelSet(noCells, AT_, "levelSet
");
16472 MIntScratchSpace regridL(noCells, AT_, "regridL
");
16473 MInt tmpSize = debugOutput ? 1 : 0;
16474 MFloatScratchSpace tmpW(noCells * tmpSize, AT_, "tmpw
");
16477 if(m_levelSetRans) {
16478 updateLowerGridLevels();
16481 if(m_maxNoSets == 1) {
16483 name.push_back("G
");
16484 if(grid().newMinLevel() < 0) {
16485 for(MInt cell = 0; cell < noCells; cell++) {
16486 levelSet[cell] = a_levelSetFunctionG(cell, 0);
16489 for(MInt cell = 0; cell < noCells; cell++) {
16490 levelSet[cell] = a_levelSetFunctionG(reOrderedCells[cell], 0);
16493 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16495 for(MInt set = 0; set < m_noSets; set++) {
16496 string tmps = "G_
" + to_string(set);
16498 name.push_back(tmps);
16499 if(grid().newMinLevel() < 0) {
16500 for(MInt cell = 0; cell < noCells; cell++) {
16501 levelSet[cell] = a_levelSetFunctionG(cell, set);
16504 for(MInt cell = 0; cell < noCells; cell++) {
16505 levelSet[cell] = a_levelSetFunctionG(reOrderedCells[cell], set);
16508 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16512 if(m_semiLagrange) {
16513 if(m_maxNoSets == 1) {
16515 name.push_back("oldG
");
16516 if(grid().newMinLevel() < 0) {
16517 for(MInt cell = 0; cell < noCells; cell++) {
16518 levelSet[cell] = a_oldLevelSetFunctionG(cell, 0);
16521 for(MInt cell = 0; cell < noCells; cell++) {
16522 levelSet[cell] = a_oldLevelSetFunctionG(reOrderedCells[cell], 0);
16525 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16527 for(MInt set = 0; set < m_noSets; set++) {
16528 string tmps = "oldG_
" + to_string(set);
16530 name.push_back(tmps);
16531 if(grid().newMinLevel() < 0) {
16532 for(MInt cell = 0; cell < noCells; cell++) {
16533 levelSet[cell] = a_oldLevelSetFunctionG(cell, set);
16536 for(MInt cell = 0; cell < noCells; cell++) {
16537 levelSet[cell] = a_oldLevelSetFunctionG(reOrderedCells[cell], set);
16540 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16543 if(m_bodyIdOutput) {
16544 for(MInt i = 0; i < m_noSets; i++) {
16545 string tmps = "bodyId_
" + to_string(i);
16547 name.push_back(tmps);
16548 if(grid().newMinLevel() < 0) {
16549 for(MInt cell = 0; cell < noCells; cell++) {
16550 levelSet[cell] = a_bodyIdG(cell, i);
16553 for(MInt cell = 0; cell < noCells; cell++) {
16554 levelSet[cell] = a_bodyIdG(reOrderedCells[cell], i);
16557 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16561 if(!m_reconstructOldG) {
16562 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16563 MInt body = m_bodiesToCompute[b];
16565 string tmps = "containingCell_
" + to_string(body);
16567 name.push_back(tmps);
16569 localToGlobalIdsContainingCells();
16570 for(MInt cell = 0; cell < noCells; cell++) {
16571 levelSet[cell] = a_containingCell(cell, b);
16573 globalToLocalIdsContainingCells();
16575 this->collectVariables(levelSet.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16579 name.push_back("initialGCell
");
16580 for(MInt cell = 0; cell < noCells; cell++) {
16581 regridL[cell] = m_initialGCell[cell];
16583 this->collectVariables(regridL.begin(), idVariables, name, idVariablesName, 1, noCells);
16586 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
16587 for(MInt j = 0; j < nDim; j++) {
16588 MInt id = i * nDim + j;
16589 string tmps = "SL_xRot_
" + to_string(id);
16590 this->collectParameters(m_semiLagrange_xRot_ref[id], dbParameters, tmps.c_str(), dbParametersName);
16594 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
16595 for(MInt j = 0; j < nDim; j++) {
16596 MInt id = i * nDim + j;
16597 string tmps = "SL_xRot_STL
" + to_string(id);
16598 this->collectParameters(m_semiLagrange_xRot_STL[id], dbParameters, tmps.c_str(), dbParametersName);
16604 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
16605 for(MInt j = 0; j < nDim; j++) {
16606 const MInt id = i * nDim + j;
16607 const string tmps = "SL_xShift_
" + to_string(id);
16608 this->collectParameters(m_semiLagrange_xShift_ref[id], dbParameters, tmps.c_str(), dbParametersName);
16614 if(m_noGapRegions > 0) {
16615 for(MInt i = 0; i < m_noGapRegions; i++) {
16616 string tmps = "deltaMin_
" + to_string(i);
16617 this->collectParameters(m_minGapWidthDt1[i], dbParameters, tmps.c_str(), dbParametersName);
16621 name.push_back("regrid
");
16622 if(grid().newMinLevel() < 0) {
16623 for(MInt cell = 0; cell < noCells; cell++) {
16624 regridL[cell] = a_regridTriggerG(cell);
16627 for(MInt cell = 0; cell < noCells; cell++) {
16628 regridL[cell] = a_regridTriggerG(reOrderedCells[cell]);
16631 this->collectVariables(regridL.begin(), idVariables, name, idVariablesName, 1, noCells);
16634 if(grid().newMinLevel() > 0) mTerm(1, AT_, "Not implemented yet!
");
16636 name.push_back("Window
");
16637 for(MInt i = 0; i < noCells; i++) {
16638 if(a_isWindow(i)) {
16641 tmpW[i] = domainId();
16644 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16647 name.push_back("globalId
");
16648 for(MInt i = 0; i < noCells; i++) {
16649 tmpW[i] = c_globalId(i);
16651 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16653 name.push_back("BandCells
");
16654 for(MInt i = 0; i < noCells; i++) {
16656 for(MInt set = 0; set < m_noSets; set++) {
16657 if(a_isGBoundaryCellG(i, set)) tmpW[i] = -1;
16658 if(a_inBandG(i, set)) tmpW[i] = set;
16661 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16663 name.emplace_back("G0-Cells
");
16664 for(MInt i = 0; i < noCells; i++) {
16666 for(MInt set = 0; set < m_noSets; set++) {
16667 for(MInt id = 0; id < a_noG0Cells(set); id++) {
16668 MInt cellId = a_G0CellId(id, set);
16669 tmpW[cellId] = set;
16673 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1, noCells);
16676 name.push_back("gapWidth
");
16677 for (MInt i = 0; i < noCells; i++){
16678 tmpW[i] = a_gapWidth(i);
16680 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1,noCells);
16682 name.push_back("secondBodyId
");
16683 for (MInt i = 0; i < noCells; i++){
16684 tmpW[i] = a_secondBodyId( i );
16686 this->collectVariables(tmpW.begin(), dbVariables, name, dbVariablesName, 1,noCells);
16690 stringstream levelSetFileName;
16691 levelSetFileName.clear();
16692 levelSetFileName.str("");
16693 if(m_currentFileName.empty()) {
16694 if(!g_multiSolverGrid) {
16695 levelSetFileName << outputDir() << "restartLSCG
";
16697 levelSetFileName << outputDir() << "restartLSCG_
" << m_solverId;
16700 if(!m_useNonSpecifiedRestartFile) {
16701 levelSetFileName << "_
" << globalTimeStep;
16704 levelSetFileName << ParallelIo::fileExt();
16707 levelSetFileName << outputDir() << m_currentFileName;
16708 if(!m_useNonSpecifiedRestartFile) levelSetFileName << "_
" << globalTimeStep;
16709 levelSetFileName << ParallelIo::fileExt();
16713 if(m_LSSolver) time = m_time;
16715 MInt* pointerRecalcIds = (recalcIds == nullptr) ? nullptr : recalcIdsSolver.data();
16717 stringstream levelSetBackupFileName;
16718 levelSetBackupFileName.clear();
16719 levelSetBackupFileName.str("");
16720 levelSetBackupFileName << outputDir() << "restartLSCGBackup_
" << globalTimeStep;
16721 levelSetBackupFileName << ParallelIo::fileExt();
16722 if(domainId() == 0) cerr << "Writing level set (backup)
for the ls-solver...
";
16724 this->saveGridFlowVars((levelSetBackupFileName.str()).c_str(), m_currentGridFileName.c_str(), noCells,
16725 noInternalCellIds, dbVariables, dbVariablesName, 0, idVariables, idVariablesName, 0,
16726 dbParameters, dbParametersName, idParameters, idParametersName, pointerRecalcIds, time);
16729 this->saveGridFlowVars((levelSetFileName.str()).c_str(), m_currentGridFileName.c_str(), noCells, noInternalCellIds,
16730 dbVariables, dbVariablesName, 0, idVariables, idVariablesName, 0, dbParameters,
16731 dbParametersName, idParameters, idParametersName, pointerRecalcIds, time);
16733 if(domainId() == 0) cerr << "ok
" << endl;
16736// --------------------------------------------------------------------------------------
16740 * \brief finalize levelSet solver for rotating levelSet
16741 * \author Thomas Hoesgen
16743template <MInt nDim>
16744void LsCartesianSolver<nDim>::finalizeInitSolver() {
16746 if(m_combustion && globalTimeStep < 1) {
16750 // Nothing to be done if solver is not active
16751 if(!isActive()) return;
16754 if(m_constructGField) return;
16758 for(MInt set = 0; set < m_noSets; set++) {
16759 m_computeSet[set] = m_computeSet_tmp[set];
16760 m_changedSet[set] = true;
16763 for(MInt set = 0; set < m_noSets; set++) {
16764 ASSERT(m_computeSet[set] == m_computeSet_backup[set], "ERROR in m_computeSet
");
16767 if(m_trackMovingBndry != 0 && globalTimeStep >= m_trackMbStart && globalTimeStep < m_trackMbEnd) {
16768 // set a_wasGZeroCell to a_isGZeroCell before the timeStep!
16769 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
16770 for(MInt set = 0; set < m_noSets; set++) {
16771 a_wasGZeroCell(cellId, set) = a_isGZeroCell(cellId, set);
16775 if(!m_semiLagrange) {
16776 setGCellBndryProperty();
16778 computeNormalVectors();
16780 computeCurvature();
16782 determinePropagationSpeed();
16788 // if buildCollectedLevelSet, this should only be working on the individual-sets!
16789 buildLevelSetTube();
16790 setBandNewArrivals();
16792 if(!m_semiLagrange) {
16793 computeNormalVectors();
16794 computeCurvature();
16795 levelSetReinitialization();
16798 // wokring on the collected levelSet!
16799 buildMultipleLevelSet();
16804 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
16805 for(MInt j = 0; j < nDim; j++) {
16806 ind = i * nDim + j;
16807 m_bodyAngularAcceleration[ind] = F0;
16809 rotateLevelSet(5, &m_bodyAngularVelocity[i * nDim], i, nullptr, nullptr, &m_semiLagrange_xRot_STL[i * nDim]);
16811 updateContainingGCells(1);
16812 copyWindowToHaloIds();
16818 * \brief: Initialize lists for rotating levelset
16819 * \author Thomas Hoesgen
16821template <MInt nDim>
16822void LsCartesianSolver<nDim>::initRotatingLS() {
16825 if(!m_LsRotate) return;
16829 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
16830 for(MInt i = 0; i < nDim; i++) {
16831 ind = b * nDim + i;
16832 maRot = Context::getSolverProperty<MFloat>("MaRot
", solverId(), AT_, ind);
16833 m_omega[b * nDim + i] = m_referenceLength / m_bodyRadius[b] * m_referenceVelocity * maRot;
16837 if(m_reconstructOldG) {
16838 m_rotatingReinitTrigger = 1;
16839 resetContainingGCells();
16843 if(m_initialRefinement) return;
16845 resetContainingGCells();
16849 * \brief: resets list for rotating levelset
16850 * \author Thomas Hoesgen
16852template <MInt nDim>
16853void LsCartesianSolver<nDim>::resetContainingGCells() {
16856 for(MInt cellId = 0; cellId < m_maxNoCells; cellId++) {
16857 if(a_isHalo(cellId)) continue;
16859 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16860 a_containingCell(cellId, b) = cellId;
16864 if(m_reconstructOldG) return;
16866 for(MInt cellId = 0; cellId < m_maxNoCells; cellId++) {
16867 if(a_isHalo(cellId)) continue;
16868 m_initialGCell[cellId] = 0;
16869 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16870 a_containingCell(cellId, b) = cellId;
16871 a_containingDomain(cellId, b) = domainId();
16876 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
16877 if(a_isHalo(cellId)) continue;
16878 if(a_level(cellId) == a_maxGCellLevel()) {
16879 m_initialGCell[cellId] = 1;
16880 MInt parentId = cellId;
16881 for(MInt level = a_level(cellId); level > minLevel(); level--) {
16882 parentId = c_parentId(parentId);
16883 m_initialGCell[parentId] = 1;
16890 * \brief: update list for rotating levelset
16891 * \author Thomas Hoesgen
16893template <MInt nDim>
16894void LsCartesianSolver<nDim>::updateContainingGCells(MInt mode) {
16901 for(MInt cellId = 0; cellId < m_maxNoCells; cellId++) {
16902 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16903 body = m_bodiesToCompute[b];
16904 set = m_bodyToSetTable[body];
16905 if(!a_inBandG(cellId, set)) {
16906 a_containingCell(cellId, b) = -1;
16907 if(!m_reconstructOldG) {
16908 a_containingDomain(cellId, b) = -1;
16913 } else if(mode == 0) {
16914 if(m_reconstructOldG) {
16915 for(MInt cellId = 0; cellId < m_maxNoCells; cellId++) {
16916 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16917 body = m_bodiesToCompute[b];
16918 set = m_bodyToSetTable[body];
16919 if(a_inBandG(cellId, set)) {
16920 MInt contCell = a_containingCell(cellId, b);
16921 if(contCell > -1) {
16922 for(MInt level = grid().maxUniformRefinementLevel(); level < grid().maxRefinementLevel(); level++) {
16923 if(m_swapIds.find(contCell) != m_swapIds.end()) {
16924 contCell = m_swapIds[contCell];
16927 a_containingCell(cellId, b) = contCell;
16930 a_containingCell(cellId, b) = -1;
16937 // send the size of the data set
16939 MIntScratchSpace noBandCells(grid().noDomains(), AT_, "noBandCells
");
16940 noBandCells.fill(0);
16941 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
16942 body = m_bodiesToCompute[b];
16943 set = m_bodyToSetTable[body];
16944 noBandCells[domainId()] += a_noBandCells(set);
16946 MPI_Allreduce(MPI_IN_PLACE, &noBandCells[0], grid().noDomains(), MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE
",
16949 MInt noCellsComm = m_swapIds.size();
16950 MIntScratchSpace noCellsToDom(grid().noDomains(), AT_, "noCellsToDom
");
16951 noCellsToDom.fill(0);
16953 for(MInt i = 0; i < grid().noDomains(); i++) {
16954 if(noBandCells[i] > 0) {
16955 noCellsToDom[i] = noCellsComm;
16959 prepareGlobalComm(&noCellsToDom[0]);
16961 noCellsComm = mMax(m_globalSndOffsets[grid().noDomains()], m_globalRcvOffsets[grid().noDomains()]);
16964 MIntScratchSpace sndData(2 * noCellsComm, AT_, "sndData
");
16965 MIntScratchSpace sndDataSize(grid().noDomains(), AT_, "sndDataSize
");
16967 sndDataSize.fill(0);
16968 MIntScratchSpace rcvData(2 * noCellsComm, AT_, "rcvData
");
16969 MIntScratchSpace rcvDataSize(grid().noDomains(), AT_, "rcvDataSize
");
16971 rcvDataSize.fill(0);
16973 std::vector<std::map<MInt, MInt>> swapIdsGlobal;
16974 swapIdsGlobal.resize(grid().noDomains());
16977 for(std::map<MInt, MInt>::iterator it = m_swapIds.begin(); it != m_swapIds.end(); it++) {
16978 for(MInt d = 0; d < grid().noDomains(); d++) {
16979 if(domainId() == d) continue;
16980 if(noBandCells[d] <= 0) continue;
16981 sndData[2 * m_globalSndOffsets[d] + sndDataSize.p[d]] = it->first;
16982 sndDataSize.p[d]++;
16983 sndData[2 * m_globalSndOffsets[d] + sndDataSize.p[d]] = it->second;
16984 sndDataSize.p[d]++;
16988 exchangeBuffersGlobal(sndData.getPointer(), rcvData.getPointer(), sndDataSize.getPointer(),
16989 rcvDataSize.getPointer(), &m_globalSndOffsets[0], &m_globalRcvOffsets[0], 9, 2);
16990 for(MInt i = 0; i < grid().noDomains(); i++) {
16991 MInt ind = 2 * m_globalRcvOffsets[i];
16992 for(MInt j = 0; j < rcvDataSize(i); j += 2) {
16993 swapIdsGlobal[i].insert(make_pair(rcvData[ind + j], rcvData[ind + j + 1]));
16997 for(std::map<MInt, MInt>::iterator it = m_swapIds.begin(); it != m_swapIds.end(); it++) {
16998 swapIdsGlobal[domainId()].insert(make_pair(it->first, it->second));
17001 for(MInt cellId = 0; cellId < m_maxNoCells; cellId++) {
17002 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
17003 body = m_bodiesToCompute[b];
17004 set = m_bodyToSetTable[body];
17005 if(a_inBandG(cellId, set)) {
17006 MInt contCell = a_containingCell(cellId, b);
17007 if(contCell > -1) {
17008 domId = a_containingDomain(cellId, b);
17009 if(swapIdsGlobal[domId].find(contCell) != swapIdsGlobal[domId].end()) {
17010 a_containingCell(cellId, b) = swapIdsGlobal[domId][contCell];
17014 a_containingCell(cellId, b) = -1;
17015 a_containingDomain(cellId, b) = -1;
17026 * \brief: Updates a list which contains the respective windowCellId of each haloCell
17027 * \author Thomas Hoesgen
17029template <MInt nDim>
17030void LsCartesianSolver<nDim>::copyWindowToHaloIds() {
17033 MInt haloId, windowId;
17035 if(m_reconstructOldG) return;
17037 for(MInt i = 0; i < 2 * m_maxNoCells; i++) {
17038 m_cellDomIds[i] = -1;
17041 MIntScratchSpace tmp_data(a_noCells() * 3, AT_, "tmp_data
");
17042 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
17043 for(MInt j = 0; j < noWindowCells(i); j++) {
17044 windowId = windowCellId(i, j);
17045 tmp_data[windowId * 3] = windowId;
17046 tmp_data[windowId * 3 + 1] = domainId();
17047 tmp_data[windowId * 3 + 2] = m_initialGCell[windowId];
17050 if(grid().azimuthalPeriodicity()) {
17051 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
17052 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
17053 windowId = grid().azimuthalWindowCell(i, j);
17054 tmp_data[windowId * 3] = windowId;
17055 tmp_data[windowId * 3 + 1] = domainId();
17056 tmp_data[windowId * 3 + 2] = m_initialGCell[windowId];
17061 // exchange data -> send, receive
17062 exchangeDataLS(&tmp_data[0], 3);
17065 // update the halo and window cell lists
17066 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
17067 for(MInt j = 0; j < noHaloCells(i); j++) {
17068 haloId = haloCellId(i, j);
17069 m_cellDomIds[haloId * 2 + 0] = tmp_data[haloId * 3];
17070 m_cellDomIds[haloId * 2 + 1] = tmp_data[haloId * 3 + 1];
17071 m_initialGCell[haloId] = tmp_data[haloId * 3 + 2];
17074 if(grid().azimuthalPeriodicity()) {
17075 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
17076 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
17077 haloId = grid().azimuthalHaloCell(i, j);
17078 m_cellDomIds[haloId * 2 + 0] = tmp_data[haloId * 3];
17079 m_cellDomIds[haloId * 2 + 1] = tmp_data[haloId * 3 + 1];
17080 m_initialGCell[haloId] = tmp_data[haloId * 3 + 2];
17091template <MInt nDim>
17092void LsCartesianSolver<nDim>::checkHaloCells() {
17095#if defined LS_DEBUG || !defined NDEBUG
17097 const MFloat eps0 = 1e-8;
17099 MInt noChecks = 3 * m_noSets;
17100 if(m_closeGaps) noChecks += 2;
17102 MFloatScratchSpace cellCheck(a_noCells(), noChecks, AT_, "cellCheck
");
17103 cellCheck.fill(std::numeric_limits<MFloat>::max());
17105 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
17106 for(MInt set = 0; set < m_noSets; set++) {
17107 cellCheck(cellId, set * 3) = (MFloat)a_inBandG(cellId, set);
17108 cellCheck(cellId, set * 3 + 1) = a_levelSetFunctionG(cellId, set);
17109 if(!m_combustion) {
17110 cellCheck(cellId, set * 3 + 2) = (MFloat)a_bodyIdG(cellId, set);
17114 cellCheck(cellId, 3 * m_noSets) = (MFloat)a_secondBodyId(cellId);
17115 cellCheck(cellId, 3 * m_noSets + 1) = (MFloat)a_nearGapG(cellId);
17119 exchangeData(&cellCheck(0), noChecks);
17121 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
17122 // changes to avoid updateLowerGridLevels each TS
17123 if(!c_isLeafCell(cellId)) continue;
17125 // Since azimuthal periodic halos are not exact cartesian matches, these
17126 // checks are not valid for them
17127 if(grid().azimuthalPeriodicity() && grid().isPeriodic(cellId)) continue;
17129 for(MInt set = 0; set < m_noSets; set++) {
17130 ASSERT((MInt)cellCheck(cellId, set * 3) == a_inBandG(cellId, set), " " + to_string(set));
17131 ASSERT(fabs(cellCheck(cellId, set * 3 + 1) - a_levelSetFunctionG(cellId, set)) < eps0,
17132 to_string(a_levelSetFunctionG(cellId, set)) + " " + to_string(cellCheck(cellId, set * 3 + 1)));
17133 if(!m_combustion) {
17134 ASSERT((MInt)cellCheck(cellId, set * 3 + 2) == a_bodyIdG(cellId, set),
17135 to_string(cellCheck(cellId, set * 3 + 2)) + " " + to_string(a_bodyIdG(cellId, set)));
17139 // ASSERT((MInt)cellCheck(cellId,3 * m_noSets) == a_secondBodyId( cellId ), to_string(cellCheck(cellId,3 *
17140 // m_noSets)) + " " + to_string(a_secondBodyId( cellId )));
17141 ASSERT((MInt)cellCheck(cellId, 3 * m_noSets + 1) == a_nearGapG(cellId),
17142 to_string(cellCheck(cellId, 3 * m_noSets + 1)) + " " + to_string(a_nearGapG(cellId)));
17154template <MInt nDim>
17155MFloat LsCartesianSolver<nDim>::reduceData(const MInt cellId, MFloat* data, const MInt dataBlockSize) {
17156 MFloat vol = cellVolumeAtCell(cellId);
17157 if(c_noChildren(cellId) > 0) {
17159 for(MInt d = 0; d < dataBlockSize; d++) {
17160 data[dataBlockSize * cellId + d] = F0;
17162 for(MInt child = 0; child < IPOW2(nDim); child++) {
17163 MInt childId = c_childId(cellId, child);
17164 if(childId < 0) continue;
17165 if(c_noChildren(childId) == 0) continue;
17166 MFloat volc = reduceData(childId, data, dataBlockSize);
17167 for(MInt d = 0; d < dataBlockSize; d++) {
17168 data[dataBlockSize * cellId + d] += volc * data[dataBlockSize * childId + d];
17172 for(MInt d = 0; d < dataBlockSize; d++) {
17173 data[dataBlockSize * cellId + d] /= mMax(1e-14, vol);
17179// --------------------------------------------------------------------------------------
17186template <MInt nDim>
17187void LsCartesianSolver<nDim>::setInterfaceList(MIntScratchSpace& inList) {
17192 const MInt startSet = m_reconstructBand > 0 ? 0 : m_startSet;
17193 const MInt endSet = m_noSets;
17196 // based on the levelset-values
17197 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
17198 if(inList[cellId] != 0) continue;
17200 for(MInt set = startSet; set < endSet; set++) {
17201 if(m_reconstructBand > 0 && !m_computeSet_backup[set]) {
17205 MBool addParents = false;
17206 if(approx(a_levelSetFunctionG(cellId, set), F0, MFloatEps)) {
17208 // if(m_adaptationLevel < a_maxGCellLevel(set)) {
17209 if(a_level(cellId) < a_maxGCellLevel(set) && a_level(cellId) < this->m_maxSensorRefinementLevel[0]) {
17210 inList[cellId] = 1;
17214 for(MInt dir = 0; dir < m_noDirs; dir++) {
17215 if(a_hasNeighbor(cellId, dir) > 0) {
17216 const MInt nghbrId = c_neighborId(cellId, dir);
17217 if((a_levelSetFunctionG(nghbrId, set) * a_levelSetFunctionG(cellId, set) < F0)) {
17218 // if(m_adaptationLevel < a_maxGCellLevel(set)) {
17219 if(a_level(cellId) < a_maxGCellLevel(set) && a_level(cellId) < this->m_maxSensorRefinementLevel[0]) {
17220 inList[cellId] = 1;
17230 MInt parentId = c_parentId(cellId);
17231 while(parentId > -1 && parentId < a_noCells()) {
17232 if(a_level(parentId) < this->m_maxSensorRefinementLevel[0]) {
17233 inList[parentId] = 1;
17235 parentId = c_parentId(parentId);
17241 // Exchange the listCount on all Domains
17242#if defined LS_DEBUG || !defined NDEBUG
17243 if(m_reconstructBand > 0) {
17244 ASSERT(m_buildCollectedLevelSetFunction, "");
17247 MInt listCount = 0;
17248 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
17249 if(inList[cellId] > 0) {
17253 MPI_Allreduce(MPI_IN_PLACE, &listCount, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE
", "listCount
");
17255 if(listCount == 0 && !m_maxLevelChange && this->m_maxSensorRefinementLevel[0] > minLevel()) {
17256 mTerm(1, AT_, "No Cells found
for refinement!
");
17260 // the levelset-solver has only one layer of haloCells, the exchange is necessary!
17261 exchangeDataLS(&inList[0]);
17268template <MInt nDim>
17269void LsCartesianSolver<nDim>::resetSolver() {
17277template <MInt nDim>
17278void LsCartesianSolver<nDim>::resetSolverFull() {
17279 for(MInt set = 0; set < m_noSets; set++)
17280 std::vector<MInt>().swap(m_bandCells[set]);
17288template <MInt nDim>
17289MInt LsCartesianSolver<nDim>::cellDataSizeDlb(const MInt dataId, const MInt gridCellId) {
17290 // Inactive ranks do not have any data to communicate
17295 // Convert to solver cell id and check
17296 const MInt cellId = grid().tree().grid2solver(gridCellId);
17297 if(cellId < 0 || cellId >= noInternalCells()) {
17305 dataSize = m_noSets;
17313 dataSize = (m_semiLagrange) ? m_noSets : 1;
17317 if(m_semiLagrange) {
17318 if(!m_reconstructOldG && m_LsRotate) {
17321 TERMM(1, "Unknown data
id for !m_reconstructOldG && m_LsRotate.
");
17328 if(m_semiLagrange) {
17329 if(!m_reconstructOldG && m_LsRotate) {
17332 TERMM(1, "Unknown data
id for !m_reconstructOldG && m_LsRotate.
");
17339 TERMM(1, "Unknown data
id.
");
17351template <MInt nDim>
17352void LsCartesianSolver<nDim>::getCellDataDlb(const MInt dataId, const MInt oldNoCells,
17353 const MInt* const bufferIdToCellId, MFloat* const data) {
17356 MInt localBufferId = 0;
17357 for(MInt i = 0; i < oldNoCells; i++) {
17358 const MInt gridCellId = bufferIdToCellId[i];
17360 if(gridCellId < 0) continue;
17362 const MInt cellId = grid().tree().grid2solver(gridCellId);
17363 if(cellId < 0 || cellId >= noInternalCells()) {
17367 MInt dataSize = cellDataSizeDlb(dataId, gridCellId);
17371 std::copy_n(&a_levelSetFunctionG(cellId, 0), dataSize, &data[localBufferId * dataSize]);
17375 if(m_semiLagrange) {
17376 std::copy_n(&a_oldLevelSetFunctionG(cellId, 0), dataSize, &data[localBufferId * dataSize]);
17378 std::copy_n(&a_normalVectorG(cellId, 0, 0), dataSize, &data[localBufferId * dataSize]);
17383 std::copy_n(&a_curvatureG(cellId, 0), dataSize, &data[localBufferId * dataSize]);
17387 std::copy_n(&a_levelSetFunctionSlope(cellId, 0, 0), dataSize, &data[localBufferId * dataSize]);
17391 TERMM(1, "Unknown data
id.
");
17403template <MInt nDim>
17404void LsCartesianSolver<nDim>::getCellDataDlb(const MInt dataId, const MInt oldNoCells,
17405 const MInt* const bufferIdToCellId, MInt* const data) {
17408 MInt localBufferId = 0;
17409 for(MInt i = 0; i < oldNoCells; i++) {
17410 const MInt gridCellId = bufferIdToCellId[i];
17412 if(gridCellId < 0) continue;
17414 const MInt cellId = grid().tree().grid2solver(gridCellId);
17415 if(cellId < 0 || cellId >= noInternalCells()) {
17421 data[localBufferId] = a_regridTriggerG(cellId);
17425 std::copy_n(&m_initialGCell[cellId], 1, &data[localBufferId]);
17429 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
17430 data[localBufferId * m_noBodiesToCompute + b] = a_containingCell(cellId, b);
17435 TERMM(1, "Unknown data
id.
");
17447template <MInt nDim>
17448void LsCartesianSolver<nDim>::setCellDataDlb(const MInt dataId, const MFloat* const data) {
17451 // Nothing to do if solver is not active
17456 // Set the variables if this is the correct reinitialization stage
17457 if(m_loadBalancingReinitStage == 0) {
17460 std::copy_n(data, noInternalCells() * m_noSets, &a_levelSetFunctionG(0, 0));
17464 if(m_semiLagrange) {
17465 std::copy_n(data, noInternalCells() * m_noSets, &a_oldLevelSetFunctionG(0, 0));
17467 std::copy_n(data, noInternalCells(), &a_curvatureG(0, 0));
17472 std::copy_n(data, noInternalCells() * nDim, &a_normalVectorG(0, 0, 0));
17476 std::copy_n(data, noInternalCells() * nDim, &a_levelSetFunctionSlope(0, 0, 0));
17480 TERMM(1, "Unknown data
id.
");
17490template <MInt nDim>
17491void LsCartesianSolver<nDim>::setCellDataDlb(const MInt dataId, const MInt* const data) {
17494 // Nothing to do if solver is not active
17499 // Set the variables if this is the correct reinitialization stage
17500 if(m_loadBalancingReinitStage == 0) {
17503 for(MInt i = 0; i < noInternalCells(); i++) {
17504 a_regridTriggerG(i) = (MBool)data[i];
17509 std::copy_n(data, noInternalCells(), &m_initialGCell[0]);
17513 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
17514 for(MInt i = 0; i < noInternalCells(); i++) {
17515 a_containingCell(i, b) = data[b * noInternalCells() + i];
17521 TERMM(1, "Unknown data
id.
");
17530template <MInt nDim>
17531void LsCartesianSolver<nDim>::balancePre() {
17534 // Set reinitialization stage
17535 m_loadBalancingReinitStage = 0;
17537 // Update the grid proxy for this solver
17540 if(!grid().isActive()) {
17541 // Reset parallelization information if solver is not active
17542 updateDomainInfo(-1, -1, MPI_COMM_NULL, AT_);
17544 // Set new domain info for solver
17545 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
17548 // Reset cell, surface, boundary cell data and deallocate halo/window cell arrays
17554 // Return if solver is not active
17555 if(!grid().isActive()) {
17559 grid().updateLeafCellExchange();
17561 // check for empry cell collector
17562 ASSERT(m_cells.size() == 0, "");
17564 // Resize cell collector to internal cells
17565 m_cells.append(grid().noInternalCells());
17567 // Check that global ids are sorted
17568 for(MInt cellId = 0; cellId < grid().noInternalCells(); cellId++) {
17569 if(grid().domainOffset(domainId()) + (MLong)cellId != c_globalId(cellId)) {
17570 TERMM(1, "Global
id mismatch.
");
17572 m_cells.erase(cellId);
17581template <MInt nDim>
17582void LsCartesianSolver<nDim>::balancePost() {
17585 m_loadBalancingReinitStage = 1;
17587 // If m_buildCollectedLevelSetFunction = false, identifyBodies() is never called.
17588 // Setting bodyId to -1, however, leads to errors in cut-cell generation.
17589 MInt defaultBodyId = (m_buildCollectedLevelSetFunction ? -1 : 0);
17590 for(MInt i = 0; i < noInternalCells(); i++) {
17591 for(MInt j = 0; j < m_noSets; j++) {
17592 if(m_semiLagrange) {
17593 a_bodyIdG(i, j) = defaultBodyId;
17598 // append the halo-cells and erase
17599 m_cells.append(grid().tree().size() - m_cells.size());
17600 for(MInt cellId = grid().noInternalCells(); cellId < a_noCells(); cellId++) {
17601 m_cells.erase(cellId);
17606 // Nothing to do if solver is not active
17607 if(!grid().isActive()) {
17611 // reallocate exchange-storages:
17612 if(grid().noDomains() > 1) {
17614 mDeallocate(m_intSendBuffers);
17615 mDeallocate(m_intReceiveBuffers);
17617 mAlloc(m_intSendBuffers, grid().noNeighborDomains(), m_maxNoCells, "m_intSendBuffers
", 0, AT_);
17618 mAlloc(m_intReceiveBuffers, grid().noNeighborDomains(), m_maxNoCells, "m_intReceiveBuffers
", 0, AT_);
17621 if(!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2) {
17622 mDeallocate(m_gSendBuffers);
17623 mDeallocate(m_gReceiveBuffers);
17625 mAlloc(m_gSendBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells, "m_gSendBuffers
", F0, AT_);
17626 mAlloc(m_gReceiveBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells, "m_gReceiveBuffers
", F0, AT_);
17629 if(m_combustion || (!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2)) {
17630 mDeallocate(mpi_request);
17631 mDeallocate(mpi_recive);
17633 mAlloc(mpi_request, grid().noNeighborDomains(), "mpi_request
", AT_);
17634 mAlloc(mpi_recive, grid().noNeighborDomains(), "mpi_recive
", AT_);
17638 generateListOfGExchangeCellsCG();
17639 this->checkNoHaloLayers();
17641 // initAzimuthalExchange
17642 initAzimuthalExchange();
17644 exchangeAllLevelSetData();
17646 m_adaptationSinceLastRestart = true;
17647 m_loadBalancingReinitStage = 2;
17654template <MInt nDim>
17655void LsCartesianSolver<nDim>::balance(const MInt* const noCellsToReceiveByDomain,
17656 const MInt* const noCellsToSendByDomain, const MInt* const sortedCellId,
17657 const MInt oldNoCells) {
17660 NEW_TIMER_GROUP(t_initTimer, "balance solver
");
17661 NEW_TIMER(t_timertotal, "balance solver
", t_initTimer);
17662 NEW_SUB_TIMER(t_variables, "variables
", t_timertotal);
17663 NEW_SUB_TIMER(t_communicator, "communicator
", t_timertotal);
17665 RECORD_TIMER_START(t_timertotal);
17666 RECORD_TIMER_START(t_variables);
17668 // save solver-data in grid-format (necessary for multi-solver-balancing!)
17669 // while this might not be the fastes way to ensure a multi-solver balance,
17670 // it is ginuelly simple and clear to understand what is happening!
17671 // This needs to happen before the proxy-update!! (otherwise the solver2grid might change)
17672 MFloatScratchSpace lsValuesBalance(oldNoCells, m_noSets, FUN_, "lsValuesBalance
");
17673 MIntScratchSpace regridBalance(oldNoCells, FUN_, "regridBalance
");
17674 MFloatScratchSpace curvatureBalance((!m_semiLagrange) * oldNoCells, FUN_, "curvatureBalance
");
17675 MFloatScratchSpace normalVectorsBalance((!m_semiLagrange) * oldNoCells, nDim, FUN_, "normalVectorsBalance
");
17676 MFloatScratchSpace slopeBalance((!m_semiLagrange) * oldNoCells, nDim, FUN_, "slopeBalance
");
17678 MFloatScratchSpace oldLsValuesBalance(m_semiLagrange * oldNoCells, m_semiLagrange * m_noSets, FUN_,
17679 "oldLsValuesBalance
");
17681 MLongScratchSpace containingCellsBalance((m_LsRotate && !m_reconstructOldG) * oldNoCells,
17682 (m_LsRotate && !m_reconstructOldG) * m_noBodiesToCompute, FUN_,
17683 "containingCellsBalance
");
17684 MLongScratchSpace initialGCellBalance((m_LsRotate && !m_reconstructOldG) * oldNoCells, FUN_, "initialGCellBalance
");
17686 regridBalance.fill(-2);
17687 lsValuesBalance.fill(-900);
17688 curvatureBalance.fill(-900);
17689 normalVectorsBalance.fill(-900);
17690 slopeBalance.fill(-900);
17693 oldLsValuesBalance.fill(-900);
17694 containingCellsBalance.fill(-900);
17695 initialGCellBalance.fill(-900);
17697 for(MInt cellId = 0; cellId < grid().tree().size(); cellId++) {
17698 MInt gridCellId = grid().tree().solver2grid(cellId);
17699 for(MInt set = 0; set < m_noSets; set++) {
17700 lsValuesBalance(gridCellId, set) = a_levelSetFunctionG(cellId, set);
17702 if(a_regridTriggerG(cellId)) regridBalance(gridCellId) = 1;
17705 if(m_semiLagrange) {
17706 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
17707 MInt gridCellId = grid().tree().solver2grid(cellId);
17708 for(MInt set = 0; set < m_noSets; set++) {
17709 oldLsValuesBalance(gridCellId, set) = a_oldLevelSetFunctionG(cellId, set);
17711 if(!m_reconstructOldG && m_LsRotate) {
17712 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
17713 containingCellsBalance(gridCellId, b) = a_containingCell(cellId, b);
17715 initialGCellBalance(gridCellId) = m_initialGCell[cellId];
17720 for(MInt cellId = 0; cellId < grid().tree().size(); cellId++) {
17721 MInt gridCellId = grid().tree().solver2grid(cellId);
17722 for(MInt dim = 0; dim < nDim; dim++) {
17723 normalVectorsBalance(gridCellId, dim) = a_normalVectorG(cellId, dim, 0);
17724 slopeBalance(gridCellId, dim) = a_levelSetFunctionSlope(cellId, dim, 0);
17726 curvatureBalance(gridCellId) = a_curvatureG(cellId, 0);
17731 // update of the proxy
17734 // Just reset parallelization information if solver is not active
17735 // NOTE: inactive ranks not supported here since the data sizes etc are not determined for the
17736 // solver but for the whole grid -> use balancePre/Post instead!
17738 updateDomainInfo(-1, -1, MPI_COMM_NULL, AT_);
17739 TERMM(1, "fixme: inactive ranks not supported in balance(); implement balancePre/Post!
");
17743 // Set new domain info for solver
17744 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
17746 // This is only working of the same domains as in the grid are used!
17747 ASSERT(domainId() == grid().raw().domainId(), "");
17748 ASSERT(noDomains() == grid().raw().noDomains(), "");
17750 // data-to be saved during the balancing:
17751 //- a_levelSetFunctionG
17753 // if semiLagrange:
17755 //- oldLevelSetFunction
17757 MFloatScratchSpace levelSet(noCellsToReceiveByDomain[noDomains()], m_noSets, FUN_, "levelSet
");
17758 MIntScratchSpace regridTrigger(noCellsToReceiveByDomain[noDomains()], FUN_, "regridTrigger
");
17760 MFloatScratchSpace curvature((!m_semiLagrange) * noCellsToReceiveByDomain[noDomains()], FUN_, "curvature
");
17761 MFloatScratchSpace normalVectors((!m_semiLagrange) * noCellsToReceiveByDomain[noDomains()], nDim, FUN_,
17763 MFloatScratchSpace slopes((!m_semiLagrange) * noCellsToReceiveByDomain[noDomains()], nDim, FUN_, "slopes
");
17765 MFloatScratchSpace oldLevelSet(m_semiLagrange * noCellsToReceiveByDomain[noDomains()], m_semiLagrange * m_noSets,
17766 FUN_, "oldLevelSet
");
17768 MLongScratchSpace containingCells((m_LsRotate && !m_reconstructOldG) * noCellsToReceiveByDomain[noDomains()],
17769 (m_LsRotate && !m_reconstructOldG) * m_noBodiesToCompute, FUN_, "containingCells
");
17770 MLongScratchSpace initialGCell((m_LsRotate && !m_reconstructOldG) * noCellsToReceiveByDomain[noDomains()], FUN_,
17773 levelSet.fill(-1.0);
17774 regridTrigger.fill(-2);
17776 curvature.fill(-1.0);
17777 normalVectors.fill(-1.0);
17780 oldLevelSet.fill(-1.0);
17781 containingCells.fill(-1);
17782 initialGCell.fill(-1);
17784 maia::mpi::communicateData(&lsValuesBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17785 noCellsToSendByDomain, noCellsToReceiveByDomain, m_noSets, &levelSet[0]);
17787 maia::mpi::communicateData(®ridBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17788 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, ®ridTrigger[0]);
17790 if(m_semiLagrange) {
17791 maia::mpi::communicateData(&oldLsValuesBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17792 noCellsToSendByDomain, noCellsToReceiveByDomain, m_noSets, &oldLevelSet[0]);
17794 if(!m_reconstructOldG && m_LsRotate) {
17795 maia::mpi::communicateData(&containingCellsBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(),
17796 mpiComm(), noCellsToSendByDomain, noCellsToReceiveByDomain, m_noBodiesToCompute,
17797 &containingCells[0]);
17798 maia::mpi::communicateData(&initialGCellBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17799 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &initialGCell[0]);
17803 maia::mpi::communicateData(&normalVectorsBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17804 noCellsToSendByDomain, noCellsToReceiveByDomain, nDim, &normalVectors[0]);
17805 maia::mpi::communicateData(&slopeBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17806 noCellsToSendByDomain, noCellsToReceiveByDomain, nDim, &slopes[0]);
17807 maia::mpi::communicateData(&curvatureBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
17808 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &curvature[0]);
17817 // Iterate over all received grid cells
17818 for(MInt gridCellId = 0; gridCellId < noCellsToReceiveByDomain[noDomains()]; gridCellId++) {
17819 // Determine cell id and append to collector
17820 const MInt cellId = m_cells.size();
17822 if(!grid().raw().treeb().solver(gridCellId, m_solverId)) continue;
17824 ASSERT(grid().tree().solver2grid(cellId) == gridCellId, "");
17826 if(grid().domainOffset(domainId()) + (MLong)cellId != c_globalId(cellId)) {
17827 mTerm(1, AT_, "Global
id mismatch.
");
17830 m_cells.erase(cellId);
17833 for(MInt j = 0; j < m_noSets; j++) {
17834 a_levelSetFunctionG(cellId, j) = levelSet(gridCellId, j);
17836 if(m_semiLagrange) {
17837 a_bodyIdG(cellId, j) = -1;
17838 a_oldLevelSetFunctionG(cellId, j) = oldLevelSet(gridCellId, j);
17842 if(!m_reconstructOldG && m_LsRotate) {
17843 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
17844 a_containingCell(cellId, b) = containingCells(gridCellId, b);
17846 m_initialGCell[cellId] = initialGCell[gridCellId];
17849 if(!m_semiLagrange) {
17850 for(MInt dim = 0; dim < nDim; dim++) {
17851 a_normalVectorG(cellId, dim, 0) = normalVectors(gridCellId, dim);
17852 a_levelSetFunctionSlope(cellId, dim, 0) = slopes(gridCellId, dim);
17854 a_curvatureG(cellId, 0) = curvature(gridCellId);
17857 if(regridTrigger[gridCellId] > 0) {
17858 a_regridTriggerG(cellId) = true;
17862 // append the halo-cells:
17863 m_cells.append(grid().tree().size() - m_cells.size());
17864 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
17865 m_cells.erase(cellId);
17870 RECORD_TIMER_STOP(t_variables);
17871 RECORD_TIMER_START(t_communicator);
17873 // reallocate exchange-storages:
17874 if(grid().noDomains() > 1) {
17876 mDeallocate(m_intSendBuffers);
17877 mDeallocate(m_intReceiveBuffers);
17879 mAlloc(m_intSendBuffers, grid().noNeighborDomains(), m_maxNoCells, "m_intSendBuffers
", 0, AT_);
17880 mAlloc(m_intReceiveBuffers, grid().noNeighborDomains(), m_maxNoCells, "m_intReceiveBuffers
", 0, AT_);
17883 if(!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2) {
17884 mDeallocate(m_gSendBuffers);
17885 mDeallocate(m_gReceiveBuffers);
17887 mAlloc(m_gSendBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells, "m_gSendBuffers
", F0, AT_);
17888 mAlloc(m_gReceiveBuffers, grid().noNeighborDomains(), m_maxNoSets * m_maxNoCells, "m_gReceiveBuffers
", F0, AT_);
17891 if(m_combustion || (!m_semiLagrange || m_guaranteeReinit || m_STLReinitMode != 2)) {
17892 mDeallocate(mpi_request);
17893 mDeallocate(mpi_recive);
17895 mAlloc(mpi_request, grid().noNeighborDomains(), "mpi_request
", AT_);
17896 mAlloc(mpi_recive, grid().noNeighborDomains(), "mpi_recive
", AT_);
17900 generateListOfGExchangeCellsCG();
17902 this->checkNoHaloLayers();
17904 startLoadTimer(AT_);
17906 // Initialize the azimuthal periodic exchange
17907 initAzimuthalExchange();
17909 exchangeAllLevelSetData();
17911 m_adaptationSinceLastRestart = true;
17913 RECORD_TIMER_STOP(t_communicator);
17914 RECORD_TIMER_STOP(t_timertotal);
17915 DISPLAY_TIMER(t_timertotal);
17922template <MInt nDim>
17923void LsCartesianSolver<nDim>::finalizeBalance() {
17924 if(!grid().isActive()) {
17928 reInitSolver(false);
17930 // Update local ids of window cell on halo rank or reconstructOldG
17932 if(m_reconstructOldG) {
17933 reconstructOldGField();
17935 globalToLocalIdsContainingCells();
17936 copyWindowToHaloIds();
17946template <MInt nDim>
17947void LsCartesianSolver<nDim>::rotateLevelSet(MInt returnMode, MFloat* cellData, MInt body, const MFloat* xCoord,
17948 const MFloat* xCenter, const MFloat* angle) {
17951 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "rotateLevelSet needs to be updated to 2D!
");
17953 switch(returnMode) {
17954 case 1: // current coordinate
17955 cellData[0] = xCenter[0] + (cos(angle[1]) * cos(angle[0])) * (xCoord[0] - xCenter[0])
17956 + (cos(angle[1]) * sin(angle[0])) * (xCoord[1] - xCenter[1])
17957 + (-sin(angle[1])) * (xCoord[2] - xCenter[2]);
17961 + (sin(angle[2]) * sin(angle[1]) * cos(angle[0]) - cos(angle[2]) * sin(angle[0])) * (xCoord[0] - xCenter[0])
17962 + (sin(angle[2]) * sin(angle[1]) * sin(angle[0]) + cos(angle[2]) * cos(angle[0])) * (xCoord[1] - xCenter[1])
17963 + (sin(angle[2]) * cos(angle[1])) * (xCoord[2] - xCenter[2]);
17967 + (cos(angle[2]) * sin(angle[1]) * cos(angle[0]) + sin(angle[2]) * sin(angle[0])) * (xCoord[0] - xCenter[0])
17968 + (cos(angle[2]) * sin(angle[1]) * sin(angle[0]) - sin(angle[2]) * cos(angle[0])) * (xCoord[1] - xCenter[1])
17969 + (cos(angle[2]) * cos(angle[1])) * (xCoord[2] - xCenter[2]);
17973 case 2: // current velocity
17976 ((m_omega[body * nDim + 1] * cos(angle[0]) + m_omega[body * nDim + 2] * sin(angle[0]) * cos(angle[1]))
17977 * (xCoord[2] - xCenter[2])
17978 - (m_omega[body * nDim + 0] - m_omega[body * nDim + 2] * sin(angle[1])) * (xCoord[1] - xCenter[1]));
17980 ((m_omega[body * nDim + 0] - m_omega[body * nDim + 2] * sin(angle[1])) * (xCoord[0] - xCenter[0])
17981 - (-m_omega[body * nDim + 1] * sin(angle[0]) + m_omega[body * nDim + 2] * cos(angle[0]) * cos(angle[1]))
17982 * (xCoord[2] - xCenter[2]));
17984 ((-m_omega[body * nDim + 1] * sin(angle[0]) + m_omega[body * nDim + 2] * cos(angle[0]) * cos(angle[1]))
17985 * (xCoord[1] - xCenter[1])
17986 - (m_omega[body * nDim + 1] * cos(angle[0]) + m_omega[body * nDim + 2] * sin(angle[0]) * cos(angle[1]))
17987 * (xCoord[0] - xCenter[0]));
17991 case 3: // current acceleration
17993 MFloat omeg[3], omegRad[3];
17995 rotateLevelSet(5, omeg, body, nullptr, nullptr, &m_semiLagrange_xRot_STL[body * nDim]);
17996 rotateLevelSet(2, omegRad, body, xCoord, xCenter, &m_semiLagrange_xRot_STL[body * nDim]);
17998 cellData[0] = omeg[1] * omegRad[2] - omeg[2] * omegRad[1];
17999 cellData[1] = omeg[2] * omegRad[0] - omeg[0] * omegRad[2];
18000 cellData[2] = omeg[0] * omegRad[1] - omeg[1] * omegRad[0];
18004 case 4: // current angle
18006 cellData[0] = angle[0];
18007 cellData[1] = angle[1];
18008 cellData[2] = angle[2];
18012 case 5: // current angular velocity
18015 (-m_omega[body * nDim + 1] * sin(angle[0]) + m_omega[body * nDim + 2] * cos(angle[0]) * cos(angle[1]));
18017 (m_omega[body * nDim + 1] * cos(angle[0]) + m_omega[body * nDim + 2] * sin(angle[0]) * cos(angle[1]));
18018 cellData[2] = (m_omega[body * nDim + 0] - m_omega[body * nDim + 2] * sin(angle[1]));
18022 case 6: // current angular acceleration
18043template <MInt nDim>
18044MInt LsCartesianSolver<nDim>::getContainingCellHalo(MFloat* point) {
18049 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
18050 for(MInt j = 0; j < noHaloCells(i); j++) {
18051 cellId = haloCellId(i, j);
18052 if(a_level(cellId) != a_maxGCellLevel() || (!m_reconstructOldG && m_initialGCell[cellId] == 0)) continue;
18054 if(inCell(cellId, point)) {
18055 cerr << "Halo
" << cellId << " " << c_coordinate(cellId, 0) << " " << c_coordinate(cellId, 1) << " "
18056 << c_coordinate(cellId, 2) << endl;
18073template <MInt nDim>
18074void LsCartesianSolver<nDim>::processRotatingLevelSet(MFloat& phi, MInt& cellId, MInt& domId, MFloat* point, MInt set) {
18077 if(a_level(cellId) != a_maxGCellLevel() || (!m_reconstructOldG && m_initialGCell[cellId] == 0)) {
18078 mTerm(1, AT_, "ContainingCell is not initialGCell or on maxLevel!
");
18080 const MInt magic_number = 8; // pow(2, nDim);
18081 std::array<MInt, magic_number> interpolationCells = {0, 0, 0, 0, 0, 0, 0, 0};
18083 // Set up interpolation stencil
18084 position = setUpLevelSetInterpolationStencil(cellId, interpolationCells.data(), point);
18085 // Check if all interpolationCells are initialGCells
18086 if(position > -1) {
18087 for(MInt i = 0; i < 8; i++) {
18088 if(a_level(interpolationCells[i]) != a_maxGCellLevel()
18089 || (!m_reconstructOldG && m_initialGCell[interpolationCells[i]] == 0)) {
18090 mTerm(1, AT_, "interpolationCell is not initialGCell!
");
18096 // Interpolate level set
18097 if(position > -1) {
18098 phi = interpolateOldLevelSet(interpolationCells.data(), point, set);
18100 phi = a_oldLevelSetFunctionG(cellId, set);
18103 if(a_isHalo(cellId)) {
18104 if(!m_reconstructOldG) {
18105 domId = m_cellDomIds[cellId * 2 + 1];
18106 cellId = m_cellDomIds[cellId * 2 + 0];
18118template <MInt nDim>
18119MInt LsCartesianSolver<nDim>::cellOutside(const MFloat* coords, const MInt level, const MInt gridCellId) {
18120 // TODO labels:LS,toremove remove and update fv-combustion testcases accordingly!
18121 if(m_combustion) return -1;
18123 if(m_engineSetup) {
18127 if(m_virtualSurgery) {
18131 std::ignore = gridCellId;
18133 static constexpr MInt cornerIndices[8][3] = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1},
18134 {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
18135 MFloat corner[3] = {0, 0, 0};
18136 MBool outside = true;
18137 MFloat cellHalfLength = F1B2 * c_cellLengthAtLevel(level);
18139 for(MInt i = 0; i < m_noCorners; i++) {
18140 for(MInt dim = 0; dim < nDim; dim++) {
18141 corner[dim] = coords[dim] + cornerIndices[i][dim] * cellHalfLength;
18143 IF_CONSTEXPR(nDim == 2) {
18144 if(!m_geometry->pointIsInside(corner)) outside = false;
18145 // pointIsInside == true if Point is outside fluid domain
18148 if(!m_geometry->pointIsInside2(corner)) outside = false;
18149 // pointIsInside == true if Point is outside fluid domain
18153 // Why? pointIsInside checks for the outer geometry
18154 // if(m_levelSetSign[0] < 0) {
18155 // outside = !outside;
18169template <MInt nDim>
18170MInt LsCartesianSolver<nDim>::noLoadTypes() const {
18172 // band-Cells and G0-Cells
18173 const MInt noLsLoadTypes = m_weightLevelSet ? 3 : 1;
18174 return noLsLoadTypes;
18179template <MInt nDim>
18180void LsCartesianSolver<nDim>::getDefaultWeights(MFloat* weights, std::vector<MString>& names) const {
18183 // TODO labels:LS set sensible default values
18185 names[0] = "ls_cell
";
18188 if(m_weightLevelSet) {
18190 names[1] = "ls_band_cell
";
18194 names[2] = "ls_g0_cell
";
18198 if(noLoadTypes() != count) {
18199 TERMM(1, "Count does not match noLoadTypes.
");
18211template <MInt nDim>
18212void LsCartesianSolver<nDim>::getLoadQuantities(MInt* const loadQuantities) const {
18215 // Nothing to do if solver is not active
18221 for(MInt type = 0; type < noLoadTypes(); type++) {
18222 loadQuantities[type] = 0;
18226 loadQuantities[0] = noInternalCells();
18228 MInt noBandCells = 0;
18229 MInt noG0Cells = 0;
18230 if(m_weightLevelSet) {
18231 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18232 MBool inAnyBand = false;
18233 for(MInt set = (MInt)m_buildCollectedLevelSetFunction; set < m_noSets; set++) {
18234 if(a_inBandG(cellId, set) && !inAnyBand) {
18238 if(a_isGZeroCell(cellId, set)) {
18246 loadQuantities[1] = noBandCells;
18247 loadQuantities[2] = noG0Cells;
18260template <MInt nDim>
18261MFloat LsCartesianSolver<nDim>::getCellLoad(const MInt gridCellId, const MFloat* const weights) const {
18263 ASSERT(isActive(), "solver is not active
");
18265 // Convert to solver cell id and check
18266 const MInt cellId = grid().tree().grid2solver(gridCellId);
18271 if(cellId < 0 || cellId >= grid().noInternalCells()) {
18272 TERMM(1, "The given cell
id is
invalid.
");
18275 // Default cell load
18276 MFloat cellLoad = weights[0];
18278 if(m_weightLevelSet) {
18279 for(MInt set = (MInt)m_buildCollectedLevelSetFunction; set < m_noSets; set++) {
18280 if(a_inBandG(cellId, set)) {
18281 cellLoad = weights[1];
18282 if(a_isGZeroCell(cellId, set)) {
18283 cellLoad = weights[2];
18296template <MInt nDim>
18297void LsCartesianSolver<nDim>::limitWeights(MFloat* weights) {
18298 if(m_limitWeights) {
18299 weights[0] = mMax(weights[0], 0.01 * mMax(weights[1], weights[2]));
18307template <MInt nDim>
18308void LsCartesianSolver<nDim>::getSolverTimings(std::vector<std::pair<MString, MFloat>>& solverTimings,
18309 const MBool NotUsed(allTimings)) {
18312 const MString namePrefix = "b
" + std::to_string(solverId()) + "_
";
18314 const MFloat load = returnLoadRecord();
18315 const MFloat idle = returnIdleRecord();
18317 solverTimings.emplace_back(namePrefix + "loadLsCartesianSolver
", load);
18318 solverTimings.emplace_back(namePrefix + "idleLsCartesianSolver
", idle);
18320#ifdef MAIA_TIMER_FUNCTION
18321 solverTimings.emplace_back(namePrefix + "timeIntegration
", RETURN_TIMER_TIME(m_timers[Timers::TimeInt]));
18322 solverTimings.emplace_back(namePrefix + "firstEx
", RETURN_TIMER_TIME(m_timers[Timers::FirstEx]));
18323 solverTimings.emplace_back(namePrefix + "postTS
", RETURN_TIMER_TIME(m_timers[Timers::PostTime]));
18324 solverTimings.emplace_back(namePrefix + "finalize
", RETURN_TIMER_TIME(m_timers[Timers::Finalize]));
18325 solverTimings.emplace_back(namePrefix + "buildTube
", RETURN_TIMER_TIME(m_timers[Timers::BuildTube]));
18326 solverTimings.emplace_back(namePrefix + "setBand
", RETURN_TIMER_TIME(m_timers[Timers::SetBand]));
18327 solverTimings.emplace_back(namePrefix + "multiple
", RETURN_TIMER_TIME(m_timers[Timers::BuildMultiple]));
18336template <MInt nDim>
18337void LsCartesianSolver<nDim>::getDomainDecompositionInformation(std::vector<std::pair<MString, MInt>>& domainInfo) {
18340 MInt noBandCells = 0;
18341 MInt noG0Cells = 0;
18342 MInt noCells = noInternalCells();
18343 if(m_weightLevelSet) {
18344 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18345 MBool inAnyBand = false;
18346 for(MInt set = (MInt)m_buildCollectedLevelSetFunction; set < m_noSets; set++) {
18347 if(a_inBandG(cellId, set) && !inAnyBand) {
18351 if(a_isGZeroCell(cellId, set)) {
18359 const MString namePrefix = "b" + std::to_string(solverId()) + "_
";
18360 domainInfo.emplace_back(namePrefix + "noLsCells
", noCells);
18361 domainInfo.emplace_back(namePrefix + "noLsBandCells
", noBandCells);
18362 domainInfo.emplace_back(namePrefix + "noLsG0Cells
", noG0Cells);
18371template <MInt nDim>
18372MInt LsCartesianSolver<nDim>::checkSecondLayerCells(std::vector<MInt>& diag2Cells,
18373 std::map<MInt, std::vector<MInt>>& dirCode, MFloat* point) {
18378 std::vector<MInt> secondLayer;
18380 MInt nghbrId2, nghbrId3;
18381 MInt d1, d2, d3, e, w; //,g;
18382 MInt dir[3] = {0, 2, 4};
18383 MInt oDir[6] = {2, 4, 0, 4, 0, 2};
18385 for(MInt& diag2Cell : diag2Cells) {
18386 d[0] = dirCode[diag2Cell][0];
18387 d[1] = dirCode[diag2Cell][1];
18388 d[2] = dirCode[diag2Cell][2];
18391 for(MInt nghbr = 0; nghbr < 2 * nDim; nghbr++) {
18392 if(nghbr == d[nghbr / 2]) continue;
18393 nghbrId = c_neighborId(diag2Cell, nghbr);
18394 if(nghbrId == -1) continue;
18396 secondLayer.push_back(nghbrId);
18399 // add diagonal neighbors
18400 for(MInt i = 0; i < nDim; i++) {
18401 for(MInt j = 0; j < 2; j++) {
18403 nghbrId = c_neighborId(diag2Cell, d1);
18404 if(nghbrId == -1) continue;
18406 for(MInt k = 0; k < 2; k++) {
18407 for(MInt m = 0; m < 2; m++) {
18408 d2 = oDir[2 * e + k] + m;
18409 nghbrId2 = c_neighborId(nghbrId, d2);
18410 if(nghbrId2 == -1) continue;
18412 // if ( !(d1 == d[i]) && !(d2 == d[w]) )
18413 secondLayer.push_back(nghbrId2);
18415 for(MInt n = 0; n < 2; n++) {
18416 d3 = dir[nDim - e - w] + n;
18417 if(a_hasNeighbor(nghbrId2, d3)) {
18418 nghbrId3 = c_neighborId(nghbrId2, d3);
18421 // if ( !(d1 == d[i]) && !(d2 == d[w]) && !(d3 == d[g] ) )
18422 secondLayer.push_back(nghbrId3);
18431 std::sort(secondLayer.begin(), secondLayer.end());
18432 auto last = std::unique(secondLayer.begin(), secondLayer.end());
18433 secondLayer.erase(last, secondLayer.end());
18434 for(MInt& it : secondLayer) {
18435 if(inCell(it, point)) return it;
18447template <MInt nDim>
18448void LsCartesianSolver<nDim>::prepareGlobalComm(MInt* noCellsToDom) {
18451 ScratchSpace<MPI_Request> requestGlobal(grid().noDomains(), AT_, "requestGlobal
");
18455 requestGlobal.fill(MPI_REQUEST_NULL);
18457 m_globalSndOffsets[0] = 0;
18458 for(MInt i = 0; i < grid().noDomains(); i++) {
18459 if(domainId() == i) {
18460 m_globalSndOffsets[i + 1] = m_globalSndOffsets[i];
18462 m_globalSndOffsets[i + 1] = m_globalSndOffsets[i] + noCellsToDom[i];
18467 MIntScratchSpace noCellsToSend(grid().noDomains(), AT_, "sendData
");
18468 MIntScratchSpace noCellsToReceive(grid().noDomains(), AT_, "receiveData
");
18469 noCellsToSend.fill(0);
18470 noCellsToReceive.fill(0);
18472 m_globalRcvOffsets[0] = 0;
18473 // send the size of the data set
18474 for(MInt i = 0; i < grid().noDomains(); i++) {
18475 if(domainId() == i) continue;
18476 noCellsToSend.p[i] = noCellsToDom[i];
18477 MPI_Issend(&noCellsToSend.p[i], 1, MPI_INT, i, tag, mpiComm(), &requestGlobal[i], AT_, "noCellsToSend.p[i]
");
18480 // receive the size of the data set
18481 for(MInt i = 0; i < grid().noDomains(); i++) {
18482 if(domainId() == i) {
18483 m_globalRcvOffsets[i + 1] = m_globalRcvOffsets[i];
18485 MPI_Recv(&noCellsToReceive.p[i], 1, MPI_INT, i, tag, mpiComm(), &status, AT_, "noCellsToReceive.p[i]
");
18486 m_globalRcvOffsets[i + 1] = m_globalRcvOffsets[i] + noCellsToReceive.p[i];
18489 for(MInt i = 0; i < grid().noDomains(); i++) {
18490 if(domainId() == i) continue;
18491 MPI_Wait(&requestGlobal[i], &status, AT_);
18502template <MInt nDim>
18503void LsCartesianSolver<nDim>::sensorInterface(std::vector<std::vector<MFloat>>& sensors,
18504 std::vector<std::bitset<64>>& sensorCellFlag,
18505 std::vector<MFloat>& sensorWeight, MInt sensorOffset, MInt sen) {
18506 m_log << " - Sensor preparation
for the
interface sensor
" << endl;
18508 MIntScratchSpace inList(a_noCells(), AT_, "inList
");
18509 setInterfaceList(inList);
18511 for(MInt level = minLevel(); level < this->m_maxSensorRefinementLevel[sen]; level++) {
18512 this->markSurrndCells(inList, m_outerBandWidth[level], level, m_refineDiagonals);
18515 ASSERT(a_noCells() == grid().tree().size(), "");
18517 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18518 if(inList(cellId) == 0) {
18519 // if(a_oldLevelSetFunctionG(cellId , 0) > - m_outsideGValue &&
18520 // a_oldLevelSetFunctionG(cellId , 0) < m_outsideGValue ) continue;
18521 // keep the are of the old-levelSet-function refined!
18522 if(a_level(cellId) == minLevel()) continue;
18523 if(inList(c_parentId(cellId))) continue;
18524 if(c_noChildren(cellId) == 0) {
18525 const MInt gridCellId = grid().tree().solver2grid(cellId);
18526 sensors[sensorOffset + sen][gridCellId] = -1.0;
18527 sensorCellFlag[gridCellId][sensorOffset + sen] = true;
18529 if(!m_reconstructOldG && m_LsRotate && globalTimeStep > 0) {
18530 if(m_initialGCell[cellId] == 1) {
18531 const MInt gridCellId = grid().tree().solver2grid(cellId);
18532 sensors[sensorOffset + sen][gridCellId] = 1.0;
18533 sensorCellFlag[gridCellId][sensorOffset + sen] = true;
18537 ASSERT(inList(cellId) > 0, "");
18538 const MInt gridCellId = grid().tree().solver2grid(cellId);
18539 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) { // refine cell
18540 if(c_noChildren(cellId) > 0) continue;
18541 if(a_isHalo(cellId)) continue;
18542 sensors[sensorOffset + sen][gridCellId] = 1.0;
18543 sensorCellFlag[gridCellId][sensorOffset + sen] = true;
18548 // find additional small-geometries:
18550 if(globalTimeStep < 0 && !m_combustion) {
18551 //&& m_adaptationLevel < this->m_maxSensorRefinementLevel[sen]
18553 /*&& !m_reconstructBand*/
18554 //&& !m_combustion) {
18555 if(m_engineSetup && m_adaptationLevel < this->m_maxSensorRefinementLevel[sen]) {
18556 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18557 for(MInt set = 0; set < m_noSets; set++) {
18558 if(!m_computeSet_backup[set]) continue;
18559 if(a_inBandG(cellId, set)) {
18560 const MInt gridCellId = grid().tree().solver2grid(cellId);
18561 sensors[sensorOffset + sen][gridCellId] = 1;
18562 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
18566 } else if(m_adaptationLevel == minLevel() && m_reconstructBand < 1) {
18567 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18568 for(MInt set = 0; set < m_noSets; set++) {
18569 if(a_inBandG(cellId, set)) {
18570 const MInt gridCellId = grid().tree().solver2grid(cellId);
18571 sensors[sensorOffset + sen][gridCellId] = 1;
18572 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
18580 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
18587template <MInt nDim>
18588void LsCartesianSolver<nDim>::setSensors(std::vector<std::vector<MFloat>>& sensors,
18589 std::vector<MFloat>& sensorWeight,
18590 std::vector<std::bitset<64>>& sensorCellFlag,
18591 std::vector<MInt>& sensorSolverId) {
18594 if(this->m_noSensors < 1) {
18598 // If solver is inactive the sensor arrays still need to be set to optain the
18601 const MInt sensorOffset = (signed)sensors.size();
18602 ASSERT(sensorOffset == 0 || grid().raw().treeb().noSolvers() > 1, "");
18603 sensors.resize(sensorOffset + this->m_noSensors, vector<MFloat>(grid().raw().m_noInternalCells, F0));
18604 sensorWeight.resize(sensorOffset + this->m_noSensors, -1);
18605 sensorCellFlag.resize(grid().raw().m_noInternalCells, sensorOffset + this->m_noSensors);
18606 sensorSolverId.resize(sensorOffset + this->m_noSensors, solverId());
18607 ASSERT(sensorOffset + this->m_noSensors < CartesianGrid<nDim>::m_maxNoSensors, "Increase bitset size!
");
18609 for(MInt sen = 0; sen < this->m_noSensors; sen++) {
18610 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
18616 // necessary here, as the sensors are also set on lower Grid-levels!
18617 // for avoid updateLowerGridLevels
18618 // updateLowerGridLevels();
18620 // the sensors are added at the end of the previous sensor-vectors!
18621 const auto sensorOffset = (signed)sensors.size();
18622 ASSERT(sensorOffset == 0 || grid().raw().treeb().noSolvers() > 1, "");
18623 sensors.resize(sensorOffset + this->m_noSensors, vector<MFloat>(grid().raw().m_noInternalCells, F0));
18624 sensorWeight.resize(sensorOffset + this->m_noSensors, -1);
18625 sensorCellFlag.resize(grid().raw().m_noInternalCells, sensorOffset + this->m_noSensors);
18626 sensorSolverId.resize(sensorOffset + this->m_noSensors, solverId());
18627 ASSERT(sensorOffset + this->m_noSensors < CartesianGrid<nDim>::m_maxNoSensors, "Increase bitset size!
");
18629 // Sohels-sensor-method:
18631 MIntScratchSpace regrid(1, AT_, "regrid
");
18633 // FIXME labels:LS,toenhance
18634 // more efficient solution can be found!!:
18635 // levelSetAdaptationTrigger is also run in the application loop at the moment to figure out if the grid controller
18636 // adaptation has to be forced for the ls-solver it is also included here in case that a different solver wants to
18637 // adapt since in that case this function has to do certain things even if levelSetAdaptationTrigger() is false
18638 regrid.p[0] = levelSetAdaptationTrigger();
18641 // only using this for initial refinement right now
18642 // should be removed once the proper initialAdaptation routines are used instead of this one
18643 if(globalTimeStep == 0 || globalTimeStep == -1) {
18647 // Use all sets for the mesh-adaptation!
18648 for(MInt set = 0; set < m_noSets; set++) {
18649 m_computeSet_tmp[set] = m_computeSet[set];
18650 m_computeSet[set] = true;
18654 // to remove, its replaced by levelSetAdaptationTrigger
18655 // From this part on a level-Set based adaptation will be triggered
18656 m_forceAdaptation = true;
18658 if(regrid.p[0] == 0) {
18662 MIntScratchSpace sendBufferSize(grid().noNeighborDomains(), AT_, "sendBufferSize
");
18663 MIntScratchSpace receiveBufferSize(grid().noNeighborDomains(), AT_, "receiveBufferSize
");
18666 MIntScratchSpace tmp(m_maxNoCells, AT_, "tmp
");
18667 MInt lastLayerCount = 0;
18668 MIntScratchSpace lastLayer(m_maxNoCells, AT_, "lastLayer
");
18669 MBoolScratchSpace isAdded(m_maxNoCells, AT_, "isAdded
");
18670 MInt listCount = 0;
18671 MIntScratchSpace list(m_maxNoCells, AT_, "list
");
18672 MBoolScratchSpace coarseningFlag(grid().raw().treeb().size(), AT_, "coarseningFlag
");
18674 for(MInt i = 0; i < a_noCells(); i++) {
18675 a_isBndryCellG(i) = false;
18678 for(MInt c = 0; c < m_maxNoCells; c++) {
18679 isAdded.p[c] = false;
18682 for(MInt c = 0; c < grid().raw().treeb().size(); c++) {
18683 coarseningFlag.p[c] = true;
18686 // if this is not done the g0 cells are sometimes not determined correctly after adaptation
18687 determineG0Cells(0);
18688 // first layer consists of g0 cells
18689 MInt endSet = m_noSets;
18690 if(m_buildCollectedLevelSetFunction) endSet = 1;
18691 for(MInt set = 0; set < endSet; set++) {
18692 for(MInt id = 0; id < a_noG0Cells(set); id++) {
18693 MInt cellId = a_G0CellId(id, set);
18694 if(a_isHalo(cellId)) continue; // dont add halo cells here
18695 lastLayer.p[lastLayerCount] = cellId;
18696 list.p[lastLayerCount] = cellId;
18697 isAdded.p[cellId] = true;
18703 ASSERT(lastLayerCount == listCount, "");
18705 // now add the correct halo cells to the list
18707 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
18708 sendBufferSize.p[i] = 0;
18709 for(MInt j = 0; j < noWindowCells(i); j++) {
18710 m_intSendBuffers[i][sendBufferSize.p[i]++] = isAdded(windowCellId(i, j));
18713 if(grid().azimuthalPeriodicity()) {
18714 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
18715 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
18716 m_intSendBuffers[i][sendBufferSize.p[i]++] = isAdded(grid().azimuthalWindowCell(i, j));
18720 // exchange data -> send, receive
18721 exchangeIntBuffers(sendBufferSize.getPointer(), receiveBufferSize.getPointer(), 4, 1);
18723 // update the halo information
18724 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
18726 // check, if received data size matches expected size:
18727 if(!(receiveBufferSize.p[i] == noHaloCells(i))) {
18728 cerr << "this was not expected to happen: wrong number of halo information, buf=
" << receiveBufferSize.p[i]
18729 << "noGHaloCells=
" << noHaloCells(i) << ", has been added
" << endl;
18733 for(MInt j = 0; j < noHaloCells(i); j++) {
18734 MInt gc = haloCellId(i, j);
18735 if(m_intReceiveBuffers[i][j]) {
18736 lastLayer.p[lastLayerCount] = gc;
18738 isAdded.p[gc] = true;
18742 if(grid().azimuthalPeriodicity()) {
18743 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
18744 MInt offset = noHaloCells(grid().azimuthalNeighborDomain(i));
18745 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
18746 MInt n = offset + j;
18747 MInt haloCell = grid().azimuthalHaloCell(i, j);
18748 if(m_intReceiveBuffers[i][n]) {
18749 lastLayer.p[lastLayerCount] = haloCell;
18751 isAdded.p[haloCell] = true;
18759 MInt level = minLevel();
18761 // calculate the number of layers of the current level
18762 MInt factor = IPOW2((a_maxGCellLevel(0) - level));
18763 MInt currentWidth = m_gShadowWidth / factor;
18764 if(currentWidth * factor < m_gShadowWidth) { // round up the currentWidth value
18767 if(currentWidth == 1) {
18768 cerr << "WARNING: you only have 1 layer of cells
for your level set band on the coarsest level right now... you
"
18769 "may want to rethink your level set grid resolution
"
18772 MInt currentLayer = 0;
18775 // add g0 cells to the list
18776 for(MInt i = 0; i < lastLayerCount; i++) {
18777 if(!isAdded.p[lastLayer.p[i]]) {
18778 list.p[listCount] = lastLayer.p[i];
18780 isAdded.p[lastLayer.p[i]] = true;
18784 while(currentLayer < currentWidth) {
18785 // find next layer of cells
18786 for(MInt i = 0; i < lastLayerCount; i++) {
18787 MInt gc = lastLayer.p[i];
18789 // if gc is on a higher level than the current level, take the parent until you find a parent with the correct
18791 while(a_level(gc) > level) {
18792 gc = c_parentId(gc);
18795 for(MInt d = 0; d < m_noDirs; d++) {
18796 if(a_hasNeighbor(gc, d)) {
18797 if(!isAdded.p[c_neighborId(gc, d)]) {
18798 tmp.p[tmpCount] = c_neighborId(gc, d);
18799 isAdded.p[tmp.p[tmpCount]] = true;
18806 // check if halo cells must be coarsened
18808 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
18809 sendBufferSize.p[i] = 0;
18810 for(MInt j = 0; j < noWindowCells(i); j++) {
18811 m_intSendBuffers[i][sendBufferSize.p[i]++] = isAdded(windowCellId(i, j));
18814 if(grid().azimuthalPeriodicity()) {
18815 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
18816 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
18817 m_intSendBuffers[i][sendBufferSize.p[i]++] = isAdded[grid().azimuthalWindowCell(i, j)];
18821 // exchange data -> send, receive
18822 exchangeIntBuffers(sendBufferSize.getPointer(), receiveBufferSize.getPointer(), 4, 1);
18824 // update the halo information
18825 for(MInt i = 0; i < grid().noNeighborDomains(); i++) {
18827 // check, if received data size matches expected size:
18828 if(!(receiveBufferSize.p[i] == noHaloCells(i))) {
18829 m_log << "this was not expected to happen: wrong number of halo information, buf=
" << receiveBufferSize.p[i]
18830 << "noGHaloCells=
" << noHaloCells(i) << ", has been added
" << endl;
18834 for(MInt j = 0; j < noHaloCells(i); j++) {
18835 MInt gc = haloCellId(i, j);
18836 if(m_intReceiveBuffers[i][j]) {
18837 tmp.p[tmpCount] = gc;
18838 isAdded.p[tmp.p[tmpCount]] = true;
18843 if(grid().azimuthalPeriodicity()) {
18844 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
18845 MInt offset = noHaloCells(grid().azimuthalNeighborDomain(i));
18846 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
18847 MInt n = offset + j;
18848 MInt haloCell = grid().azimuthalHaloCell(i, j);
18849 if(m_intReceiveBuffers[i][n]) {
18850 tmp.p[tmpCount] = haloCell;
18851 isAdded.p[tmp.p[tmpCount]] = true;
18858 // add new layer to list
18859 for(MInt i = 0; i < tmpCount; i++) {
18860 list.p[listCount] = tmp.p[i];
18862 // and replace the last layer list with the tmp list
18863 lastLayer.p[i] = tmp.p[i];
18865 lastLayerCount = tmpCount;
18870 // add all children to the list
18871 for(MInt i = 0; i < listCount; i++) {
18872 MInt gc = list.p[i];
18873 if(c_noChildren(gc) > 0) {
18874 for(MInt child = 0; child < IPOW2(nDim); child++) {
18875 if(c_childId(gc, child) == -1) {
18878 MInt cId = c_childId(gc, child);
18879 if(!isAdded.p[cId]) {
18880 isAdded.p[cId] = true;
18881 list.p[listCount] = cId;
18888 // set sensor for all cells that have been added to the list
18889 for(MInt c = 0; c < listCount; c++) {
18890 MInt gridCellId = grid().tree().solver2grid(list.p[c]);
18891 coarseningFlag.p[gridCellId] = false;
18892 if(a_level(list.p[c]) < a_maxGCellLevel(0)) { // refine cell
18893 if(c_noChildren(list.p[c]) > 0) continue;
18894 if(a_isHalo(list.p[c])) continue;
18895 sensors[sensorOffset][gridCellId] = 1.0;
18896 sensorCellFlag[gridCellId][sensorOffset] = 1;
18900 // now coarsen all cells that are not tagged and that have no children
18901 // only do this for the grid proxy though
18902 for(MInt i = 0; i < grid().tree().size(); i++) {
18903 if(!coarseningFlag.p[grid().tree().solver2grid(i)]) {
18906 if(grid().tree().level(i) == minLevel()) {
18909 if(grid().tree().noChildren(i) == 0) {
18910 MInt solverCellId = i;
18911 if(grid().tree().hasProperty(solverCellId, Cell::IsHalo)) {
18914 MInt gridCellId = grid().tree().solver2grid(solverCellId); // use correct grid id for the sensor
18915 sensors[sensorOffset][gridCellId] = -1.0;
18916 sensorCellFlag[gridCellId][sensorOffset] = 1;
18920 } else { // using Tims-sensor-method:
18922 // only set sensors if the adaptation was globally triggered in buildLevelSetTubeCG!
18923 if(this->m_adapts && ((m_forceAdaptation && globalTimeStep > 0) || (globalTimeStep < 0))) {
18924 if(domainId() == 0) {
18925 cerr << "Setting
" << this->m_noSensors << " sensor(s)
for the ls-solver adaptation!
" << endl;
18928 for(MInt sen = 0; sen < this->m_noSensors; sen++) {
18929 (this->*(this->m_sensorFnPtr[sen]))(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
18935 for(MInt i=0;i<grid().raw().treeb().size();i++){
18936 grid().raw().treeb().weight(i)=1;
18938 m_bodyIdOutput = true;
18939 MInt globalTimeStep_temp = globalTimeStep;
18940 globalTimeStep = m_adaptationLevel;
18941 // for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
18942 // const MInt gridCellId = grid().tree().solver2grid(cellId);
18943 // a_bodyIdG(cellId, 0) = sensors[sensorOffset][gridCellId];
18945 writeRestartLevelSetFileCG(1, "restartLSGridCG_sensors
" , "restartLSCG_sensors
");
18946 globalTimeStep = globalTimeStep_temp;
18949 ASSERT(m_freeIndices.empty(), "");
18950 m_freeIndices.clear();
18952 m_refinedCells.clear();
18960template <MInt nDim>
18961void LsCartesianSolver<nDim>::postAdaptation() {
18964 this->compactCells();
18966 if(!g_multiSolverGrid) {
18967 for(MInt gridCellId = 0; gridCellId < grid().raw().treeb().size(); gridCellId++) {
18968 ASSERT(grid().tree().solver2grid(gridCellId) == gridCellId, "");
18969 ASSERT(grid().tree().grid2solver(gridCellId) == gridCellId, "");
18974 grid().updateOther();
18976 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
18978 // Nothing further to be done if solver inactive
18979 if(!isActive()) return;
18981 grid().updateLeafCellExchange();
18983 ASSERT(!m_constructGField, "");
18985 generateListOfGExchangeCellsCG();
18987 this->checkNoHaloLayers();
18989 // Initialize the azimuthal periodic exchange
18990 initAzimuthalExchange();
18992 exchangeAllLevelSetData();
18995 // previous part from initialRefinement!
18996 if(globalTimeStep < 0 && m_geometryChange == nullptr) {
19000 for(MInt set = 0; set < m_noSets; set++) {
19001 std::vector<MInt>().swap(m_bandCells[set]);
19004 if(m_GFieldInitFromSTL) constructGFieldFromSTL(1);
19006 if(m_buildCollectedLevelSetFunction) buildCollectedLevelSet(0);
19008 determineG0Cells();
19011 if(m_GFieldInitFromSTL) {
19012 determineG0Cells();
19013 determineBandCells();
19014 m_log << "Initialize G Field from stl data...
";
19015 constructGFieldFromSTL(3);
19016 m_log << "ok
" << endl;
19017 for(MInt set = 0; set < m_noSets; set++) {
19018 std::vector<MInt>().swap(m_bandCells[set]);
19022 if(m_buildCollectedLevelSetFunction) buildCollectedLevelSet(0);
19023 determineG0Cells();
19024 determineBandCells();
19025 updateBndryCellList();
19026 resetOutsideCells();
19027 if(m_GFieldInitFromSTL) constructGFieldFromSTL(0);
19028 if(m_buildCollectedLevelSetFunction) buildCollectedLevelSet(0);
19029 if(m_GFieldInitFromSTL) resetOutsideCells();
19031 if(m_LsRotate) resetContainingGCells();
19032 exchangeAllLevelSetData();
19035 } else if(globalTimeStep < 0 && m_geometryChange != nullptr) {
19036 for(MInt set = 0; set < m_noSets; set++) {
19037 std::vector<MInt>().swap(m_bandCells[set]);
19040 determineG0Cells();
19041 determineBandCells();
19042 m_log << "Initialize G Field from mew stl data...
";
19043 constructGFieldFromSTL(5);
19044 m_log << "ok
" << endl;
19046 // NOTE: two loops ensure that new bandCells are also already initialised in the
19047 // first adaptationLoop. This increases the load but ensures the current
19048 // construction of the new levelSet Field!
19049 // thus only necessary if this is only called once!
19050 if(maxRefinementLevel() - maxUniformRefinementLevel() < 2) {
19051 for(MInt set = 0; set < m_noSets; set++) {
19052 std::vector<MInt>().swap(m_bandCells[set]);
19055 determineG0Cells();
19056 determineBandCells();
19057 updateBndryCellList();
19058 resetOutsideCells();
19060 determineG0Cells();
19061 determineBandCells();
19062 m_log << "Initialize G Field from mew stl data...
";
19063 constructGFieldFromSTL(5);
19064 m_log << "ok
" << endl;
19067 if(m_buildCollectedLevelSetFunction) buildCollectedLevelSet(2);
19069 reInitSolver(true);
19071 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
19072 for(MInt set = m_startSet; set < m_noSets; set++) {
19073 if(!m_geometryChange[set]) continue;
19074 a_oldLevelSetFunctionG(cellId, set) = a_levelSetFunctionG(cellId, set);
19078 if(m_LsRotate) resetContainingGCells();
19080 // exchange required afterwards
19081 exchangeDataLS(&(a_oldLevelSetFunctionG(0, 0)), m_maxNoSets);
19083 } else { // globalTimeStep > -1
19085 if(globalTimeStep == 0) {
19089 MInt noRefinedBandCells = (signed)m_refinedCells.size();
19090 MPI_Allreduce(MPI_IN_PLACE, &noRefinedBandCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE
",
19091 "noRefinedBandCells
");
19093 // On the fly reconstruction of levelset band cells outside the G0 Set!
19094 if(noRefinedBandCells > 0 && !m_virtualSurgery) {
19095 if(domainId() == 0 && m_reconstructBand > 1) {
19096 cerr << "Reinitialisation of
" << noRefinedBandCells << " cells
" << endl;
19098 if(domainId() == 0 && m_reconstructBand == 1) {
19099 cerr << "Interpolation of
" << noRefinedBandCells << " cells
" << endl;
19102 m_newRefinedBand = true;
19104 ASSERT(m_semiLagrange, "");
19105 ASSERT(m_reconstructBand > 0,
19106 "CAUTION: refining
a band cell after the initial adaptation without reconstructBand!
");
19108 ASSERT(m_GFieldInitFromSTL, "");
19110 // construct old-LevelSet data based on shifted geometry!
19111 if(m_reconstructBand > 1) {
19112 constructGFieldFromSTL(4);
19113 exchangeDataLS(&(a_oldLevelSetFunctionG(0, 0)), m_maxNoSets);
19115 if(m_maxLevelChange) {
19116 resetOldOutsideCells();
19119 // copy old levelset to levelset for stationary bodies
19120 for(auto& m_refinedCell : m_refinedCells) {
19121 const MInt cellId = m_refinedCell.first;
19122 ASSERT(!a_isHalo(cellId), "");
19123 const MInt set = m_refinedCell.second;
19125 if(!m_computeSet_backup[set]) {
19126 a_levelSetFunctionG(cellId, set) = a_oldLevelSetFunctionG(cellId, set);
19129 for(MInt setI = m_startSet; setI < m_noSets; setI++) {
19130 if(m_computeSet_backup[setI]) {
19133 a_levelSetFunctionG(cellId, setI) = a_oldLevelSetFunctionG(cellId, setI);
19138 // interpolate level set
19139 for(auto& m_refinedCell : m_refinedCells) {
19140 const MInt cellId = m_refinedCell.first;
19141 const MInt set = m_refinedCell.second;
19145 std::array<MInt, 8> interpolationCells = {0, 0, 0, 0, 0, 0, 0, 0};
19146 std::array<MFloat, nDim> cellPos = {};
19147 for(MInt i = 0; i < nDim; i++) {
19148 cellPos[i] = c_coordinate(cellId, i);
19150 const MInt parent = c_parentId(cellId);
19151 const MInt position = setUpLevelSetInterpolationStencil(parent, interpolationCells.data(), cellPos.data());
19152 if(position > -1) {
19153 a_levelSetFunctionG(cellId, set) = interpolateLevelSet(interpolationCells.data(), cellPos.data(), set);
19154 a_oldLevelSetFunctionG(cellId, set) =
19155 interpolateOldLevelSet(interpolationCells.data(), cellPos.data(), set);
19159 exchangeLevelSet();
19161 reInitSolver(m_forceAdaptation);
19163 if(grid().azimuthalPeriodicity()) {
19164 this->exchangeAzimuthalPer(&(a_oldLevelSetFunctionG(0, 0)), m_maxNoSets);
19172 for(MInt i=0;i<grid().raw().treeb().size();i++){
19173 grid().raw().treeb().weight(i)=1;
19175 MInt globalTimeStep_temp = globalTimeStep;
19176 globalTimeStep = m_adaptationLevel;
19177 writeRestartLevelSetFileCG(1, "restartLSGridCG_init
" , "restartLSCG_init
");
19178 globalTimeStep = globalTimeStep_temp;
19180 m_adaptationLevel++;
19188template <MInt nDim>
19189void LsCartesianSolver<nDim>::finalizeAdaptation() {
19192 // Set properties and return if solver is inactive
19194 m_forceAdaptation = false;
19195 m_adaptationSinceLastRestart = false;
19199 if(m_combustion || m_freeSurface) {
19200 finalizeLevelSet_(0, 0);
19201 m_forceAdaptation = false;
19202 m_adaptationSinceLastRestart = true;
19206 if(globalTimeStep > 0) { // part from reinitAfterAdaptation:
19209 reInitSolver(m_forceAdaptation);
19212 updateContainingGCells();
19213 copyWindowToHaloIds();
19216 if(m_maxLevelChange) {
19217 if(domainId() == 0) {
19218 cerr << "Ls-MaxLevel after adaptation:
" << maxLevel() << endl;
19222 } else if(m_geometryChange == nullptr) { // part from postInitialRefinementStep:
19224 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
19225 for(MInt set = 0; set < m_maxNoSets; set++) {
19226 if(!m_semiLagrange) {
19227 for(MInt d = 0; d < nDim; d++) {
19228 a_extensionVelocityG(cellId, d, set) = F0;
19231 a_oldLevelSetFunctionG(cellId, set) = a_levelSetFunctionG(cellId, set);
19234 if(m_maxNoSets > 1 && m_closeGaps) {
19235 a_potentialGapCell(cellId) = 0;
19236 a_potentialGapCellClose(cellId) = 0;
19240 setGCellBndryProperty();
19242 if(!m_semiLagrange) {
19243 computeNormalVectors();
19244 computeCurvature();
19247 finalizeLevelSetInitialization();
19249 buildMultipleLevelSet(2);
19251 if(m_GFieldFromSTLInitCheck) {
19252 // FIXME labels:LS hack to initialise weights,
19253 // necessary for writing a restart-file out of the solver, after an adaptation
19254 // move into the meshAdaptation to initialice new cells with weight 1/0
19255 for(MInt i = 0; i < grid().raw().treeb().size(); i++) {
19256 grid().raw().treeb().weight(i) = 1;
19259 MInt globalTimeStep_temp = globalTimeStep;
19260 globalTimeStep = 0;
19261 if(!m_initFromRestartFile) {
19262 writeRestartLevelSetFileCG(1, "restartLSGridCG_init
", "restartLSCG_init
");
19264 writeRestartLevelSetFileCG(1, "restartLSGridCG_reinit
", "restartLSCG_reinit
");
19266 globalTimeStep = globalTimeStep_temp;
19269 if(m_LSSolver) initSolver();
19271 } else { // globalTimeStep = -1 && m_geometryChange != nullptr
19273 finalizeLevelSetInitialization();
19275 if(!m_oldG0Cells.empty()) {
19277 if(m_buildCollectedLevelSetFunction) startSet = 1;
19279 // check new G0-cells and delete entries which were were also a G0 cell in the old geometry!
19280 for(MInt set = startSet; set < m_noSets; set++) {
19281 if(!m_geometryChange[set]) continue;
19282 for(MInt id = 0; id < a_noG0Cells(set); id++) {
19283 const MInt cellId = a_G0CellId(id, set);
19284 if(a_isHalo(cellId)) continue;
19285 auto it0 = m_oldG0Cells.find(cellId);
19286 if(it0 != m_oldG0Cells.end()) {
19287 const MInt oldSet = it0->second;
19288 if(oldSet == set) {
19289 m_oldG0Cells.erase(it0);
19297 if((m_maxLevelChange || m_geometryChange != nullptr) && m_trackMovingBndry) {
19299 ASSERT(m_GCtrlPntMethod == 2, "Only working
for controlPoint-Method 2!
");
19300 MFloat dx[3] = {F0, F0, F0};
19301 MFloat xCurrent[3] = {F0, F0, F0};
19302 MFloat xOld[3] = {F0, F0, F0};
19303 const MFloat usedTime = m_geometryChange != nullptr ? time() : time() + timeStep();
19304 for(MInt set = m_startSet; set < m_noSets; set++) {
19305 if(!m_computeSet_backup[set]) continue;
19306 for(MInt b = 0; b < m_noBodiesInSet[set]; b++) {
19307 const MInt body = m_setToBodiesTable[set][b];
19308 const MInt bcId = m_bodyBndryCndIds[body];
19309 computeBodyPropertiesForced(1, xCurrent, body, usedTime);
19310 computeBodyPropertiesForced(1, xOld, body, 0.0);
19312 for(MInt d = 0; d < nDim; d++) {
19313 // dx[d] = -(xCurrent[d] - xOld[d]);
19314 dx[d] = -m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body];
19316 m_gCtrlPnt.CtrlPnt2_shiftSTL(bcId, dx);
19321 // reset properties back to default after the sucessful adaptation
19322 if(m_maxLevelChange && (maxLevel() == maxRefinementLevel() || maxLevel() == this->m_maxSensorRefinementLevel[0])) {
19323 m_maxLevelChange = false;
19325 if(m_geometryChange != nullptr) {
19326 mDeallocate(m_geometryChange);
19329 exchangeAllLevelSetData();
19331 if(m_virtualSurgery) {
19332 if(globalTimeStep < 0) {
19333 initializeCollectedLevelSet(0);
19335 initializeCollectedLevelSet(1);
19339 // ASSERT sanity checks
19344 m_forceAdaptation = false;
19345 m_adaptationSinceLastRestart = true;
19352template <MInt nDim>
19353void LsCartesianSolver<nDim>::prepareAdaptation() {
19356 ASSERT(m_freeIndices.empty(), "");
19358 m_adaptationLevel = maxUniformRefinementLevel();
19359 m_newRefinedBand = false;
19360 m_oldG0Cells.clear();
19362 if(!isActive()) return;
19364 if(this->m_noSensors <= 0) {
19368 if(maxRefinementLevel() > maxLevel() && globalTimeStep > 0) {
19369 m_forceAdaptation = true;
19370 if(domainId() == 0) {
19371 cerr << "Max Refinement Level has been increased at restart.
" << endl;
19372 cerr << "Initialising interpolation at adaptation!
" << endl;
19375 // recalculate outside-G-value for max-Level-change!
19376 if(m_maxLevelChange) {
19377 if(!Context::propertyExists("maxGCellLevel
", m_solverId)) {
19378 m_maxGCellLevel[0] = Context::getSolverProperty<MInt>("maxRfnmntLvl
", m_solverId, AT_);
19380 m_maxGCellLevel[0] = Context::getSolverProperty<MInt>("maxGCellLevel
", m_solverId, AT_, 0);
19383 m_gCellDistance = c_cellLengthAtLevel(m_maxGCellLevel[0]);
19384 m_FgCellDistance = F1 / m_gCellDistance;
19385 m_log << "smallest gCell length
" << m_gCellDistance << endl;
19387 m_outsideGValue = (MFloat)(2 * m_gBandWidth * m_gCellDistance);
19388 m_log << "Outside G value:
" << m_outsideGValue << endl;
19392 if(this->m_maxSensorRefinementLevel[0] < maxLevel()) {
19393 m_forceAdaptation = true;
19394 if(domainId() == 0) {
19395 cerr << "Max Refinement Level has been decreased at restart.
" << endl;
19396 cerr << "Initialising interpolation at adaptation!
" << endl;
19398 if(Context::propertyLength("maxRfnmntLvl
", m_solverId) == 1) {
19399 m_maxGCellLevel[0] = this->m_maxSensorRefinementLevel[0];
19401 for(MInt set = 0; set < m_maxNoSets; set++) {
19402 m_maxGCellLevel[set] = this->m_maxSensorRefinementLevel[0];
19406 m_gCellDistance = c_cellLengthAtLevel(m_maxGCellLevel[0]);
19407 m_FgCellDistance = F1 / m_gCellDistance;
19408 m_log << "smallest gCell length
" << m_gCellDistance << endl;
19410 m_outsideGValue = (MFloat)(2 * m_gBandWidth * m_gCellDistance);
19411 m_log << "Outside G value:
" << m_outsideGValue << endl;
19414 if(grid().newMinLevel() > maxUniformRefinementLevel()) m_forceAdaptation = true;
19417 if(globalTimeStep < 0 && m_geometryChange != nullptr) {
19418 // save old G0-Cells, so that a sponging can be applied to the fv-solution
19419 // if they are no longer a G0-cell for the new geometry!
19422 if(m_buildCollectedLevelSetFunction) startSet = 1;
19424 for(MInt set = startSet; set < m_noSets; set++) {
19425 if(!m_geometryChange[set]) continue;
19426 for(MInt id = 0; id < a_noG0Cells(set); id++) {
19427 const MInt cellId = a_G0CellId(id, set);
19428 if(a_isHalo(cellId)) continue;
19429 ASSERT(a_isGZeroCell(cellId, set), "");
19430 m_oldG0Cells.insert(make_pair(cellId, set));
19435 // the levelset of a moving STL will be reconstructed during the adaptation!
19436 // shift all STLs to the correct place
19437 if((m_geometryChange != nullptr || m_maxLevelChange) && m_trackMovingBndry) {
19438 ASSERT(m_GCtrlPntMethod == 2, "Only working
for controlPoint-Method 2!
");
19439 MFloat dx[3] = {F0, F0, F0};
19440 MFloat xCurrent[3] = {F0, F0, F0};
19441 MFloat xOld[3] = {F0, F0, F0};
19442 const MFloat usedTime = m_geometryChange != nullptr ? time() : time() + timeStep();
19443 for(MInt set = m_startSet; set < m_noSets; set++) {
19444 if(!m_computeSet_backup[set]) continue;
19445 for(MInt b = 0; b < m_noBodiesInSet[set]; b++) {
19446 const MInt body = m_setToBodiesTable[set][b];
19447 const MInt bcId = m_bodyBndryCndIds[body];
19448 computeBodyPropertiesForced(1, xCurrent, body, usedTime);
19449 computeBodyPropertiesForced(1, xOld, body, 0.0);
19451 for(MInt d = 0; d < nDim; d++) {
19452 // dx[d] = xCurrent[d] - xOld[d];
19453 dx[d] = m_semiLagrange_xShift_ref[d * m_noEmbeddedBodies + body];
19455 m_gCtrlPnt.CtrlPnt2_shiftSTL(bcId, dx);
19466template <MInt nDim>
19467void LsCartesianSolver<nDim>::postTimeStep() {
19470 if(!m_trackMovingBndry || globalTimeStep < m_trackMbStart || globalTimeStep > m_trackMbEnd) {
19474 RECORD_TIMER_START(m_timers[Timers::PostTime]);
19477 m_forceAdaptation = levelSetAdaptationTrigger();
19478 if(!m_forceAdaptation) {
19479 finalizeLevelSet_(0, 0);
19482 } else if(m_freeSurface) {
19483 finalizeLevelSet_(0, 0);
19486 finalizeLevelSet();
19489 RECORD_TIMER_STOP(m_timers[Timers::PostTime]);
19497template <MInt nDim>
19498void LsCartesianSolver<nDim>::reInitSolver(const MBool regrid) {
19502 for(MInt set = 0; set < m_noSets; set++) {
19503 std::vector<MInt>().swap(m_bandCells[set]);
19504 m_computeSet[set] = true;
19505 m_changedSet[set] = true;
19508 // recreate a_regridTriggerG
19510 determineG0Cells();
19511 if(m_buildCollectedLevelSetFunction) determineG0Cells(0);
19513 createGgridCG(); // requires all G0-cells
19515 determineG0Cells();
19518 determineBandCells();
19520 if(!m_semiLagrange) {
19521 setGCellBndryProperty();
19522 updateBndryCellList();
19525 resetOutsideCells();
19527 setUpPotentialGapCells();
19528 buildMultipleLevelSet(2);
19531 updateLowerGridLevels();
19533 exchangeAllLevelSetData();
19537 // reset m_computeSet, to the original values before the adaptation
19538 if(globalTimeStep > -1) {
19539 for(MInt set = 0; set < m_noSets; set++) {
19540 m_computeSet[set] = m_computeSet_backup[set];
19552template <MInt nDim>
19553MFloat LsCartesianSolver<nDim>::crankAngle(const MFloat elapsedTime, const MInt mode) {
19556 MFloat& Strouhal = m_static_crankAngle_Strouhal;
19557 MFloat& initialCad = m_static_crankAngle_initialCad;
19559 if(initialCad < 0) {
19560 Strouhal = Context::getSolverProperty<MFloat>("Strouhal
", m_solverId, AT_, &Strouhal);
19562 initialCad = Context::getSolverProperty<MFloat>("initialCrankAngle
", m_solverId, AT_, &initialCad);
19565 return maia::math::crankAngle(elapsedTime, Strouhal, initialCad, mode);
19572template <MInt nDim>
19573void LsCartesianSolver<nDim>::initAzimuthalExchange() {
19576 if(grid().noAzimuthalNeighborDomains() == 0) return;
19578 MUint sndSize = maia::mpi::getBufferSize(grid().azimuthalHaloCells());
19579 MFloatScratchSpace haloBuff(sndSize * nDim, AT_, "haloBuff
");
19581 MUint rcvSize = maia::mpi::getBufferSize(grid().azimuthalWindowCells());
19582 MFloatScratchSpace windowBuff(rcvSize * nDim, AT_, "windowBuff
");
19583 windowBuff.fill(0);
19585 this->m_azimuthalCartRecCoord.clear();
19586 this->m_azimuthalCartRecCoord.reserve(rcvSize * nDim);
19588 // Get azimuthal image coordinate
19589 MFloat angle = grid().azimuthalAngle();
19591 MFloat haloCoords[nDim];
19592 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
19593 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
19594 MInt haloId = grid().azimuthalHaloCell(i, j);
19595 ASSERT(grid().raw().a_hasProperty(grid().tree().solver2grid(haloId), Cell::IsPeriodic),
19596 "azimuthal halo is not isPeriodic!
");
19598 for(MInt d = 0; d < nDim; d++) {
19599 haloCoords[d] = c_coordinate(haloId, d);
19602 MInt side = grid().determineAzimuthalBoundarySide(haloCoords);
19604 grid().rotateCartesianCoordinates(haloCoords, (side * angle));
19606 for(MInt d = 0; d < nDim; d++) {
19607 haloBuff[sndCnt++] = haloCoords[d];
19612 maia::mpi::exchangeBuffer(grid().azimuthalNeighborDomains(), grid().azimuthalWindowCells(),
19613 grid().azimuthalHaloCells(), mpiComm(), haloBuff.getPointer(), windowBuff.getPointer(),
19617 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
19618 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
19619 for(MInt d = 0; d < nDim; d++) {
19620 this->m_azimuthalCartRecCoord[rcvCnt] = windowBuff[rcvCnt];
19630template <MInt nDim>
19631void LsCartesianSolver<nDim>::rotateSTL(MInt direction, MInt body, MFloat* center) {
19634 MFloat phiRot[nDim];
19635 const MInt bcId = m_bodyBndryCndIds[body];
19637 for(MInt n = 0; n < nDim; n++) {
19638 phiRot[n] = -1 * direction * m_semiLagrange_xRot_STL[body * nDim + n];
19641 m_gCtrlPnt.CtrlPnt2_rotateSTL(bcId, phiRot, center);
19647template <MInt nDim>
19648void LsCartesianSolver<nDim>::rotateSTL(MInt direction) {
19651 MFloat center[nDim];
19653 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
19654 const MInt body = m_bodiesToCompute[b];
19656 computeBodyPropertiesForced(1, center, body, time());
19658 rotateSTL(direction, body, center);
19665template <MInt nDim>
19666void LsCartesianSolver<nDim>::localToGlobalIdsContainingCells() {
19669 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
19670 MInt body = m_bodiesToCompute[b];
19671 MInt set = m_bodyToSetTable[body];
19673 MIntScratchSpace noCellsToDom(grid().noDomains(), AT_, "noCellsToDom
");
19674 noCellsToDom.fill(0);
19676 for(MInt id = 0; id < a_noBandCells(set); id++) {
19677 MInt cellId = a_bandCellId(id, set);
19678 if(!(a_bodyIdG(cellId, set) == body)) continue;
19679 if(grid().tree().hasProperty(cellId, Cell::IsHalo)) continue;
19680 if(a_level(cellId) != a_maxGCellLevel()) continue;
19682 MInt domId = a_containingDomain(cellId, b);
19684 noCellsToDom[domId]++;
19688 startLoadTimer(AT_);
19690 prepareGlobalComm(&noCellsToDom[0]);
19692 MInt noCellsComm = mMax(m_globalSndOffsets[grid().noDomains()], m_globalRcvOffsets[grid().noDomains()]);
19694 MLongScratchSpace sndBufGlob(noCellsComm, AT_, "sndBufGlob
");
19695 MLongScratchSpace rcvBufGlob(noCellsComm, AT_, "rcvBufGlob
");
19696 MIntScratchSpace sndBufSizeGlob(grid().noDomains(), AT_, "sndBufSizeGlob
");
19697 MIntScratchSpace rcvBufSizeGlob(grid().noDomains(), AT_, "rcvBufSizeGlob
");
19699 sndBufGlob.fill(-1);
19700 rcvBufGlob.fill(-1);
19701 sndBufSizeGlob.fill(0);
19702 rcvBufSizeGlob.fill(0);
19704 std::vector<std::vector<MInt>> cellIdsLoc;
19705 cellIdsLoc.resize(grid().noDomains());
19707 for(MInt cell = 0; cell < a_noCells(); cell++) {
19708 if(a_isHalo(cell)) continue;
19709 ASSERT(a_domainId(c_globalId(cell)) == domainId(), "globalId conversion is broken!
");
19710 MInt cellId = a_containingCell(cell, b);
19711 if(cellId > -1 && a_inBandG(cell, set) && a_bodyIdG(cell, set) == body && a_level(cell) == a_maxGCellLevel()) {
19712 MInt domId = a_containingDomain(cell, b);
19713 if(domainId() == domId) {
19714 ASSERT(a_localId(c_globalId(cellId)) == cellId, "GlobalId conversion is broken!
");
19715 a_containingCell(cell, b) = c_globalId(cellId);
19717 cellIdsLoc[domId].push_back(cell);
19718 sndBufGlob[m_globalSndOffsets[domId] + sndBufSizeGlob.p[domId]] = cellId;
19719 sndBufSizeGlob.p[domId]++;
19722 a_containingCell(cell, b) = -1;
19726 exchangeBuffersGlobal(sndBufGlob.getPointer(), rcvBufGlob.getPointer(), sndBufSizeGlob.getPointer(),
19727 rcvBufSizeGlob.getPointer(), &m_globalSndOffsets[0], &m_globalRcvOffsets[0], 3);
19729 sndBufGlob.fill(-1);
19730 sndBufSizeGlob.fill(0);
19731 for(MInt i = 0; i < grid().noDomains(); i++) {
19732 MInt ind = m_globalRcvOffsets[i];
19733 for(MInt j = 0; j < rcvBufSizeGlob(i); j++) {
19734 MInt cellId = rcvBufGlob(ind + j);
19735 ASSERT(a_localId(c_globalId(cellId)) == cellId, "GlobalId conversion is broken!
");
19736 sndBufGlob(ind + sndBufSizeGlob.p[i]) = c_globalId(cellId);
19737 sndBufSizeGlob.p[i]++;
19740 rcvBufGlob.fill(-1);
19741 rcvBufSizeGlob.fill(0);
19743 exchangeBuffersGlobal(sndBufGlob.getPointer(), rcvBufGlob.getPointer(), sndBufSizeGlob.getPointer(),
19744 rcvBufSizeGlob.getPointer(), &m_globalRcvOffsets[0], &m_globalSndOffsets[0], 3);
19746 for(MInt i = 0; i < grid().noDomains(); i++) {
19747 MInt ind = m_globalSndOffsets[i];
19748 for(MInt j = 0; j < rcvBufSizeGlob(i); j++) {
19749 MInt cellId = cellIdsLoc[i][j];
19750 a_containingCell(cellId, b) = rcvBufGlob(ind + j);
19759template <MInt nDim>
19760void LsCartesianSolver<nDim>::globalToLocalIdsContainingCells() {
19763 MIntScratchSpace noCellsToDom(grid().noDomains(), AT_, "noCellsToDom
");
19764 noCellsToDom.fill(0);
19766 for(MInt b = 0; b < m_noBodiesToCompute; b++) {
19767 for(MInt i = 0; i < a_noCells(); ++i) {
19768 if(grid().tree().hasProperty(i, Cell::IsHalo)) continue;
19769 if(a_level(i) != a_maxGCellLevel()) continue;
19771 MLong globalId = a_containingCell(i, b);
19772 if(globalId > -1) {
19773 MInt domId = a_domainId(globalId);
19774 noCellsToDom[domId]++;
19778 prepareGlobalComm(&noCellsToDom[0]);
19780 MInt noCellsComm = mMax(m_globalSndOffsets[grid().noDomains()], m_globalRcvOffsets[grid().noDomains()]);
19782 MLongScratchSpace sndBufGlob(noCellsComm, AT_, "sndBufGlob
");
19783 MLongScratchSpace rcvBufGlob(noCellsComm, AT_, "rcvBufGlob
");
19784 MIntScratchSpace sndBufSizeGlob(grid().noDomains(), AT_, "sndBufSizeGlob
");
19785 MIntScratchSpace rcvBufSizeGlob(grid().noDomains(), AT_, "rcvBufSizeGlob
");
19786 sndBufGlob.fill(-1);
19787 rcvBufGlob.fill(-1);
19788 sndBufSizeGlob.fill(0);
19789 rcvBufSizeGlob.fill(0);
19791 std::vector<std::vector<MInt>> cellIdsLoc;
19792 cellIdsLoc.resize(grid().noDomains());
19794 for(MInt i = 0; i < a_noCells(); ++i) {
19795 if(grid().tree().hasProperty(i, Cell::IsHalo)) continue;
19797 ASSERT(a_domainId(c_globalId(i)) == domainId(), "globalId conversion is broken!
");
19799 MLong globalId = a_containingCell(i, b);
19800 if(globalId > -1 && a_level(i) == a_maxGCellLevel()) {
19801 MInt domId = a_domainId(globalId);
19802 if(domainId() == domId) {
19803 ASSERT(c_globalId(a_localId(globalId)) == globalId, "GlobalId conversion is broken!
");
19804 a_containingCell(i, b) = a_localId(globalId);
19805 a_containingDomain(i, b) = domId;
19807 cellIdsLoc[domId].push_back(i);
19808 sndBufGlob[m_globalSndOffsets[domId] + sndBufSizeGlob.p[domId]] = globalId;
19809 sndBufSizeGlob.p[domId]++;
19812 a_containingCell(i, b) = -1;
19813 a_containingDomain(i, b) = -1;
19817 exchangeBuffersGlobal(sndBufGlob.getPointer(), rcvBufGlob.getPointer(), sndBufSizeGlob.getPointer(),
19818 rcvBufSizeGlob.getPointer(), &m_globalSndOffsets[0], &m_globalRcvOffsets[0], 3);
19819 sndBufGlob.fill(-1);
19820 sndBufSizeGlob.fill(0);
19822 for(MInt i = 0; i < grid().noDomains(); i++) {
19823 MInt ind = m_globalRcvOffsets[i];
19824 for(MInt j = 0; j < rcvBufSizeGlob(i); j++) {
19825 MLong globalId = rcvBufGlob(ind + j);
19826 ASSERT(c_globalId(a_localId(globalId)) == globalId, "GlobalId conversion is broken!
");
19827 sndBufGlob(ind + sndBufSizeGlob.p[i]) = a_localId(globalId);
19828 sndBufSizeGlob.p[i]++;
19831 rcvBufGlob.fill(-1);
19832 rcvBufSizeGlob.fill(0);
19834 exchangeBuffersGlobal(sndBufGlob.getPointer(), rcvBufGlob.getPointer(), sndBufSizeGlob.getPointer(),
19835 rcvBufSizeGlob.getPointer(), &m_globalRcvOffsets[0], &m_globalSndOffsets[0], 3);
19837 for(MInt i = 0; i < grid().noDomains(); i++) {
19838 MInt ind = m_globalSndOffsets[i];
19839 for(MInt j = 0; j < rcvBufSizeGlob(i); j++) {
19840 MInt containingId = rcvBufGlob(ind + j);
19841 MInt cellId = cellIdsLoc[i][j];
19843 a_containingCell(cellId, b) = containingId;
19844 a_containingDomain(cellId, b) = i;
19854template <MInt nDim>
19855void LsCartesianSolver<nDim>::localToGlobalIds() {
19858 // Nothing to do if solver is not active
19863 if(!m_reconstructOldG && m_LsRotate) {
19864 updateContainingGCells();
19865 localToGlobalIdsContainingCells();
19872template <MInt nDim>
19873void LsCartesianSolver<nDim>::reconstructOldGField() {
19876 if(domainId() == 0) cerr << "Reconstruct oldG Field...
";
19878 mAlloc(m_geometryChange, m_noSets, "geometryChange
", false, AT_);
19879 for(MInt i = 0; i < m_noBodiesToCompute; i++) {
19880 MInt body = m_bodiesToCompute[i];
19881 MInt set = m_bodyToSetTable[body];
19882 m_geometryChange[set] = true;
19885 constructGFieldFromSTL(6);
19887 constructGFieldFromSTL(5);
19888 if(m_buildCollectedLevelSetFunction) buildCollectedLevelSet(0);
19889 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
19890 for(MInt set = m_startSet; set < m_noSets; set++) {
19891 if(!m_geometryChange[set]) continue;
19892 a_oldLevelSetFunctionG(cellId, set) = a_levelSetFunctionG(cellId, set);
19897 mDeallocate(m_geometryChange);
19898 // Reset the rotated angle
19899 for(MInt i = 0; i < m_noBodiesToCompute; i++) {
19900 MInt body = m_bodiesToCompute[i];
19901 for(MInt d = 0; d < nDim; d++) {
19902 m_semiLagrange_xRot_ref[body * nDim + d] = F0;
19905 resetContainingGCells();
19907 m_rotatingReinitTrigger = 0;
19908 if(domainId() == 0) cerr << " done
" << endl;
19916template <MInt nDim>
19917template <MBool currentLevelSet>
19918void LsCartesianSolver<nDim>::exchangeLeafDataLS() {
19921 if(m_firstSolutionExchange) {
19922 RECORD_TIMER_START(m_timers[Timers::FirstEx]);
19925 std::function<MFloat&(const MInt, const MInt)> scalarField = [&](const MInt cellId, const MInt set) -> MFloat& {
19926 IF_CONSTEXPR(currentLevelSet) { return a_levelSetFunctionG(cellId, set); }
19928 return a_oldLevelSetFunctionG(cellId, set);
19932 this->exchangeLeafData(scalarField, m_maxNoSets);
19934 if(grid().azimuthalPeriodicity()) {
19935 IF_CONSTEXPR(currentLevelSet) { this->exchangeAzimuthalPer(&a_levelSetFunctionG(0, 0), m_maxNoSets); }
19937 this->exchangeAzimuthalPer(&a_oldLevelSetFunctionG(0, 0), m_maxNoSets);
19941 if(m_firstSolutionExchange) {
19942 RECORD_TIMER_STOP(m_timers[Timers::FirstEx]);
19943 m_firstSolutionExchange = false;
19953template <MInt nDim>
19954template <typename T>
19955void LsCartesianSolver<nDim>::exchangeDataLS(T* data, const MInt dataSize) {
19958 if(m_firstSolutionExchange) {
19959 RECORD_TIMER_START(m_timers[Timers::FirstEx]);
19962 exchangeData(data, dataSize);
19964 if(grid().azimuthalPeriodicity()) {
19965 this->exchangeAzimuthalPer(data, dataSize);
19968 if(m_firstSolutionExchange) {
19969 RECORD_TIMER_STOP(m_timers[Timers::FirstEx]);
19970 m_firstSolutionExchange = false;
19979template <MInt nDim>
19980void LsCartesianSolver<nDim>::initializeTimers() {
19983 std::fill(m_timers.begin(), m_timers.end(), -1);
19985 // Create timer group & timer for solver, and start the timer
19986 NEW_TIMER_GROUP_NOCREATE(m_timerGroup, "LS (solverId =
" + to_string(m_solverId) + ")
");
19987 NEW_TIMER_NOCREATE(m_timers[Timers::Solver], "total
object lifetime
", m_timerGroup);
19988 RECORD_TIMER_START(m_timers[Timers::Solver]);
19990 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::TimeInt], "Time-integration
", m_timers[Timers::Solver]);
19991 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::FirstEx], "firstLSExchange
", m_timers[Timers::TimeInt]);
19992 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::PostTime], "PostTimeStep
", m_timers[Timers::Solver]);
19993 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Finalize], "finalizeLS
", m_timers[Timers::PostTime]);
19994 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BuildTube], "buildLSTube
", m_timers[Timers::Finalize]);
19995 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SetBand], "setLSBand
", m_timers[Timers::Finalize]);
19996 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BuildMultiple], "buildMultipleLS
", m_timers[Timers::Finalize]);
19999template class LsCartesianSolver<2>;
20000template class LsCartesianSolver<3>;
MLong allocatedBytes()
Return the number of allocated bytes.
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
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.
void initializeIntegrationScheme_semiLagrange()
void updateAllLowerGridLevels(MInt mode=-1)
void identifyBodies(MInt mode=0)
sets a_bodyIdG(gCells,set) for all sets exept for the collected levelset (this is done in buildCollec...
void shiftOldLevelSetField(MInt dir, MInt set, MInt body)
void exchangeAllLevelSetData()
void setUpPotentialGapCells()
Set up cells, that may be tagged as gap cells during the solver run! Initialises the arrays,...
void setUpBodyToSetTable()
void regionGrowing(MInt cellId, MInt region)
MFloat secondOrderEikonalSolver(MFloat *q, const MInt *nghbrs, MInt cellListSize, MInt maxIterations, MInt set)
void computeCurvature(MInt mode=-1)
MBool semiLagrangeTimeStep()
void determineSteadyFlameLength()
void determinePropagationSpeed()
void finalizeLevelSetInitialization()
void exchangeIntBuffers(MInt *, MInt *, MInt, MInt)
void spatiallyAdaptiveCorrectionFromSTL()
this function does a correction based on the curvature of the geometry. The high curvature regions ar...
void extendVelocity(const MInt set)
void initializeGField()
Initializes the solver values with the values of the undisturbed flow The values are given by the pro...
void computeBodyPropertiesForced(MInt returnMode, MFloat *bodyData, MInt body, MFloat time, MBool printPosition=false)
returns a specific property of the specifuec body used to provide a unique function for both level-se...
void determineMinMaxMeanInterfacePosition()
void initializeGControlPoint()
this function is used to initialize the control point.
MFloat firstOrderEikonalSolver(MInt cellListSize, MInt maxIterations, MInt set)
void computeLevelSetRHS()
void initializeIntegrationScheme()
void computeZeroLevelSetArcLength()
MBool inCell(MInt cellId, MFloat *point)
void allocateLevelSetMemory()
void computeExtensionVelocityGEQUPVMarksteinOpt(MFloat *FfluidDensity, MInt set)
void determineMinMaxMeanRegionInterfacePosition(MFloat xRegN, MFloat xRegP, MFloat yRegN, MFloat yRegP, MInt set)
MInt hyperbolicExtensionOpt(MFloat *q, MInt *cellList, MInt cellListSize, MFloat convergenceCriterion, MInt set)
void setGCellBndryProperty()
void levelSetReinitialization(MInt mode=1)
void updateLowerGridLevels(MInt mode=-1)
void levelSetRestriction()
void levelSetGapCorrect()
void initializeCollectedLevelSet(MInt mode)
void resetOutsideCells(MInt mode=-1)
void exchangeLs(MFloat *, MInt, MInt)
MBool levelSetReinitializationTrigger()
void applyLevelSetBoundaryConditions()
void computeNormalVectorsPeriodic()
void levelSetHighOrderConstrainedReinitialization(MInt methodId, MInt startSet, MInt endSet, MInt gapMode)
void computeCurvaturePeriodic()
void exchangeBuffersGlobal(T *sendBuffer, T *receiveBuffer, MInt *, MInt *, MInt *, MInt *, MInt, MInt offset=1)
MInt determineLevelSetSignFromSTL(MFloat *target, MInt set)
this function checks if the "target" coordinates is inside(return 1) or outside (return -1) STL and r...
void reBuildCollectedLevelSet(MInt mode)
void levelSetGapRecorrect()
MFloat interpolateLevelSet(MInt *interpolationCells, MFloat *point, MInt referenceSet)
void readLevelSetProperties()
MFloat computeDistanceFromSTL(MFloat *target, MInt *closestElement, MFloat *closestPoint, MInt set, MFloat sphereRadiusFactor=F5)
MFloat fifthOrderEikonalSolver(MInt cellListSize, MInt maxIterations, MInt *crCells, MInt noCRCells, MFloat *factors, MInt crMode, MInt set)
void setUpLevelSetInterpolationStencil(MInt cellId, MInt *interpolationCells, MInt position)
void updateBndryCellList()
void buildCollectedLevelSet(MInt mode=1)
void allocateRotatingLs()
void resetOldOutsideCells()
LsCartesianSolver(MInt, const MBool *, GridProxy &gridProxy_, Geom &geometry_, const MPI_Comm comm)
MInt getContainingCell(MFloat *point)
void maintainOuterBandLayers(MInt order, MInt startSet, MInt endSet)
void setChildRegions(MInt cellId, MInt region)
void reinitBand(MInt startSet, MInt endSet)
void getContainingCellFromNeighbor(MInt body, MInt cellId, MFloat *xCoord, MFloat *xOld)
void constructGFieldFromSTL(MInt ConstructFlag)
Used for initializing G field into the domain. ConstructFlag == 0: only reinitialization part will be...
void setBandNewArrivals(MInt computingSet=-1)
void determineG0Cells(MInt computingSet=-1)
void determineBandCells(MInt mode=-1)
void levelSetConstrainedReinitialization(MInt methodId, MInt startSet, MInt endSet, MInt gapMode)
MFloat interpolateOldLevelSet(MInt *interpolationCells, MFloat *point, MInt referenceSet)
void computeNormalVectorsAtFront()
void computeNormalVectors(MInt mode=-1)
void initSolver() override
void computeGCellTimeStep()
MBool localGapCellsExist()
This class is a ScratchSpace.
Parent class of all solvers This class is the base for all solvers. I.e. all solver class (e....
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
@ MAIA_SEMI_LAGRANGE_LEVELSET_LB
@ MAIA_RUNGE_KUTTA_MB_SEMI_LAGRANGE_LEVELSET
@ MAIA_SEMI_LAGRANGE_LEVELSET
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW4(const Real x)
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)
MBool approx(const T &, const U &, const T)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
void printAllocatedMemory(const MLong oldAllocatedBytes, const MString &solverName, const MPI_Comm comm)
Prints currently allocated memory.
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
std::basic_string< char > MString
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status, const MString &name, const MString &varname)
same as MPI_Recv
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Isend
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Irecv
int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Issend
int MPI_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Send
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.
T cos(const T a, const T b, const T x)
Cosine slope filter.
MFloat crankAngle(const MFloat time, const MFloat Strouhal, const MFloat offset, const MInt mode)
help-function for engine calculations which returns the crank-angle for a given time,...
Namespace for auxiliary functions/classes.
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)