31 _gridTraversalEventGenerator(0) {
45 logDebug(
"Spacetree(...)",
"create spacetree with " << offset <<
"x" << width <<
" and periodic BCs=" <<
_periodicBC);
53 bool traversalInverted
63 _gridTraversalEventGenerator(newId) {
77 logInfo(
"Spacetree(...)",
"created spacetree " <<
_id <<
" with master tree " << masterId);
83 GridVertex vertex,
bool splittingIsConsideredLocal,
bool joiningIsConsideredLocal
86 and _gridTraversalEventGenerator.isVertexAdjacentToLocalSpacetree(
92 splittingIsConsideredLocal,
93 joiningIsConsideredLocal
116 GridVertex vertices[
TwoPowerD],
bool splittingIsConsideredLocal,
bool joiningIsConsideredLocal
118 return _gridTraversalEventGenerator.isSpacetreeNodeLocal(
119 vertices, _splitTriggered, _splitting, _joinTriggered, _joining, splittingIsConsideredLocal, joiningIsConsideredLocal
127 assertion2(_root.getAccessNumber(d) > -2 * Dimensions, d, _root.toString());
128 assertion2(_root.getAccessNumber(d) < 2 * Dimensions, d, _root.toString());
131 if (calledFromSpacetreeSet) {
132 assertion(_joinTriggered.empty() or _splitTriggered.empty());
133 assertion(_joinTriggered.empty() or _splitting.empty());
134 assertion(_joining.empty() or _splitTriggered.empty());
135 assertion(_joining.empty() or _splitting.empty());
137 "traverse(TraversalObserver)",
138 _splitTriggered.size() <<
" tree split triggered and " << _splitting.size() <<
" splitting trees on tree " << _id
142 clear(_statistics, _id == 0);
145 _gridControlEvents.clear();
149 const int MagicUpperLimitToWhichIDumpEvents = 4;
151 if (_gridControlEvents.empty()) {
152 logInfo(
"traverse(...)",
"got no grid refinement events");
155 if (not _gridControlEvents.empty() and _gridControlEvents.size() <= MagicUpperLimitToWhichIDumpEvents) {
156 std::ostringstream msg;
157 for (
auto& p : _gridControlEvents)
159 logInfo(
"traverse(...)",
"got " << _gridControlEvents.size() <<
" grid control events: " << msg.str());
160 }
else if (not _gridControlEvents.empty()) {
161 logInfo(
"traverse(...)",
"got " << _gridControlEvents.size() <<
" grid control events");
164 if (not _gridControlEvents.empty()) {
171 _splittedCells.clear();
177 adjacentRanks(
TwoPowerD - 1 - kScalar) = 0;
180 _root.getX() + tarch::la::convertScalar<double>(k),
186 logDebug(
"traverse(TraversalObserver)",
"create " << vertices[kScalar].
toString() <<
" for tree " << _id);
189 for (
int d = 0; d < Dimensions; d++) {
190 if (_periodicBC[d]) {
192 if (vertex(d) == 0) {
199 "traverse(TraversalObserver)",
"set periodic boundary conditions: " << vertices[vertexScalar].
toString()
207 descend(_root, vertices, observer);
211 _root.setInverted(not _root.getInverted());
213 if (calledFromSpacetreeSet) {
215 for (
auto& rank : _splitting) {
216 _childrenIds.insert(rank);
217 _hasSplit.insert(rank);
220 for (
auto& p : _splitTriggered) {
221 if (p.second.numberOfFineGridCells > 0) {
223 "traverse(TraversalObserver)",
224 "have not been able to assign enough cells from "
225 << _id <<
" to new tree " << p.first <<
" (should have deployed " << p.second <<
" more cells)"
228 _splitting.insert(p.first);
230 _splitTriggered.clear();
233 _joining.insert(_joinTriggered.begin(), _joinTriggered.end());
234 _joinTriggered.clear();
236 switch (_spacetreeState) {
255 "traverse(TraversalObserver)",
"switched tree " << _id <<
" into " <<
peano4::grid::toString(_spacetreeState)
270 fineGridStates[arrayIndex] = coarseGrid;
285 firstCell.
setH(axis, coarseGrid.
getH(axis) / 3.0);
286 fineGridStatesPosition(axis) = 0;
287 firstCell.
setX(axis, coarseGrid.
getX(axis));
288 refineState(firstCell, fineGridStates, fineGridStatesPosition, axis - 1);
293 secondCell.
setH(axis, coarseGrid.
getH(axis) / 3.0);
294 fineGridStatesPosition(axis) = 1;
295 secondCell.
setX(axis, coarseGrid.
getX(axis) + coarseGrid.
getH(axis) / 3.0);
296 refineState(secondCell, fineGridStates, fineGridStatesPosition, axis - 1);
303 thirdCell.
setH(axis, coarseGrid.
getH(axis) / 3.0);
304 fineGridStatesPosition(axis) = 2;
305 thirdCell.
setX(axis, coarseGrid.
getX(axis) + 2.0 * coarseGrid.
getH(axis) / 3.0);
306 refineState(thirdCell, fineGridStates, fineGridStatesPosition, axis - 1);
309 if (axis == Dimensions - 1) {
313 fineGridStates[i].getAccessNumber(d) > -2 * Dimensions,
322 fineGridStates[i].getAccessNumber(d) < 2 * Dimensions,
337 for (
int d = 0; d < Dimensions; d++) {
338 result[d] = in[d] ? 1 : 0;
346 for (
auto p : _joining) {
350 "receiveAndMergeGridVertexAtVerticalBoundary(GridVertex)",
352 << vertex.
toString() <<
" with its replica from worker as worker is joining. Incoming stack no=" << stackNo
355 assertion3(not _vertexStack.getForPop(_id, stackNo)->empty(), _id, stackNo, vertex.
toString());
356 GridVertex copyFromFormerWorker = _vertexStack.getForPop(_id, stackNo)->pop();
359 vertex.getX(), copyFromFormerWorker.getX(), vertex.
toString(), copyFromFormerWorker.
toString(), _id
364 "receiveAndMergeGridVertexAtVerticalBoundary(GridVertex)",
"updated adjacency lists: " << vertex.
toString()
369 logTraceOut(
"receiveAndMergeGridVertexAtVerticalBoundary(GridVertex)");
381 receiveAndMergeGridVertexAtHorizontalBoundary(vertex);
382 receiveAndMergeGridVertexAtVerticalBoundary(vertex);
384 vertex.setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep(
385 vertex.getIsAntecessorOfRefinedVertexInCurrentTreeSweep()
387 vertex.setHasBeenParentOfSubtreeVertexInPreviousTreeSweep(vertex.getIsParentOfSubtreeVertexInCurrentTreeSweep());
389 vertex.setIsAntecessorOfRefinedVertexInCurrentTreeSweep(
false);
390 vertex.setIsParentOfSubtreeVertexInCurrentTreeSweep(
false);
391 vertex.setNumberOfAdjacentRefinedLocalCells(0);
394 if (isVertexAdjacentToLocalSpacetree(vertex,
true,
true)) {
395 logDebug(
"updateVertexAfterLoad()",
"switch vertex to refining on tree " << _id <<
": " << vertex.toString());
397 _statistics.setStationarySweeps(0);
406 if (vertex.getHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep()) {
408 "updateVertexAfterLoad(...)",
410 << vertex.toString() <<
" may not be erased on tree " << _id
411 <<
" as it is father of further refined vertices. Unroll flag"
414 _statistics.setCoarseningHasBeenVetoed(
true);
415 _statistics.setStationarySweeps(0);
418 "updateVertexAfterLoad(...)",
"erase vertex " << vertex.toString() <<
" outside of domain on tree " << _id
421 _statistics.setStationarySweeps(0);
427 not isVertexAdjacentToLocalSpacetree(vertex,
true,
true)
429 not vertex.getHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep()
434 "updateVertexAfterLoad(GridVertex&)",
"would like to erase " << vertex.toString() <<
" in spacetree " << _id
443 "updateVertexAfterLoad(GridVertex&)",
445 << vertex.toString() <<
" from tree " << _id <<
" to master " << _masterId <<
" through stack " << stackNo
447 _vertexStack.getForPush(_id, stackNo)->push(vertex);
458 for (
int d = 0; d < Dimensions; d++) {
459 assertion2(coarseVertexPosition(d) >= 0, coarseVertexPosition, fineVertexPosition);
460 assertion2(coarseVertexPosition(d) <= 1, coarseVertexPosition, fineVertexPosition);
462 assertion2(fineVertexPosition(d) >= 0, coarseVertexPosition, fineVertexPosition);
463 assertion2(fineVertexPosition(d) <= 3, coarseVertexPosition, fineVertexPosition);
466 &= ((coarseVertexPosition(d) == 1 and fineVertexPosition(d) > 0) or (coarseVertexPosition(d) == 0 and fineVertexPosition(d) < 3));
493 "updateVertexBeforeStore(...)",
494 "have to post-refine vertex "
495 << vertex.
toString() <<
" as it surrounded by 2^d refined cells on tree " << _id <<
" x "
516 restrictIsAntecessorOfRefinedVertex =
true;
519 restrictIsAntecessorOfRefinedVertex =
true;
521 restrictIsAntecessorOfRefinedVertex =
true;
526 sendGridVertex(vertex);
528 if (restrictIsAntecessorOfRefinedVertex) {
529 dfor2(k)
if (restrictToCoarseGrid(k, fineVertexPositionWithinPatch)) {
531 "updateVertexBeforeStore(...)",
532 "set antecessor flag (veto coarsenign) on vertex " << coarseGridVertices[kScalar].
toString(
533 ) <<
" due to vertex " << vertex.
toString()
535 coarseGridVertices[kScalar].setIsAntecessorOfRefinedVertexInCurrentTreeSweep(
true);
536 coarseGridVertices[kScalar].setIsParentOfSubtreeVertexInCurrentTreeSweep(
537 coarseGridVertices[kScalar].getIsParentOfSubtreeVertexInCurrentTreeSweep()
544 if (shouldEraseAdjacencyInformation(vertex, coarseGridVertices, fineVertexPositionWithinPatch)) {
562 for (
int d = 0; d < Dimensions; d++) {
563 if (fineVertexPositionWithinPatch(d) != 0 and fineVertexPositionWithinPatch(d) != 3) {
570 bool result = shouldEraseAdjacencyInformation(vertex, coarseGridVertices, positionA)
571 and shouldEraseAdjacencyInformation(vertex, coarseGridVertices, positionB);
578 fineVertexPositionWithinPatch = fineVertexPositionWithinPatch / 3;
592 dfor2(k) std::bitset<Dimensions> vertexToInherit;
593 std::bitset<Dimensions> indexToInherit;
594 for (
int d = 0; d < Dimensions; d++) {
595 if (vertexPositionWithin3x3Patch(d) <= 1) {
596 vertexToInherit.set(d,
false);
597 indexToInherit.set(d, k(d) > 0 or vertexPositionWithin3x3Patch(d) > 0);
599 vertexToInherit.set(d,
true);
600 indexToInherit.set(d, not(k(d) < 1 or vertexPositionWithin3x3Patch(d) < 3));
604 "createNewPersistentVertex(...)",
606 << indexToInherit.to_ulong() <<
"th index from coarse vertex " << vertexToInherit <<
" into local index "
609 adjacentRanks(kScalar) = coarseGridVertices[vertexToInherit.to_ulong()].getAdjacentRanks(indexToInherit.to_ulong());
612 return adjacentRanks;
626 const std::bitset<Dimensions> vertexIndex(coordinates ^ std::bitset<Dimensions>(i));
628 vertexPositionWithinPatch = cellPositionWithin3x3Patch + convertToIntegerVector(vertexIndex);
631 x = fineGridStatesState.
getX()
633 tarch::la::convertScalar<double>(convertToIntegerVector(vertexIndex)), fineGridStatesState.
getH()
636 VertexType type = _gridTraversalEventGenerator.getVertexType(coarseGridVertices, vertexPositionWithinPatch);
644 "reset stack flag for local vertex " << vertexPositionWithinPatch <<
" from new/hanging to persistent"
655 getAdjacentRanksForNewVertex(coarseGridVertices, vertexPositionWithinPatch),
664 getAdjacentRanksForNewVertex(coarseGridVertices, vertexPositionWithinPatch),
669 logDebug(
"readVertices(...)",
"read vertex from stack " << stackNumber);
672 assertion3(not _vertexStack.getForPop(_id, stackNumber)->empty(), _id, stackNumber, vertexIndex);
675 updateVertexAfterLoad(
678 vertexPositionWithinPatch,
682 assertion3(not _vertexStack.getForPop(_id, stackNumber)->empty(), _id, stackNumber, vertexIndex);
687 logDebug(
"readVertices(...)",
"read vertex from stack " << stackNumber);
690 assertion2(not _vertexStack.getForPop(_id, stackNumber)->empty(), stackNumber, _id);
693 updateVertexAfterLoad(
696 vertexPositionWithinPatch,
701 assertion2(not _vertexStack.getForPop(_id, stackNumber)->empty(), stackNumber, _id);
709 <<
peano4::grid::toString(type) <<
" vertex " << vertexIndex <<
" at " << vertexPositionWithinPatch <<
": "
747 const std::bitset<Dimensions> vertexIndex(coordinates ^ std::bitset<Dimensions>(i));
749 vertexPositionWithinPatch = cellPositionWithin3x3Patch + convertToIntegerVector(vertexIndex);
758 VertexType type = _gridTraversalEventGenerator.getVertexType(coarseGridVertices, vertexPositionWithinPatch);
763 "storeVertices(...)",
764 "reset stack flag for local vertex " << vertexPositionWithinPatch <<
" from new/hanging to persistent"
772 "storeVertices(...)",
777 updateVertexBeforeStore(
802 const bool receiverCriteria = (_joining.count(rank) == 0) and (_splitting.count(rank) == 0);
803 const bool senderCriteria = (_joining.count(rank) == 0) and (_splitTriggered.count(rank) == 0)
806 const bool mandatoryCriteria = rank != _id and rank !=
InvalidRank and rank != RankOfPeriodicBoundaryCondition;
808 return calledByReceivingProcess ? (mandatoryCriteria and receiverCriteria) : (mandatoryCriteria and senderCriteria);
817 fineGridVertices, faceNumber, calledByReceivingProcess
820 bool isAdjacentToLocalRank =
false;
821 bool holdsPeriodicBoundaryConditionFlag =
false;
823 isAdjacentToLocalRank |= adjacentRanksOfFace(i) == _id;
824 holdsPeriodicBoundaryConditionFlag |= adjacentRanksOfFace(i) == RankOfPeriodicBoundaryCondition;
827 holdsPeriodicBoundaryConditionFlag &= isAdjacentToLocalRank;
830 "isFaceAlongPeriodicBoundaryCondition(...)", holdsPeriodicBoundaryConditionFlag, isAdjacentToLocalRank
832 return holdsPeriodicBoundaryConditionFlag;
841 fineGridVertices, faceNumber, calledByReceivingProcess
844 logDebug(
"getNeighbourTrees(...)",
"face adjacency list=" << adjacentRanksOfFace);
850 bool isAdjacentToLocalRank =
false;
853 const bool mandatoryCriteria = adjacentRanksOfFace(i) != _id and adjacentRanksOfFace(i) !=
InvalidRank
854 and adjacentRanksOfFace(i) != RankOfPeriodicBoundaryCondition
857 if (calledByReceivingProcess) {
858 isAdjacentToLocalRank |= adjacentRanksOfFace(i) == _id or _splitTriggered.count(adjacentRanksOfFace(i)) == 1
859 or _splitting.count(adjacentRanksOfFace(i)) == 1;
861 const bool receiverCriteria = _splitTriggered.count(adjacentRanksOfFace(i)) == 0
862 and _splitting.count(adjacentRanksOfFace(i)) == 0
865 if (mandatoryCriteria and receiverCriteria) {
866 neighbour = adjacentRanksOfFace(i);
869 isAdjacentToLocalRank |= adjacentRanksOfFace(i) == _id or _splitTriggered.count(adjacentRanksOfFace(i)) == 1;
871 const bool senderCriteria = _splitTriggered.count(adjacentRanksOfFace(i)) == 0;
873 if (mandatoryCriteria and senderCriteria) {
874 neighbour = adjacentRanksOfFace(i);
879 if (not isAdjacentToLocalRank) {
889 std::set<int> neighbourIds;
891 const bool isLocalVertex = calledByReceivingProcess ? isVertexAdjacentToLocalSpacetree(vertex,
true,
false)
892 : isVertexAdjacentToLocalSpacetree(vertex,
false,
true);
898 if (doesRankIndexIdentifyHorizontalDataExchange(adjacentRanks(i), calledByReceivingProcess)) {
899 neighbourIds.insert(adjacentRanks(i));
917 "mergeGridVertexAdjacencyListsAtHorizontalDomainBoundary(...)",
919 << i <<
"th entry of adjacency data of vertex " << vertex.
toString() <<
" with neighbouring vertex "
920 << inVertex.
toString() <<
" on tree " << _id
929 [[maybe_unused]]
GridVertex& vertex, [[maybe_unused]]
const GridVertex& inVertex, [[maybe_unused]]
int neighbour
943 (_periodicBC.count()>1 or
tarch::la::countEqualEntries(vertex.getX(), inVertex.getX())==Dimensions-
static_cast<int>(_periodicBC.count()))
945 inVertex.toString(), vertex.toString(), _id, neighbour,
948 assertionEquals4(vertex.getLevel(), inVertex.getLevel(), inVertex.toString(), vertex.toString(), _id, neighbour);
967 vertex.setIsAntecessorOfRefinedVertexInCurrentTreeSweep(
968 vertex.getIsAntecessorOfRefinedVertexInCurrentTreeSweep()
969 or inVertex.getIsAntecessorOfRefinedVertexInCurrentTreeSweep()
978 const bool OnlyNeighbourHasTriggeredRefinement
981 const bool OnlyLocalHasTriggeredRefinement =
989 if (OnlyNeighbourHasTriggeredRefinement || OnlyLocalHasTriggeredRefinement) {
992 "mergeGridVertexRefinementStateAtHorizontalDomainBoundary( GridVertex )",
993 "set state to " << vertex.toString() <<
" on tree " << _id <<
" due to merge with neighbour"
995 }
else if (OnlyNeighbourHasTriggeredErase || OnlyLocalHasTriggeredErase) {
998 "mergeGridVertexRefinementStateAtHorizontalDomainBoundary( GridVertex )",
999 "set state to " << vertex.toString() <<
" on tree " << _id <<
" due to merge with neighbour"
1002 assertion4(vertex.getState() == inVertex.getState(), inVertex.toString(), vertex.toString(), _id, neighbour);
1016 std::set<int> neighbourIds = getNeighbourTrees(vertex,
true);
1017 for (
auto neighbour : neighbourIds) {
1021 assertion4(_vertexStack.holdsStack(_id, inStack), _id, inStack, neighbour, vertex.
toString());
1022 assertion4(not _vertexStack.getForPop(_id, inStack)->empty(), _id, inStack, neighbour, vertex.
toString());
1023 GridVertex inVertex = _vertexStack.getForPop(_id, inStack)->pop();
1025 mergeGridVertexRefinementStateAtHorizontalDomainBoundary(vertex, inVertex, neighbour);
1026 mergeGridVertexAdjacencyListsAtHorizontalDomainBoundary(vertex, inVertex, neighbour);
1029 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>
1032 : std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>();
1033 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier> periodicBCInputStacks;
1034 for (
auto& p : periodicBCOutputStacks) {
1040 for (
auto stackNo : periodicBCInputStacks) {
1042 assertion3(not _vertexStack.getForPop(_id, stackNo.first)->empty(), stackNo.first, stackNo.second, _id);
1043 GridVertex inVertex = _vertexStack.getForPop(_id, stackNo.first)->pop();
1045 "receiveAndMergeGridVertexAtHorizontalBoundary(...)",
1046 "read periodic BC data from stack " << stackNo.first <<
": " << inVertex.
toString()
1049 "receiveAndMergeGridVertexAtHorizontalBoundary(...)",
"normals of involved symmetry axes: " << stackNo.second
1051 mergeGridVertexRefinementStateAtHorizontalDomainBoundary(vertex, inVertex, _id);
1063 logTraceOut(
"receiveAndMergeGridVertexAtHorizontalBoundary(...)");
1071 std::set<int> outRanks = getNeighbourTrees(vertex,
false);
1073 for (
auto p : outRanks) {
1087 _vertexStack.getForPush(_id, stackNo)->push(vertexCopy);
1090 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>
1093 : std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>();
1095 for (
auto stackNo : periodicBCStacks) {
1096 _vertexStack.getForPush(_id, stackNo.first)->push(vertex);
1098 "sendGridVertex(GridVertex)",
1100 << vertex.
toString() <<
" on tree " << _id <<
" goes to stack " << stackNo.first <<
" to realise periodic BC"
1108 dfor2(k) vertices[kScalar].setNumberOfAdjacentRefinedLocalCells(
1109 vertices[kScalar].getNumberOfAdjacentRefinedLocalCells() + 1
1112 "incrementNumberOfAdjacentRefinedLocalCells(...)",
"incremented counter of " << vertices[kScalar].
toString()
1118 dfor2(k) fineGridVertices[kScalar].setAdjacentRanks(
TwoPowerD - kScalar - 1, newId);
1125 if (not _gridControlEvents.empty()) {
1134 bool mayChangeGrid =
true;
1151 bool refine =
false;
1153 if (mayChangeGrid) {
1154 for (
auto p : _gridControlEvents) {
1178 "evaluateGridControlEvents(...)",
1179 _gridControlEvents.size(
1180 ) <<
" event(s) in state "
1181 <<
state.
toString() <<
" trigger change=" << mayChangeGrid <<
", refine=" << refine <<
", erase=" << erase
1185 bool haveTriggeredRefinementForAtLeastOneVertex =
false;
1187 )
if (isVertexAdjacentToLocalSpacetree(fineGridVertices[iScalar],
true,
true) and fineGridVertices[iScalar].getState() ==
GridVertex::State::Unrefined) {
1189 haveTriggeredRefinementForAtLeastOneVertex =
true;
1193 if (not haveTriggeredRefinementForAtLeastOneVertex) {
1194 logDebug(
"evaluate...",
"wanted to refine cell " <<
state.
toString() <<
" but no vertex is refinable");
1198 if (isVertexAdjacentToLocalSpacetree(fineGridVertices[i],
true,
true) and fineGridVertices[i].getState() ==
GridVertex::State::Refined) {
1226 refineState(
state, fineGridStates);
1236 zfor3(k, loopDirection)
1243 mergeCellFromWorkerWithMasterThroughoutJoin(vertices, fineGridVertices);
1251 markVerticesAroundForkedCell(vertices, fineGridVertices);
1253 markVerticesAroundForkedCell(vertices, fineGridVertices);
1261 splitCellTopDown(vertices, fineGridVertices);
1263 GridTraversalEvent enterCellTraversalEvent = _gridTraversalEventGenerator.createEnterCellTraversalEvent(
1277 _gridTraversalEventGenerator.createPrunedEnterCellTraversalEvent(_spacetreeState, enterCellTraversalEvent)
1281 receiveAndMergeUserData(
1287 _gridTraversalEventGenerator.createPrunedEnterCellTraversalEvent(_spacetreeState, enterCellTraversalEvent)
1297 _statistics.setNumberOfLocalRefinedCells(_statistics.getNumberOfLocalRefinedCells() + 1);
1298 incrementNumberOfAdjacentRefinedLocalCells(fineGridVertices);
1300 _statistics.setNumberOfRemoteRefinedCells(_statistics.getNumberOfRemoteRefinedCells() + 1);
1305 _statistics.setNumberOfLocalUnrefinedCells(_statistics.getNumberOfLocalUnrefinedCells() + 1);
1307 _statistics.setNumberOfRemoteUnrefinedCells(_statistics.getNumberOfRemoteUnrefinedCells() + 1);
1314 GridTraversalEvent leaveCellTraversalEvent = _gridTraversalEventGenerator.createLeaveCellTraversalEvent(
1328 _gridTraversalEventGenerator.createPrunedLeaveCellTraversalEvent(_spacetreeState, leaveCellTraversalEvent)
1336 _gridTraversalEventGenerator.createPrunedLeaveCellTraversalEvent(_spacetreeState, leaveCellTraversalEvent)
1339 splitOrJoinCellBottomUp(vertices, fineGridVertices);
1368 int inVertexPositionWithinCell = enterCellTraversalEvent.
getVertexDataTo(i);
1374 if (enterCellTraversalEvent.
getIsVertexLocal(inVertexPositionWithinCell)) {
1375 std::set<int> neighbours = getNeighbourTrees(fineGridVertices[inVertexPositionWithinCell],
true);
1376 for (
auto p : neighbours) {
1378 "receiveAndMergeUserData(...)",
1379 "receive neighbour data from neighbour "
1380 << p <<
" for vertex " << fineGridVertices[inVertexPositionWithinCell].
toString()
1384 inVertexPositionWithinCell,
1387 enterCellTraversalEvent
1391 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>
1392 periodicBCOutputStacks = _id == 0
1394 fineGridVertices[inVertexPositionWithinCell].getAdjacentRanks()
1396 : std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>();
1398 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier> periodicBCInputStacks;
1399 for (
auto& p : periodicBCOutputStacks) {
1400 periodicBCInputStacks.insert(
1405 for (
auto p : periodicBCInputStacks) {
1407 inVertexPositionWithinCell,
1410 enterCellTraversalEvent
1417 for (
int i = 0; i < 2 * Dimensions; i++) {
1419 int inFacePositionWithinCell = enterCellTraversalEvent.
getFaceDataTo(i);
1424 if (enterCellTraversalEvent.
getIsFaceLocal(inFacePositionWithinCell)) {
1425 int neighbour = getNeighbourTrees(fineGridVertices, inFacePositionWithinCell,
true);
1426 if (neighbour >= 0) {
1429 inFacePositionWithinCell,
1432 enterCellTraversalEvent
1436 if (isFaceAlongPeriodicBoundaryCondition(fineGridVertices, inFacePositionWithinCell,
true)) {
1443 "receiveAndMergeUserData(...)",
1444 "will merge face from periodic BC stack #"
1445 << fromStack <<
" with local face. Cell marker=" << marker.toString()
1446 <<
". in-face=" << inFacePositionWithinCell
1450 inFacePositionWithinCell,
1453 enterCellTraversalEvent
1474 leaveCellTraversalEvent.toString(),
1479 int outVertexStack = leaveCellTraversalEvent.getVertexDataTo(i);
1480 int outVertexPositionWithinCell = leaveCellTraversalEvent.getVertexDataFrom(i);
1486 if (leaveCellTraversalEvent.getIsVertexLocal(outVertexPositionWithinCell)) {
1487 std::set<int> neighbours = getNeighbourTrees(fineGridVertices[outVertexPositionWithinCell],
false);
1489 for (
auto p : neighbours) {
1491 "sendUserData(...)",
1492 "send local vertex data of "
1493 << fineGridVertices[outVertexPositionWithinCell].
toString() <<
" from stack " << outVertexStack
1494 <<
" on tree " << _id <<
" to neighbour " << p <<
". Position within cell=" << outVertexPositionWithinCell
1497 observer.sendVertex(
1498 outVertexPositionWithinCell,
1501 leaveCellTraversalEvent
1505 std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>
1507 fineGridVertices[outVertexPositionWithinCell].getAdjacentRanks()
1509 : std::set<peano4::parallel::Node::PeriodicBoundaryStackIdentifier>();
1511 for (
auto stackNo : periodicBCStacks) {
1513 "sendUserData(...)",
1515 << fineGridVertices[outVertexPositionWithinCell].
toString() <<
" on tree " << _id <<
" goes to stack "
1516 << stackNo.first <<
" to realise periodic BC"
1519 observer.sendVertex(
1520 outVertexPositionWithinCell,
1523 leaveCellTraversalEvent
1528 for (
auto p : _splitting) {
1529 if (
tarch::la::contains(fineGridVertices[outVertexPositionWithinCell].getBackupOfAdjacentRanks(), p)) {
1531 "sendUserData(...)",
1532 "stream local vertex data of "
1533 << fineGridVertices[outVertexPositionWithinCell].
toString() <<
" from stack " << outVertexStack
1534 <<
" on tree " << _id <<
" to upcoming worker " << p <<
". Position within cell="
1535 << outVertexPositionWithinCell <<
". event=" << leaveCellTraversalEvent.toString()
1538 observer.sendVertex(
1539 outVertexPositionWithinCell,
1542 leaveCellTraversalEvent
1546 "sendUserData(...)",
1547 "skip vertex data of " << fineGridVertices[outVertexPositionWithinCell].
toString() <<
" on tree " << _id
1554 for (
int i = 0; i < 2 * Dimensions; i++) {
1555 int outFaceStack = leaveCellTraversalEvent.getFaceDataTo(i);
1556 int outFacePositionWithinCell = leaveCellTraversalEvent.getFaceDataFrom(i);
1561 if (leaveCellTraversalEvent.getIsFaceLocal(outFacePositionWithinCell)) {
1562 int neighbour = getNeighbourTrees(fineGridVertices, outFacePositionWithinCell,
false);
1563 if (neighbour >= 0) {
1565 "sendUserData(...)",
1566 "send local face from stack "
1567 << outFaceStack <<
" of tree " << _id <<
" to neighbour " << neighbour
1568 <<
". Position within cell=" << outFacePositionWithinCell
1573 outFacePositionWithinCell,
1576 leaveCellTraversalEvent
1580 if (isFaceAlongPeriodicBoundaryCondition(fineGridVertices, outFacePositionWithinCell,
false)) {
1582 outFacePositionWithinCell
1586 "sendUserData(...)",
1587 "send local face from stack " << outFaceStack <<
" of tree " << _id <<
" to periodic BC stack #" << toStack
1591 outFacePositionWithinCell,
1594 leaveCellTraversalEvent
1599 for (
auto p : _splitting) {
1601 _gridTraversalEventGenerator.getAdjacentRanksOfFace(fineGridVertices, outFacePositionWithinCell,
false), p
1604 "sendUserData(...)",
1605 "stream local face from stack "
1606 << outFaceStack <<
" of tree " << _id <<
" to new worker " << p
1607 <<
". Position within cell=" << outFacePositionWithinCell
1612 outFacePositionWithinCell,
1615 leaveCellTraversalEvent
1622 [[maybe_unused]]
int outCellStack = leaveCellTraversalEvent.getCellData();
1623 for (
auto p : _splitting) {
1624 if (_gridTraversalEventGenerator.getTreeOwningSpacetreeNode(fineGridVertices, _splitTriggered, _splitting, _joinTriggered, _joining) == p) {
1626 "sendUserData(...)",
1627 "stream local cell of tree "
1628 << _id <<
" to new worker " << p <<
". Left bottom vertex=" << fineGridVertices[0].
toString()
1641 bool isOneVertexAdjacentToPeriodicBC =
false;
1642 bool isOneVertexParentOfForkedTree =
false;
1645 fineGridVertices[kScalar].getAdjacentRanks(), RankOfPeriodicBoundaryCondition
1647 isOneVertexParentOfForkedTree |= fineGridVertices[kScalar].getHasBeenParentOfSubtreeVertexInPreviousTreeSweep();
1651 and
isSpacetreeNodeLocal(coarseGridVertices,
false,
false) and areAllVerticesNonHanging(fineGridVertices)
1652 and not isOneVertexAdjacentToPeriodicBC and (not isOneVertexParentOfForkedTree);
1660 [[maybe_unused]]
constexpr int NoSplit = -1;
1663 const bool isSplitCandidate = isCellSplitCandidate(coarseGridVertices, fineGridVertices);
1667 "splitOrJoinCellBottomUp(...)",
1668 "checked cell for bottom-up splits (first target tree=" << _splitTriggered.begin()->first
1669 <<
"). is-refined=" << isRefined <<
", is-split-candidate=" << isSplitCandidate
1670 <<
" / " << fineGridVertices[0].toString()
1673 if (isSplitCandidate and isRefined) {
1674 int reducedMarker = _splittedCells.back();
1676 int topMarker = _splittedCells.back();
1677 _splittedCells.pop_back();
1678 if (topMarker != reducedMarker) {
1679 reducedMarker = NoSplit;
1683 if (reducedMarker >= 0) {
1684 updateVertexRanksWithinCell(fineGridVertices, reducedMarker);
1687 _splittedCells.push_back(reducedMarker);
1688 }
else if (not isSplitCandidate and isRefined) {
1690 _splittedCells.pop_back();
1692 _splittedCells.push_back(NoSplit);
1693 }
else if (isSplitCandidate and not isRefined) {
1694 int targetSpacetreeId = getSplittingTree();
1695 if (targetSpacetreeId >= 0) {
1696 updateVertexRanksWithinCell(fineGridVertices, targetSpacetreeId);
1697 updateSplittingCounter(targetSpacetreeId);
1699 _splittedCells.push_back(targetSpacetreeId);
1700 }
else if (not isSplitCandidate and not isRefined) {
1701 _splittedCells.push_back(NoSplit);
1703 assertionMsg(
false,
"should not be entered as all combination are covered already");
1707 not _splitTriggered.empty()
1711 not _splittedCells.empty()
1713 int targetSpacetreeId = _splittedCells.back();
1714 _splittedCells.pop_back();
1717 "splitOrJoinCellBottomUp(...)",
1718 "checked cell for top-down splits (first split " << _splitTriggered.begin()->first <<
")"
1722 updateVertexRanksWithinCell(fineGridVertices, targetSpacetreeId);
1729 [[maybe_unused]]
constexpr int NoSplit = -1;
1732 const bool isParentSplit = not _splittedCells.empty();
1733 const int targetSpacetreeId = getSplittingTree();
1734 const bool isSplitCandidate = targetSpacetreeId >= 0 and isCellSplitCandidate(coarseGridVertices, fineGridVertices);
1737 if (isParentSplit and isRefined) {
1740 int parentId = _splittedCells.back();
1741 _splittedCells.push_back(parentId);
1742 }
else if (isParentSplit and not isRefined) {
1745 updateSplittingCounter(targetSpacetreeId);
1746 int parentId = _splittedCells.back();
1747 _splittedCells.push_back(parentId);
1748 }
else if (not isParentSplit and isSplitCandidate and isRefined) {
1752 "splitCellTopDown(...)",
1754 << fineGridVertices[0].
toString() <<
" should go with all children to tree " << targetSpacetreeId
1756 _splittedCells.push_back(targetSpacetreeId);
1757 }
else if (not isParentSplit and isSplitCandidate and not isRefined) {
1758 updateSplittingCounter(targetSpacetreeId);
1761 _splittedCells.push_back(targetSpacetreeId);
1763 logDebug(
"splitOrJoinCellBottomUp(...)",
"#splitted-cells=" << _splittedCells.size());
1770 for (
auto worker : _joining) {
1771 if (
isSpacetreeNodeLocal(coarseGridVertices,
false,
false) and _gridTraversalEventGenerator.getTreeOwningSpacetreeNode(fineGridVertices, _splitTriggered, _splitting, _joinTriggered, _joining) == worker) {
1773 "mergeCellFromWorkerWithMasterThroughoutJoin(...)",
1774 "cell from worker " << worker <<
" is merged into master " << _id
1776 updateVertexRanksWithinCell(fineGridVertices, _id);
1779 logDebug(
"mergeCellFromWorkerWithMasterThroughoutJoin(...)",
"- " << coarseGridVertices[i].
toString());
1782 logDebug(
"mergeCellFromWorkerWithMasterThroughoutJoin(...)",
"- " << fineGridVertices[i].
toString());
1789 for (
auto& p : _splitTriggered) {
1790 if (p.first == treeId) {
1791 p.second.numberOfFineGridCells = std::max(p.second.numberOfFineGridCells - 1, 0);
1798 for (
auto& p : _splitTriggered) {
1799 if (p.second.numberOfFineGridCells > 0) {
1814 coarseGridVertices[kScalar].setIsAntecessorOfRefinedVertexInCurrentTreeSweep(
true);
1815 coarseGridVertices[kScalar].setIsParentOfSubtreeVertexInCurrentTreeSweep(
true);
1816 fineGridVertices[kScalar].setIsParentOfSubtreeVertexInCurrentTreeSweep(
true);
1832 _splitTriggered.insert(std::pair<int, SplitInstruction>(newSpacetreeId, instruction));
1834 auto firstMode = _splitTriggered.begin()->second.mode;
1835 for (
auto& p : _splitTriggered) {
1836 if (p.second.mode != firstMode) {
1840 << p.first <<
" is of type " << p.second.mode <<
" while other splits have mode " << firstMode
1841 <<
". Switch all splits to " << firstMode
1843 p.second.mode = firstMode;
1849 std::ostringstream msg;
1851 <<
",statistics=" << _statistics.toString();
1852 if (_joinTriggered.empty()) {
1853 msg <<
",no-join-triggered-with-any-tree";
1855 msg <<
",join-triggered={";
1856 for (
const auto& p : _joinTriggered) {
1857 msg <<
"(" << p <<
")";
1861 if (_joining.empty()) {
1862 msg <<
",not-joining";
1864 msg <<
",joining={";
1865 for (
const auto& p : _joining) {
1866 msg <<
"(" << p <<
")";
1882 if (_splitTriggered.empty()) {
1883 msg <<
",no-split-triggered";
1885 msg <<
",split-triggered={";
1886 for (
const auto& p : _splitTriggered) {
1887 msg <<
"(" << p.first <<
"," << p.second <<
")";
1891 if (_splitting.empty()) {
1892 msg <<
",not-splitting";
1894 msg <<
",splitting={";
1895 for (
const auto& p : _splitting) {
1896 msg <<
"(" << p <<
")";
1900 msg <<
",stacks:" << _vertexStack.toString() <<
")";
1906 and _splitting.empty() and _statistics.getNumberOfLocalUnrefinedCells() > 0
1907 and (_splitTriggered.empty() or _splitTriggered.begin()->second.numberOfFineGridCells < std::numeric_limits<int>::max());
1912 and _splitting.empty() and _joinTriggered.empty();
1917 and _statistics.getStationarySweeps() > NumberOfStationarySweepsToWaitAtLeastTillJoin
1918 and _splitTriggered.empty() and _splitting.empty() and _joinTriggered.empty() and _joining.empty()
1919 and _statistics.getNumberOfLocalRefinedCells() == 0;
1932 logInfo(
"joinWithWorker(int)",
"merge tree " <<
id <<
" into tree " << _id);
1933 assertion2(_joinTriggered.count(
id) == 0,
id, _id);
1934 _joinTriggered.insert(
id);
1940 return not _joinTriggered.empty() or not _joining.empty() or not _splitTriggered.empty() or not _splitting.empty();
#define assertion2(expr, param0, param1)
#define assertion4(expr, param0, param1, param2, param3)
#define assertionVectorNumericalEquals3(lhs, rhs, param0, param1, param2)
#define assertionNumericalEquals5(lhs, rhs, a, b, c, d, e)
#define assertion3(expr, param0, param1, param2)
#define assertion1(expr, param)
#define assertionMsg(expr, message)
#define assertionEquals5(lhs, rhs, larg, rarg, three, four, five)
#define assertionEquals4(lhs, rhs, larg, rarg, three, four)
#define assertion6(expr, param0, param1, param2, param3, param4, param5)
#define DimensionsTimesTwo
#define logDebug(methodName, logMacroMessageStream)
#define logTraceOutWith1Argument(methodName, argument0)
#define logTraceOut(methodName)
#define logWarning(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
#define logTraceOutWith3Arguments(methodName, argument0, argument1, argument2)
#define logTraceInWith3Arguments(methodName, argument0, argument1, argument2)
#define logTraceOutWith2Arguments(methodName, argument0, argument1)
#define logTraceIn(methodName)
#define logTraceInWith1Argument(methodName, argument0)
#define logTraceInWith2Arguments(methodName, argument0, argument1)
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
#define dfor2(counter)
Shortcut For dfor(counter,2)
#define dfor3(counter)
Shortcut For dfor(counter,3)
#define zfor3(counter, direction)
#define enddforx
I prefer to use this macro for dforx instead of a closing bracket as many syntax parser fail otherwis...
std::bitset< Dimensions > periodicBC
static int getVertexWriteStackNumber(const AutomatonState &state, const std::bitset< Dimensions > &vertex)
static void invertEvenFlag(AutomatonState &cell, int axis)
static bool isInOutStack(int number)
static int getVertexReadStackNumber(const AutomatonState &state, const std::bitset< Dimensions > &vertex)
static peano4::utils::LoopDirection getLoopDirection(const AutomatonState &state)
Holds a set bit for each dimension along which the traversal is positive.
static void setEntryFace(AutomatonState &cell, int axis)
static bool isTraversePositiveAlongAxis(const AutomatonState &state, int axis)
static std::bitset< Dimensions > getFirstVertexIndex(const AutomatonState &cell)
Looks into a cell of the spacetree and gives the index of the first local vertex.
static void setExitFace(AutomatonState &cell, int axis)
static bool restrictToCoarseGrid(const tarch::la::Vector< Dimensions, int > &coarseVertexPosition, const tarch::la::Vector< Dimensions, int > &fineVertexPosition)
Determines whether to restrict a vertex to the coarser level or not.
void split(int treeId, const SplitInstruction &instruction)
Add a split instruction.
static tarch::logging::Log _log
void mergeGridVertexAdjacencyListsAtHorizontalDomainBoundary(GridVertex &vertex, const GridVertex &inVertex, int neighbour)
void storeVertices(const AutomatonState &fineGridState, GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD], const tarch::la::Vector< Dimensions, int > &cellPositionWithin3x3Patch, TraversalObserver &observer)
GridStatistics getGridStatistics() const
void sendUserData(const AutomatonState &state, TraversalObserver &observer, const GridTraversalEvent &enterCellTraversalEvent, GridVertex fineGridVertices[TwoPowerD])
Send user data.
bool isInvolvedInJoinOrFork() const
void updateVertexAfterLoad(GridVertex &vertex, GridVertex fineGridVertices[TwoPowerD], const tarch::la::Vector< Dimensions, int > &fineVertexPositionWithinPatch, TraversalObserver &observer)
This operation has multiple purposes.
static GridVertexStackMap _vertexStack
static void refineState(const AutomatonState &coarseGrid, AutomatonState fineGrid[ThreePowerD], tarch::la::Vector< Dimensions, int > fineGridPosition=tarch::la::Vector< Dimensions, int >(0), int axis=Dimensions-1)
Takes a state (describing a node in the tree) and returns the states on the next finer level along t...
void markVerticesAroundForkedCell(GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD]) const
setIsAntecessorOfRefinedVertexInCurrentTreeSweep()
bool areAllVerticesRefined(GridVertex vertices[TwoPowerD]) const
void loadVertices(const AutomatonState &fineGridState, GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD], const tarch::la::Vector< Dimensions, int > &cellPositionWithin3x3Patch, TraversalObserver &observer)
Load the vertices of one cell.
bool mayJoinWithMaster() const
Only ranks that have no kids are allowed to join.
std::string toString() const
void joinWithWorker(int id)
GridStatistics _statistics
static void incrementNumberOfAdjacentRefinedLocalCells(GridVertex vertices[TwoPowerD])
Every local refined cell should call this routine.
void receiveAndMergeUserData(const AutomatonState &state, TraversalObserver &observer, const GridTraversalEvent &enterCellTraversalEvent, GridVertex fineGridVertices[TwoPowerD])
int getSplittingTree() const
bool areAllVerticesUnrefined(GridVertex vertices[TwoPowerD]) const
bool isFaceAlongPeriodicBoundaryCondition(GridVertex vertex[TwoPowerD], int faceNumber, bool calledByReceivingProcess) const
void descend(const AutomatonState &state, GridVertex vertices[TwoPowerD], TraversalObserver &observer)
bool isSpacetreeNodeLocal(GridVertex vertices[TwoPowerD], bool splittingIsConsideredLocal, bool joiningIsConsideredLocal) const
Wrapper around GridTraversalEventGenerator::isSpacetreeNodeLocal()
const std::bitset< Dimensions > _periodicBC
Indicate per axis whether we have periodic boundary conditions.
Spacetree(int newId, int masterId, const tarch::la::Vector< Dimensions, double > &offset, const tarch::la::Vector< Dimensions, double > &width, bool traversalInverted)
Only used by SpacetreeSet to create children of the original tree.
static tarch::la::Vector< Dimensions, int > convertToIntegerVector(const std::bitset< Dimensions > &in)
Little helper.
std::set< int > getNeighbourTrees(const GridVertex &vertex, bool calledByReceivingProcess) const
Get the ids of the surrounding cells of a vertex.
void splitOrJoinCellBottomUp(GridVertex vertex[TwoPowerD], GridVertex fineGridVertices[TwoPowerD])
Realise the splits and joins.
void joinWithMaster()
Join with master.
static constexpr int NumberOfStationarySweepsToWaitAtLeastTillJoin
void sendGridVertex(const GridVertex &vertex)
This one is to be invoked if and only if a vertex goes to the in/out stacks.
AutomatonState _root
The root of a spacetree corresponds to the initial state of the tree traversal automaton.
void evaluateGridControlEvents(const AutomatonState &fineGridState, GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD])
Should only be called for inner cells.
bool isVertexAdjacentToLocalSpacetree(GridVertex vertex, bool splittingIsConsideredLocal, bool joiningIsConsideredLocal) const
Returns if a vertex is local to adjacent tree.
static void updateVertexRanksWithinCell(GridVertex fineGridVertices[TwoPowerD], int newId)
If a cell gets a new id, we have to update its vertices.
void mergeGridVertexRefinementStateAtHorizontalDomainBoundary(GridVertex &vertex, const GridVertex &inVertex, int neighbour)
Called by receiveAndMergeGridVertexAtHorizontalBoundary().
void updateVertexBeforeStore(GridVertex &vertex, GridVertex fineGridVertices[TwoPowerD], const tarch::la::Vector< Dimensions, int > &fineVertexPositionWithinPatch)
bool maySplit() const
Is the tree in principle allowed to split.
bool doesRankIndexIdentifyHorizontalDataExchange(int rank, bool calledByReceivingProcess) const
You may exchange data horizontally with rank if and only if.
void traverse(TraversalObserver &observer, bool calledFromSpacetreeSet=false)
bool mayJoinWithWorker() const
We allow at most one join at a time and not while we split.
void receiveAndMergeGridVertexAtVerticalBoundary(GridVertex &vertex)
This is a merge routine for vertical data exchange.
void receiveAndMergeGridVertexAtHorizontalBoundary(GridVertex &vertex)
Manage the data exchange after a vertex is loaded for the first time.
bool shouldEraseAdjacencyInformation(const GridVertex &vertex, GridVertex coarseGridVertices[TwoPowerD], tarch::la::Vector< Dimensions, int > fineVertexPositionWithinPatch) const
void updateSplittingCounter(int treeId)
Reduce splitting counter.
void mergeCellFromWorkerWithMasterThroughoutJoin(GridVertex vertex[TwoPowerD], GridVertex fineGridVertices[TwoPowerD])
Merge data from worker with master data throughout join.
void splitCellTopDown(GridVertex vertex[TwoPowerD], GridVertex fineGridVertices[TwoPowerD])
Split cell in a top down fashion.
tarch::la::Vector< TwoPowerD, int > getAdjacentRanksForNewVertex(GridVertex coarseGridVertices[TwoPowerD], const tarch::la::Vector< Dimensions, int > &vertexPositionWithin3x3Patch) const
bool areAllVerticesNonHanging(GridVertex vertices[TwoPowerD]) const
Could also be called areAllVerticesPersistent() in the Peano terminology.
bool isCellSplitCandidate(GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD]) const
Can a cell be split (deployed to another rank)
virtual void receiveAndMergeVertex(int, int, SendReceiveContext, const GridTraversalEvent &)
@ PeriodicBoundaryDataSwap
static constexpr int CreateOrDestroyHangingGridEntity
Implies that the data will then be local or had been local.
static constexpr int CreateOrDestroyPersistentGridEntity
Implies that the data will then be local or had been local.
virtual void loadCell(const GridTraversalEvent &event)=0
virtual void storeCell(const GridTraversalEvent &event)=0
virtual void beginTraversal(const tarch::la::Vector< Dimensions, double > &x, const tarch::la::Vector< Dimensions, double > &h)=0
Begin the traversal.
virtual void endTraversal(const tarch::la::Vector< Dimensions, double > &x, const tarch::la::Vector< Dimensions, double > &h)=0
static constexpr int NoData
Can this grid entity hold data.
virtual std::vector< GridControlEvent > getGridControlEvents() const =0
virtual void leaveCell(const GridTraversalEvent &event)=0
virtual void enterCell(const GridTraversalEvent &event)=0
Event is invoked per cell.
virtual void receiveAndMergeFace(int, int, SendReceiveContext, const GridTraversalEvent &)
static int getOutputStackForPeriodicBoundaryExchange(int faceNumber)
Identify output stack for periodic boundary data written by face.
static int getOutputStackNumberForHorizontalDataExchange(int id)
Hand in a spacetree id and get back the number that we should use to send something to this tree.
static int getInputStackNumberForHorizontalDataExchange(int id)
Counterpart of getOutputStackNumberOfBoundaryExchange(int)
std::pair< int, int > PeriodicBoundaryStackIdentifier
A periodic boundary stack is basically a stack (an integer), but I do augment it by a bitset which id...
static int getOutputStackNumberForVerticalDataExchange(int id)
static std::set< PeriodicBoundaryStackIdentifier > getOutputStacksForPeriodicBoundaryExchange(const tarch::la::Vector< TwoPowerD, int > &flags)
You hand in a the flags of a vertex and you get the boundary stack identifiers including their direct...
static int getPeriodicBoundaryExchangeInputStackNumberForOutputStack(int outputStackNumber)
Hand in an output stack number of a face and you get back the input stack number.
static int getInputStackNumberForVerticalDataExchange(int id)
Get the input stack where a tree writes all of its vertical data to/from when it exchanges informatio...
static Node & getInstance()
This operation returns the singleton instance.
void log(const std::string &identifier, double value, bool disableSampling=false)
static Statistics & getInstance()
This is not the canonical realisation of singletons as I use it usually for stats in Peano.
bool isSpacetreeNodeRefined(GridVertex vertices[TwoPowerD])
A spacetree node is refined if any of its adjacent vertices holds one of the following flags:
std::string toString(VertexType type)
bool isSpacetreeNodeLocal(GridVertex vertices[TwoPowerD], bool splittingIsConsideredLocal, bool joiningIsConsideredLocal, int id)
A spacetree node as 2^d adjacent vertices.
void clear(GridStatistics &statistics, bool isGlobalMasterTree)
The term clear() is not 100% correct, as the number of stationary traversals is not reset to a dummy ...
GridVertex createVertex(GridVertex::State state, const tarch::la::Vector< Dimensions, double > &x, int level, const tarch::la::Vector< TwoPowerD, int > &adjacentRanks, bool isNewFineGridVertex)
Factory mechanism.
@ NewFromSplit
Set if this tree results from a split and if this is the first grid sweep when the former owner actua...
@ JoinTriggered
Join has been triggered for this tree.
@ EmptyRun
Not yet a new root.
bool overlaps(const tarch::la::Vector< Dimensions, double > &x, const GridControlEvent &event)
constexpr int InvalidRank(-1)
std::vector< GridControlEvent > merge(std::vector< GridControlEvent > events, const double Tolerance=0.1)
Merge set of refinement/coarsening commands.
bool isContained(const AutomatonState &x, const GridControlEvent &event, double upscaleAutomatonState=1.0)
isContained() is defined over the closed interval, i.e.
std::bitset< Dimensions > LoopDirection
Is used by the z-loop.
CPUGPUMethod int dLinearised(const tarch::la::Vector< Dimensions, int > &counter, int max)
Map d-dimensional vector onto integer index.
bool allGreaterEquals(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
int countEqualEntries(const Vector< Size, int > &lhs, const Vector< Size, int > &rhs)
Run through both vectors and count how many entries are the same.
bool allSmaller(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
Matrix< Rows, Cols, Scalar > multiplyComponents(const Matrix< Rows, X, Scalar > &lhs, const Matrix< X, Cols, Scalar > &rhs)
bool contains(const Vector< Size, Scalar > &vector, const Scalar &value)
Scalar min(const Vector< Size, Scalar > &vector)
Returns the element with minimal value (NOT absolute value).
int numberOfFineGridCells
Provide information about selected face.
tarch::la::Vector< Dimensions, double > getX() const
void setAccessNumber(const tarch::la::Vector< DimensionsTimesTwo, int > &value)
std::string toString() const
void setInverted(bool value)
tarch::la::Vector< Dimensions, double > getH() const
void setH(const tarch::la::Vector< Dimensions, double > &value)
void setEvenFlags(const std::bitset< Dimensions > &value)
void setX(const tarch::la::Vector< Dimensions, double > &value)
void setStationarySweeps(int value)
std::bitset< TwoTimesD > getIsFaceLocal() const
tarch::la::Vector< TwoTimesD, int > getFaceDataFrom() const
std::string toString() const
tarch::la::Vector< TwoPowerD, int > getVertexDataFrom() const
tarch::la::Vector< TwoTimesD, int > getFaceDataTo() const
tarch::la::Vector< TwoPowerD, int > getVertexDataTo() const
std::bitset< TwoPowerD > getIsVertexLocal() const
bool getIsParentOfSubtreeVertexInCurrentTreeSweep() const
tarch::la::Vector< TwoPowerD, int > getAdjacentRanks() const
int getNumberOfAdjacentRefinedLocalCells() const
void setBackupOfAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
tarch::la::Vector< TwoPowerD, int > getBackupOfAdjacentRanks() const
std::string toString() const
bool getIsAntecessorOfRefinedVertexInCurrentTreeSweep() const
void setHasBeenParentOfSubtreeVertexInPreviousTreeSweep(bool value)
void setState(State value)
void setAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
peano4::grid::GridVertex::State getState() const