Peano
Loading...
Searching...
No Matches
grid.cpp
Go to the documentation of this file.
1#include "grid.h"
2
3#include "GridVertex.h"
4#include "AutomatonState.h"
5#include "GridControlEvent.h"
6#include "GridStatistics.h"
7#include "Spacetree.h"
8#include "peano4/utils/Loop.h"
9
10namespace {
11 [[maybe_unused]] tarch::logging::Log _log("peano4::grid");
12} // namespace
13
15 switch (mode) {
17 return "aggressive-top-down";
19 return "bottom-up";
20 }
21 return "<undef>";
22}
23
25 std::ostringstream msg;
26 msg << "(" << toString(mode) << ",#cells=" << numberOfFineGridCells << ")";
27 return msg.str();
28}
29
30std::ostream& operator<<(std::ostream& out, const peano4::SplitInstruction& instruction) {
31 out << instruction.toString();
32 return out;
33}
34
35std::ostream& operator<<(std::ostream& out, const peano4::SplitInstruction::Mode& mode) {
37 return out;
38}
39
41 const peano4::grid::AutomatonState& state, const peano4::grid::GridControlEvent& event, double upscaleAutomatonState
42) {
43 assertion1(upscaleAutomatonState >= 1.0, upscaleAutomatonState);
44 return tarch::la::
45 allGreaterEquals(state.getX() + (0.5 - 0.5 * upscaleAutomatonState) * state.getH(), event.getOffset())
47 state.getX() + (0.5 + 0.5 * upscaleAutomatonState) * state.getH(), event.getOffset() + event.getWidth()
48 );
49}
50
55
60
62 [[maybe_unused]] GridVertex::State state,
63 [[maybe_unused]] const tarch::la::Vector<Dimensions,double>& x,
64 [[maybe_unused]] int level,
65 [[maybe_unused]] const tarch::la::Vector<TwoPowerD,int>& adjacentRanks,
66 [[maybe_unused]] bool isNewFineGridVertex
67) {
68 GridVertex result;
69
70 result.setState(state);
71 result.setAdjacentRanks(adjacentRanks);
72 result.setBackupOfAdjacentRanks(adjacentRanks);
73 result.setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep(not isNewFineGridVertex);
74 result.setIsAntecessorOfRefinedVertexInCurrentTreeSweep(not isNewFineGridVertex);
77
78#if PeanoDebug > 0
79 result.setX(x);
80#endif
81 result.setLevel(level);
82
83 // not required logically, but makes valgrind's memchecker happy
85
86 return result;
87}
88
89std::string peano4::grid::toString(const std::vector<GridControlEvent>& events) {
90 std::ostringstream msg;
91 msg << "(";
92 for (int i = 0; i < static_cast<int>(events.size()); i++) {
93 if (i > 0) {
94 msg << ",";
95 }
96 msg << events[i].toString();
97 }
98 msg << ")";
99 return msg.str();
100}
101
102std::string peano4::grid::toString(const std::list<GridControlEvent>& events) {
103 std::ostringstream msg;
104 msg << "[";
105 for (auto p : events) {
106 msg << p.toString();
107 }
108 msg << "]";
109 return msg.str();
110}
111
112std::vector<peano4::grid::GridControlEvent> peano4::grid::merge(
113 std::vector<GridControlEvent> events, [[maybe_unused]] const double Tolerance
114) {
115 logTraceInWith1Argument("merge(...)", events.size());
116
117 std::list<peano4::grid::GridControlEvent> refineEvents;
118 std::list<peano4::grid::GridControlEvent> eraseEvents;
119 for (auto p : events) {
120 if (p.getRefinementControl() == GridControlEvent::RefinementControl::Erase) {
121 eraseEvents.push_back(p);
122 } else {
123 refineEvents.push_back(p);
124 }
125 }
126 logDebug(
127 "merge(...)",
128 "have a total of "
129 << events.size() << " event(s) consisting of " << refineEvents.size() << " refine and " << eraseEvents.size()
130 << " erase events"
131 );
132
133 internal::removeEraseEventsThatAreCancelledByRefineEvents(refineEvents, eraseEvents);
134 logDebug(
135 "merge(...)",
136 "reduced to " << eraseEvents.size() << " erase event(s) by eliminating erase events that overlap with refinement"
137 );
138
139 internal::mergeAdjacentRefinementEvents(refineEvents, Tolerance);
140 internal::mergeAdjacentRefinementEvents(eraseEvents, Tolerance);
141 logDebug("merge(...)", "merged refine events into " << refineEvents.size() << " event(s)");
142
143 std::vector<peano4::grid::GridControlEvent> result;
144 result.insert(result.begin(), refineEvents.begin(), refineEvents.end());
145 result.insert(result.begin(), eraseEvents.begin(), eraseEvents.end());
146 logTraceOutWith1Argument("merge(...)", result.size());
147 return result;
148}
149
150void peano4::grid::internal::sort(std::list<peano4::grid::GridControlEvent>& events) {
151
152 auto compare = [](const peano4::grid::GridControlEvent& lhs, const peano4::grid::GridControlEvent& rhs) -> bool {
153 if ( tarch::la::smaller( tarch::la::volume(lhs.getH()), tarch::la::volume(rhs.getH()) ) ) return true;
154 for (int d = 0; d < Dimensions; d++) {
155 if (tarch::la::smaller(lhs.getOffset(d), rhs.getOffset(d)))
156 return true;
157 if (tarch::la::greater(lhs.getOffset(d), rhs.getOffset(d)))
158 return false;
159 }
160 return false;
161 };
162
163 events.sort(compare);
164}
165
167 const std::list<peano4::grid::GridControlEvent>& refineEvents, std::list<peano4::grid::GridControlEvent>& eraseEvents
168) {
169 std::list<peano4::grid::GridControlEvent>::iterator pEraseEvent = eraseEvents.begin();
170 while (pEraseEvent != eraseEvents.end()) {
171 bool overlaps = false;
172 for (auto refineEvent : refineEvents) {
173 overlaps |= refinementEventOverrulesCoarsening(refineEvent, *pEraseEvent);
174 }
175 if (overlaps) {
176 pEraseEvent = eraseEvents.erase(pEraseEvent);
177 } else {
178 pEraseEvent++;
179 }
180 }
181}
182
184 std::list<peano4::grid::GridControlEvent>& inputEvents, int Tolerance
185) {
186 bool hasMergedEvents = true;
187 while (hasMergedEvents) {
188 internal::sort(inputEvents);
189 hasMergedEvents = false;
190
191 std::list<peano4::grid::GridControlEvent>::iterator lhs = inputEvents.begin();
192 std::list<peano4::grid::GridControlEvent>::iterator rhs = inputEvents.begin();
193 rhs++;
194
195 while (rhs != inputEvents.end()) {
196 if (twoEventsAreAdjacent(*rhs, *lhs, Tolerance)) {
197 GridControlEvent newEvent = createBoundingBoxEvent(*rhs, *lhs);
198 logDebug(
199 "mergeAdjacentRefinementEvents(...)",
200 "merge two adjacent events "
201 << lhs->toString() << " and " << rhs->toString() << ") into " << newEvent.toString()
202 );
203 *lhs = newEvent;
204 lhs = inputEvents.erase(rhs);
205 rhs = lhs;
206 if (rhs != inputEvents.end())
207 rhs++;
208 hasMergedEvents = true;
209 } else {
210 lhs++;
211 rhs++;
212 }
213 }
214 }
215}
216
219 lhs.getNumberOfLocalUnrefinedCells() + rhs.getNumberOfLocalUnrefinedCells(),
220 lhs.getNumberOfRemoteUnrefinedCells() + rhs.getNumberOfRemoteUnrefinedCells(),
221 lhs.getNumberOfLocalRefinedCells() + rhs.getNumberOfLocalRefinedCells(),
222 lhs.getNumberOfRemoteRefinedCells() + rhs.getNumberOfRemoteRefinedCells(),
223 std::min(lhs.getStationarySweeps(), rhs.getStationarySweeps()),
224 lhs.getCoarseningHasBeenVetoed() or rhs.getCoarseningHasBeenVetoed(),
225 lhs.getRemovedEmptySubtree() or rhs.getRemovedEmptySubtree(),
226 tarch::la::min(lhs.getMinH(), rhs.getMinH())
227 );
228}
229
230void peano4::grid::clear(GridStatistics& statistics, bool isGlobalMasterTree) {
231 statistics.setNumberOfLocalUnrefinedCells(0);
233 statistics.setNumberOfLocalRefinedCells(isGlobalMasterTree ? 1 : 0);
234 statistics.setNumberOfRemoteRefinedCells(isGlobalMasterTree ? 0 : 1);
235 statistics.setCoarseningHasBeenVetoed(false);
236 statistics.setRemovedEmptySubtree(false);
237 statistics.setStationarySweeps(statistics.getStationarySweeps() + 1);
238 statistics.setMinH(tarch::la::Vector<Dimensions, double>(std::numeric_limits<double>::max()));
239}
240
242 bool result = false;
243 dfor2(k) result |= willVertexBeRefined(vertices[kScalar]);
244 result |= hasVertexBeenRefined(vertices[kScalar]);
245 enddforx return result;
246}
247
249 return vertex.getState() == GridVertex::State::Refining or vertex.getState() == GridVertex::State::Refined
250 or vertex.getState() == GridVertex::State::EraseTriggered;
251}
252
254 return vertex.getState() == GridVertex::State::Refined or vertex.getState() == GridVertex::State::EraseTriggered
255 or vertex.getState() == GridVertex::State::Erasing;
256}
257
259 std::bitset<TwoPowerD> bitset;
260 for (int i = 0; i < TwoPowerD; i++) {
261 assertion(not willVertexBeRefined(vertices[i]) or vertices[i].getState() != GridVertex::State::HangingVertex);
262 bitset.set(i, willVertexBeRefined(vertices[i]));
263 }
264 return bitset;
265}
266
268 std::bitset<TwoPowerD> bitset;
269 for (int i = 0; i < TwoPowerD; i++) {
270 assertion(not hasVertexBeenRefined(vertices[i]) or vertices[i].getState() != GridVertex::State::HangingVertex);
271 bitset.set(i, hasVertexBeenRefined(vertices[i]));
272 }
273 return bitset;
274}
275
277 switch (type) {
278 case VertexType::New:
279 return "new";
280 case VertexType::Hanging:
281 return "hanging";
282 case VertexType::Persistent:
283 return "persistent";
284 case VertexType::Delete:
285 return "delete";
286 }
287 return "<undef>";
288}
289
291 switch (type) {
292 case FaceType::New:
293 return "new";
294 case FaceType::Hanging:
295 return "hanging";
296 case FaceType::Persistent:
297 return "persistent";
298 case FaceType::Delete:
299 return "delete";
300 }
301 return "<undef>";
302}
303
305 switch (type) {
306 case CellType::New:
307 return "new";
308 case CellType::Persistent:
309 return "persistent";
310 case CellType::Delete:
311 return "delete";
312 }
313 return "<undef>";
314}
315
317 switch (state) {
318 case SpacetreeState::EmptyRun:
319 return "empty-run";
320 case SpacetreeState::NewRoot:
321 return "new-root";
322 case SpacetreeState::NewFromSplit:
323 return "new-from-split";
324 case SpacetreeState::Running:
325 return "running";
326 case SpacetreeState::JoinTriggered:
327 return "join-triggered";
328 case SpacetreeState::Joining:
329 return "joining";
330 case SpacetreeState::Joined:
331 return "joined";
332 }
333 return "<undef>";
334}
335
338) {
339 bool twoEventsOverlap = true;
340 for (int d = 0; d < Dimensions; d++) {
341 twoEventsOverlap &= lhs.getOffset()(d) + lhs.getWidth()(d) >= rhs.getOffset()(d);
342 twoEventsOverlap &= lhs.getOffset()(d) <= rhs.getOffset()(d) + rhs.getWidth()(d);
343 }
344 return twoEventsOverlap;
345};
346
349) {
350 bool sameType
351 = (lhs.getRefinementControl() == GridControlEvent::RefinementControl::Erase
352 and rhs.getRefinementControl() == GridControlEvent::RefinementControl::Erase)
353 or (lhs.getRefinementControl() == GridControlEvent::RefinementControl::Refine and rhs.getRefinementControl() == GridControlEvent::RefinementControl::Refine);
354
355 return sameType and tarch::la::equals(lhs.getOffset(), rhs.getOffset())
356 and tarch::la::equals(lhs.getWidth(), rhs.getWidth()) and tarch::la::equals(lhs.getH(), rhs.getH());
357};
358
360 const peano4::grid::GridControlEvent& refineEvent, const peano4::grid::GridControlEvent& eraseEvent
361) {
362 return twoEventsOverlap(refineEvent, eraseEvent)
363 and refineEvent.getRefinementControl() == GridControlEvent::RefinementControl::Refine
364 and eraseEvent.getRefinementControl() == GridControlEvent::RefinementControl::Erase
365 and tarch::la::oneSmallerEquals(1.0 / 3.0 * refineEvent.getH(), eraseEvent.getH());
366};
367
369 const peano4::grid::GridControlEvent& lhs, const peano4::grid::GridControlEvent& rhs, double tolerance
370) {
371 tarch::la::Vector<Dimensions, double> boundingEventOffset = tarch::la::min(lhs.getOffset(), rhs.getOffset());
373 boundingEventSize = tarch::la::max(lhs.getOffset() + lhs.getWidth(), rhs.getOffset() + rhs.getWidth())
374 - boundingEventOffset;
375
376 const double relativeTolerance = tarch::la::relativeEps(
377 tarch::la::volume(lhs.getWidth()), tarch::la::volume(rhs.getWidth()), tolerance
378 );
379 const double fusedEventsSize = tarch::la::volume(lhs.getWidth()) + tarch::la::volume(rhs.getWidth());
380 return tarch::la::equals(lhs.getH(), rhs.getH(), relativeTolerance)
381 and tarch::la::smallerEquals(tarch::la::volume(boundingEventSize), fusedEventsSize, relativeTolerance);
382};
383
386) {
387 tarch::la::Vector<Dimensions, double> boundingEventOffset = tarch::la::min(lhs.getOffset(), rhs.getOffset());
389 boundingEventSize = tarch::la::max(lhs.getOffset() + lhs.getWidth(), rhs.getOffset() + rhs.getWidth())
390 - boundingEventOffset;
391 return GridControlEvent(rhs.getRefinementControl(), boundingEventOffset, boundingEventSize, rhs.getH());
392};
393
394void peano4::grid::reduceGridControlEvents([[maybe_unused]] std::vector<GridControlEvent>& events) {
395#ifdef Parallel
396 std::vector<GridControlEvent> localEvents = events;
397 int localSize = events.size();
398 int* sizes = new int[tarch::mpi::Rank::getInstance().getNumberOfRanks()];
399
400 logDebug("reduceGridControlEvents(...)", "feed local data of size " << localEvents.size() << " into allgather");
401
402 MPI_Allgather(&localSize, 1, MPI_INT, sizes, 1, MPI_INT, tarch::mpi::Rank::getInstance().getCommunicator());
403
404 int totalSize = 0;
405 for (int i = 0; i < tarch::mpi::Rank::getInstance().getNumberOfRanks(); i++) {
406 totalSize += sizes[i];
407 }
408 events.resize(totalSize);
409 logDebug(
410 "reduceGridControlEvents(...)",
411 "we have "
412 << totalSize << " grid control event(s) over all ranks, while the local rank hosts " << events.size()
413 << " event(s)"
414 );
415
416 int offset = 0;
417 for (int i = 0; i < tarch::mpi::Rank::getInstance().getNumberOfRanks(); i++) {
419 for (int j = 0; j < sizes[i]; j++) {
420 events[offset + j] = localEvents[j];
421 }
422 }
423
424 if (sizes[i] > 0) {
425 MPI_Bcast(
426 events.data() + offset,
427 sizes[i],
428 GridControlEvent::getGlobalCommunciationDatatype(),
429 i,
431 );
432 offset += sizes[i];
433 }
434 }
435
436 delete[] sizes;
437#endif
438}
#define assertion1(expr, param)
#define assertion(expr)
std::ostream & operator<<(std::ostream &out, const peano4::datamanagement::CellMarker &marker)
Definition CellMarker.cpp:7
#define TwoPowerD
Definition Globals.h:19
AutomatonState state
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logTraceOutWith1Argument(methodName, argument0)
Definition Log.h:380
#define logTraceInWith1Argument(methodName, argument0)
Definition Log.h:370
#define dfor2(counter)
Shortcut For dfor(counter,2)
Definition Loop.h:911
#define enddforx
I prefer to use this macro for dforx instead of a closing bracket as many syntax parser fail otherwis...
Definition Loop.h:933
Log Device.
Definition Log.h:516
int getNumberOfRanks() const
Definition Rank.cpp:552
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
int getRank() const
Return rank of this node.
Definition Rank.cpp:529
MPI_Comm getCommunicator() const
Definition Rank.cpp:545
std::string toString(Filter filter)
Definition convert.cpp:170
tarch::logging::Log _log("exahype2::fv")
peano4::grid::GridStatistics operator+(peano4::grid::GridStatistics lhs, peano4::grid::GridStatistics rhs)
Definition grid.cpp:217
bool twoEventsAreAdjacent(const peano4::grid::GridControlEvent &lhs, const peano4::grid::GridControlEvent &rhs, double Tolerance)
Are two events adjacent.
Definition grid.cpp:368
void mergeAdjacentRefinementEvents(std::list< peano4::grid::GridControlEvent > &inputEvents, int Tolerance)
Merge adjacent events.
Definition grid.cpp:183
void removeEraseEventsThatAreCancelledByRefineEvents(const std::list< peano4::grid::GridControlEvent > &refineEvents, std::list< peano4::grid::GridControlEvent > &eraseEvents)
This is the first thing I do.
Definition grid.cpp:166
bool refinementEventOverrulesCoarsening(const peano4::grid::GridControlEvent &refineEvent, const peano4::grid::GridControlEvent &eraseEvent)
A refinement event overrules the coarsening if.
Definition grid.cpp:359
peano4::grid::GridControlEvent createBoundingBoxEvent(const peano4::grid::GridControlEvent &lhs, const peano4::grid::GridControlEvent &rhs)
Definition grid.cpp:384
void sort(std::list< peano4::grid::GridControlEvent > &events)
Sort grid control events geometrically.
Definition grid.cpp:150
bool twoEventsOverlap(const peano4::grid::GridControlEvent &lhs, const peano4::grid::GridControlEvent &rhs)
Helper function which helps us throughout the merge.
Definition grid.cpp:336
bool equals(const peano4::grid::GridControlEvent &lhs, const peano4::grid::GridControlEvent &rhs)
Definition grid.cpp:347
bool isSpacetreeNodeRefined(GridVertex vertices[TwoPowerD])
A spacetree node is refined if any of its adjacent vertices holds one of the following flags:
Definition grid.cpp:241
std::string toString(VertexType type)
Definition grid.cpp:276
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 ...
Definition grid.cpp:230
void reduceGridControlEvents(std::vector< GridControlEvent > &events)
Peano 4 does not reduce any grid control events globally.
Definition grid.cpp:394
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.
Definition grid.cpp:61
std::bitset< TwoPowerD > haveVerticesBeenRefined(GridVertex vertices[TwoPowerD])
Definition grid.cpp:267
bool overlaps(const tarch::la::Vector< Dimensions, double > &x, const GridControlEvent &event)
Definition grid.cpp:56
std::bitset< TwoPowerD > willVerticesBeRefined(GridVertex vertices[TwoPowerD])
A vertex is unrefined if it is hanging.
Definition grid.cpp:258
bool hasVertexBeenRefined(const GridVertex &vertex)
A vertex has been refined if it is (already) refined or is erasing or the erase has been triggered.
Definition grid.cpp:253
std::vector< GridControlEvent > merge(std::vector< GridControlEvent > events, const double Tolerance=0.1)
Merge set of refinement/coarsening commands.
Definition grid.cpp:112
bool willVertexBeRefined(const GridVertex &vertex)
A vertex will be refined if it is already refined or currently refining.
Definition grid.cpp:248
bool isContained(const AutomatonState &x, const GridControlEvent &event, double upscaleAutomatonState=1.0)
isContained() is defined over the closed interval, i.e.
Definition grid.cpp:40
Scalar volume(const Vector< Size, Scalar > &vector)
Computes the volume of the tetrahedron spanned by the Cartesian unit vectors scaled by the correspond...
bool allGreaterEquals(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
static bool smaller(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE) InlineMethod
Smaller operator for floating point values.
bool greater(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool oneSmallerEquals(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
double relativeEps(double valueA, double valueB=std::numeric_limits< double >::min(), double eps=NUMERICAL_ZERO_DIFFERENCE)
Determine a relative tolerance from one or two values.
Definition Scalar.cpp:14
double max(double a, double b, double c)
I need the maximum of three values all the time, to I decided to write a function for this.
Definition Scalar.cpp:8
bool smallerEquals(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool allSmallerEquals(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.
Scalar min(const Vector< Size, Scalar > &vector)
Returns the element with minimal value (NOT absolute value).
Instruction to split.
Definition grid.h:34
static std::string toString(Mode mode)
Definition grid.cpp:14
std::string toString() const
Definition grid.cpp:24
tarch::la::Vector< Dimensions, double > getWidth() const
peano4::grid::GridControlEvent::RefinementControl getRefinementControl() const
tarch::la::Vector< Dimensions, double > getOffset() const
tarch::la::Vector< Dimensions, double > getH() const
void setNumberOfLocalRefinedCells(int value)
void setNumberOfRemoteUnrefinedCells(int value)
void setMinH(const tarch::la::Vector< Dimensions, double > &value)
void setCoarseningHasBeenVetoed(bool value)
void setNumberOfLocalUnrefinedCells(int value)
void setNumberOfRemoteRefinedCells(int value)
tarch::la::Vector< Dimensions, double > getMinH() const
void setRemovedEmptySubtree(bool value)
void setBackupOfAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
void setIsAntecessorOfRefinedVertexInCurrentTreeSweep(bool value)
void setLevel(int value)
void setNumberOfAdjacentRefinedLocalCells(int value)
void setIsParentOfSubtreeVertexInCurrentTreeSweep(bool value)
void setHasBeenParentOfSubtreeVertexInPreviousTreeSweep(bool value)
void setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep(bool value)
void setState(State value)
void setAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
peano4::grid::GridVertex::State getState() const
Simple vector class.
Definition Vector.h:134