Peano
Loading...
Searching...
No Matches
GridTraversalEventGenerator.cpp
Go to the documentation of this file.
2#include "grid.h"
3#include "PeanoCurve.h"
4#include "Spacetree.h"
5#include "TraversalObserver.h"
6
7#include "peano4/utils/Loop.h"
8
9tarch::logging::Log peano4::grid::GridTraversalEventGenerator::_log( "peano4::grid::GridTraversalEventGenerator" );
10
13
15 [[maybe_unused]] GridVertex vertices[TwoPowerD],
16 [[maybe_unused]] const SplitSpecification& splitTriggered,
17 [[maybe_unused]] const std::set<int>& splitting,
18 [[maybe_unused]] const std::set< int >& joinTriggered,
19 [[maybe_unused]] const std::set< int >& joining
20) const {
21 std::bitset<TwoPowerD> bitset;
22 for (int i=0; i<TwoPowerD; i++) {
23 bitset.set(i,isVertexAdjacentToLocalSpacetree(vertices[i], splitTriggered, splitting, joinTriggered, joining, true, true));
24 }
25 logDebug( "areVerticesLocal(...)", bitset );
26 return bitset;
27}
28
30 [[maybe_unused]] GridVertex vertices[TwoPowerD],
31 [[maybe_unused]] const SplitSpecification& splitTriggered,
32 [[maybe_unused]] const std::set<int>& splitting,
33 [[maybe_unused]] const std::set< int >& joinTriggered,
34 [[maybe_unused]] const std::set< int >& joining
35) const {
36 std::bitset<TwoTimesD> result;
37 for (int faceNumber=0; faceNumber<2*Dimensions; faceNumber++) {
38 bool isLocal = false;
39
40 const int normal = faceNumber % Dimensions;
41 for (int i=0; i<TwoPowerD; i++) {
42 std::bitset<Dimensions> studiedVertex = i;
43 studiedVertex.set(normal,faceNumber>=Dimensions);
44 std::bitset<Dimensions> studiedEntry = TwoPowerD - studiedVertex.to_ulong() - 1;
45
46 studiedEntry.set(normal,0);
47 int currentRank = vertices[studiedVertex.to_ulong()].getAdjacentRanks( studiedEntry.to_ulong() );
48 if (
49 vertices[studiedVertex.to_ulong()].getState()!=GridVertex::State::HangingVertex
50 or
51 faceNumber>=Dimensions
52 ) {
53 isLocal |= currentRank == _id;
54 isLocal |= splitTriggered.count(currentRank)>0;
55 isLocal |= splitting.count(currentRank)>0;
56 }
57
58 studiedEntry.set(normal,1);
59 if (
60 vertices[studiedVertex.to_ulong()].getState()!=GridVertex::State::HangingVertex
61 or
62 faceNumber<Dimensions
63 ) {
64 currentRank = vertices[studiedVertex.to_ulong()].getAdjacentRanks( studiedEntry.to_ulong() );
65 isLocal |= currentRank == _id;
66 isLocal |= splitTriggered.count(currentRank)>0;
67 isLocal |= splitting.count(currentRank)>0;
68 }
69 }
70
71 result[faceNumber] = isLocal;
72 }
73 return result;
74}
75
77 [[maybe_unused]] GridVertex vertex,
78 [[maybe_unused]] const SplitSpecification& splitTriggered,
79 [[maybe_unused]] const std::set<int>& splitting,
80 [[maybe_unused]] const std::set< int >& joinTriggered,
81 [[maybe_unused]] const std::set< int >& joining,
82 [[maybe_unused]] bool splittingIsConsideredLocal,
83 [[maybe_unused]] bool joiningIsConsideredLocal
84) const {
85/*
86 if (vertex.getState()==GridVertex::State::HangingVertex) {
87 return false;
88 }
89 else {
90*/
91 logTraceInWith3Arguments( "isVertexAdjacentToLocalSpacetree(...)", vertex.toString(), splittingIsConsideredLocal, joiningIsConsideredLocal );
92 bool result = false;
93 for(int i=0; i<TwoPowerD; i++) {
94 assertion( splitTriggered.count( vertex.getAdjacentRanks(i) )<=1 );
95 assertion( splitting.count( vertex.getAdjacentRanks(i) )<=1 );
96
97 result |= vertex.getAdjacentRanks(i)==_id;
98
99 result |= splitTriggered.count( vertex.getAdjacentRanks(i) )==1;
100 result |= (splittingIsConsideredLocal and splitting.count( vertex.getAdjacentRanks(i) )==1);
101
102 result |= (joiningIsConsideredLocal and joining.count( vertex.getAdjacentRanks(i) )==1);
103 }
104 logTraceOutWith1Argument( "isVertexAdjacentToLocalSpacetree(...)", result );
105 return result;
106// }
107}
108
110 [[maybe_unused]] GridVertex vertices[TwoPowerD],
111 [[maybe_unused]] const SplitSpecification& splitTriggered,
112 [[maybe_unused]] const std::set<int>& splitting,
113 [[maybe_unused]] const std::set< int >& joinTriggered,
114 [[maybe_unused]] const std::set< int >& joining,
115 [[maybe_unused]] bool splittingIsConsideredLocal,
116 [[maybe_unused]] bool joiningIsConsideredLocal
117) const {
118 bool isLocal = true;
119 dfor2(k)
120 isLocal &= (
121 (vertices[kScalar].getState()==GridVertex::State::HangingVertex)
122 or
123 (
124 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)==_id
125 )
126 or
127 ( splitTriggered.count(vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)) > 0)
128 or
129 (
130 splittingIsConsideredLocal and splitting.count(vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1))>0
131 )
132 or
133 (
134 joiningIsConsideredLocal and joining.count(vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1))>0
135 )
136 );
138
139 return isLocal;
140}
141
143 [[maybe_unused]] GridVertex vertices[TwoPowerD],
144 [[maybe_unused]] const SplitSpecification& splitTriggered,
145 [[maybe_unused]] const std::set<int>& splitting,
146 [[maybe_unused]] const std::set< int >& joinTriggered,
147 [[maybe_unused]] const std::set< int >& joining,
148 [[maybe_unused]] bool calledByLeaveCell
149) const {
150 std::bitset<TwoPowerD> result;
151 for (int j=0; j<TwoPowerD; j++) {
152 tarch::la::Vector< TwoPowerD, int > adjacency = vertices[j].getBackupOfAdjacentRanks();
153 bool oneLocal = false;
154 bool oneRemote = false;
155 for (int i=0; i<TwoPowerD; i++ ) {
156 bool valid = adjacency(i)>=0 or adjacency(i)==peano4::grid::Spacetree::RankOfPeriodicBoundaryCondition;
157 bool local = adjacency(i)==_id or splitting.count(adjacency(i))>0 or splitTriggered.count(adjacency(i))>0;
158 oneLocal |= (valid and local);
159 oneRemote |= (valid and not local);
160 }
161 result.set(j,oneLocal and oneRemote);
162 }
163 return result;
164}
165
167 [[maybe_unused]] GridVertex vertices[TwoPowerD],
168 [[maybe_unused]] const SplitSpecification& splitTriggered,
169 [[maybe_unused]] const std::set<int>& splitting,
170 [[maybe_unused]] const std::set< int >& joinTriggered,
171 [[maybe_unused]] const std::set< int >& joining,
172 [[maybe_unused]] bool calledByLeaveCell
173) const {
174 std::bitset<TwoTimesD> result;
175 for (int j=0; j<TwoTimesD; j++) {
176 // @todo
177 tarch::la::Vector< TwoPowerD, int > adjacency = getAdjacentRanksOfFace(vertices, j, calledByLeaveCell);
178 //tarch::la::Vector< TwoPowerD, int > adjacency = getAdjacentRanksOfFace(vertices, i, false);
179 bool oneLocal = false;
180 bool oneRemote = false;
181 for (int i=0; i<TwoPowerD; i++ ) {
182 // @todo noch rueber auf vertices
183 // So ganz stimmt es natuerlich net, weil das ist ja jetzt eins zu frueh
184 bool valid = adjacency(i)>=0 or adjacency(i)==peano4::grid::Spacetree::RankOfPeriodicBoundaryCondition;
185/*
186 bool local = adjacency(i)==_id
187 or (splitting.count(adjacency(i))>0 and calledByEnterCell)
188 or splitTriggered.count(adjacency(i))>0;
189 bool remote = adjacency(i)!=_id
190 and not splitTriggered.count(adjacency(i))>0
191 and (not splitting.count(adjacency(i))>0 or not calledByEnterCell);
192*/
193 bool local = adjacency(i)==_id
194 or splitTriggered.count(adjacency(i))>0
195// or splitting.count(adjacency(i))>0;
196 or (splitting.count(adjacency(i))>0 and not calledByLeaveCell);
197 bool remote = adjacency(i)!=_id
198 and not (splitTriggered.count(adjacency(i))>0)
199 and (splitting.count(adjacency(i))==0 or calledByLeaveCell);
200// and not (splitTriggered.count(adjacency(i))>0 and calledByLeaveCell);
201// bool remote = not local;
202 oneLocal |= (valid and local);
203 oneRemote |= (valid and remote);
204 }
205 result.set(j,oneLocal and oneRemote);
206 }
207 return result;
208}
209
211 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
212 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
213 [[maybe_unused]] const AutomatonState& state,
214 [[maybe_unused]] const SplitSpecification& splitTriggered,
215 [[maybe_unused]] const std::set<int>& splitting,
216 [[maybe_unused]] const std::set< int >& joinTriggered,
217 [[maybe_unused]] const std::set< int >& joining,
218 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
219 [[maybe_unused]] bool spacetreeStateIsRunning
220) const {
221 #if Dimensions==2
222 logTraceInWith7Arguments( "createGenericCellTraversalEvent(...)", state.toString(), relativePositionToFather, fineGridVertices[0].toString(), fineGridVertices[1].toString(), fineGridVertices[2].toString(), fineGridVertices[3].toString(), _id );
223 #else
224 logTraceInWith3Arguments( "createGenericCellTraversalEvent(...)", state.toString(), relativePositionToFather, _id );
225 #endif
226 GridTraversalEvent event;
227 event.setX( state.getX() + state.getH()*0.5 );
228 event.setH( state.getH() );
229
230 event.setHasBeenRefined( haveVerticesBeenRefined(fineGridVertices) );
231 event.setWillBeRefined( willVerticesBeRefined(fineGridVertices) );
232 event.setRelativePositionToFather( relativePositionToFather );
233
234 event.setIsCellLocal( isSpacetreeNodeLocal( fineGridVertices, splitTriggered, splitting, joinTriggered, joining, true, true) );
235 event.setIsParentCellLocal( state.getLevel()>1 and isSpacetreeNodeLocal( coarseGridVertices, splitTriggered, splitting, joinTriggered, joining, true, true) );
236 event.setIsFaceLocal( areFacesLocal( fineGridVertices, splitTriggered, splitting, joinTriggered, joining) );
237 event.setIsVertexLocal( areVerticesLocal( fineGridVertices, splitTriggered, splitting, joinTriggered, joining) );
238
239 event.setIsParentVertexLocal( areVerticesLocal( coarseGridVertices, splitTriggered, splitting, joinTriggered, joining) );
240
241 event.setInvokingSpacetree( _id );
242 event.setInvokingSpacetreeIsNotInvolvedInAnyDynamicLoadBalancing(
243 spacetreeStateIsRunning and
244 joinTriggered.empty() and
245 joining.empty() and
246 splitTriggered.empty() and
247 splitting.empty()
248 );
249
250 event.setIsAdjacentCellLocal(0);
251 dfor2(k) {
252 if (fineGridVertices[kScalar].getState()!=GridVertex::State::HangingVertex) {
253 dfor2(j) {
254 tarch::la::Vector<Dimensions,int> entryIn3x3Patch = k + j;
255 int owningTree = fineGridVertices[kScalar].getAdjacentRanks(jScalar);
256 event.setIsAdjacentCellLocal(
257 peano4::utils::dLinearised(entryIn3x3Patch,3),
258 owningTree == _id
259 );
260 event.setIsVertexParentOfSubtree( fineGridVertices[kScalar].getHasBeenParentOfSubtreeVertexInPreviousTreeSweep() );
261 } enddforx
262 }
263 } enddforx
264
265 dfor2(k) {
266 std::set<int> neighbourIds;
267
268 for (int i = 0; i < TwoPowerD; i++) {
269 if (fineGridVertices[kScalar].getAdjacentRanks(i)>=0) {
270 neighbourIds.insert(fineGridVertices[kScalar].getAdjacentRanks(i));
271 }
272 }
273
274 event.setNumberOfAdjacentTreesPerVertex(kScalar,neighbourIds.size());
275 } enddforx
276
277 logTraceOutWith2Arguments( "createGenericCellTraversalEvent(...)", event.toString(), _id );
278 return event;
279}
280
282 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
283 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
284 [[maybe_unused]] const AutomatonState& state,
285 [[maybe_unused]] const SplitSpecification& splitTriggered,
286 [[maybe_unused]] const std::set<int>& splitting,
287 [[maybe_unused]] const std::set< int >& joinTriggered,
288 [[maybe_unused]] const std::set< int >& joining,
289 [[maybe_unused]] const std::set< int >& hasSplit,
290 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
291 [[maybe_unused]] bool spacetreeStateIsRunning
292) const {
293 logTraceInWith3Arguments( "createLeaveCellTraversalEvent(...)", state.toString(), _id, relativePositionToFather );
294 GridTraversalEvent event = createGenericCellTraversalEvent(coarseGridVertices, fineGridVertices, state, splitTriggered, splitting, joinTriggered, joining, relativePositionToFather, spacetreeStateIsRunning);
295
296 event.setIsVertexAdjacentToParallelDomainBoundary( areVerticesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, true) );
297 event.setIsFaceAdjacentToParallelDomainBoundary( areFacesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, true));
298
299 const std::bitset<Dimensions> coordinates = PeanoCurve::getFirstVertexIndex(state);
300 for (int i=0; i<TwoPowerD; i++) {
301 const std::bitset<Dimensions> vertexIndex( coordinates ^ std::bitset<Dimensions>(i) );
302 const int stackNumber = PeanoCurve::getVertexWriteStackNumber(state,vertexIndex);
303
304 event.setVertexDataFrom(i,vertexIndex.to_ulong());
305 switch ( fineGridVertices[vertexIndex.to_ulong()].getState() ) {
308 break;
316 event.setVertexDataTo(i,stackNumber);
317 break;
319 {
320 if ( PeanoCurve::isInOutStack(stackNumber) ) {
322 }
323 else {
324 event.setVertexDataTo(i,stackNumber);
325 }
326 }
327 break;
328 }
329
330 if (
331 PeanoCurve::isInOutStack(event.getVertexDataTo(i))
332 and
333 not event.getIsVertexLocal(vertexIndex.to_ulong())
334 ) {
335 logDebug(
336 "createLeaveCellTraversalEvent(...)",
337 "reset event entry " << i << " to no-data as we have " << event.toString()
338 << ". vertex=" << fineGridVertices[vertexIndex.to_ulong()].toString()
339 );
340 event.setVertexDataTo(i,TraversalObserver::NoData);
341 }
342 }
343
344 for (int i=0; i<2*Dimensions; i++) {
346 FaceType type = getFaceType(coarseGridVertices,relativePositionToFather,faceIndex);
347 const int stackNumber = PeanoCurve::getFaceWriteStackNumber(state,faceIndex);
348
349 event.setFaceDataFrom(i,faceIndex);
350
351 switch (type) {
354 break;
355 case FaceType::New:
357 event.setFaceDataTo(i,stackNumber);
358 break;
359 case FaceType::Delete:
360 if ( PeanoCurve::isInOutStack(stackNumber) ) {
362 }
363 else {
364 event.setFaceDataTo(i,stackNumber);
365 }
366 break;
367 }
368
369 if (
370 PeanoCurve::isInOutStack(event.getFaceDataTo(i))
371 and
372 not event.getIsFaceLocal(faceIndex)
373 ) {
374 event.setFaceDataTo(i,TraversalObserver::NoData);
375 }
376 }
377
378 {
379 CellType type = getCellType(coarseGridVertices,relativePositionToFather);
380 const int stackNumber = PeanoCurve::getCellWriteStackNumber(state);
381
382 switch (type) {
383 case CellType::New:
384 event.setCellData(stackNumber);
385 break;
387 event.setCellData(stackNumber);
388 break;
389 case CellType::Delete:
391 break;
392 }
393
394 if (
395 // always true here, but if I write it here explicitly, then it is consistent with faces/vertices
396 PeanoCurve::isInOutStack(event.getCellData())
397 and
398 not event.getIsCellLocal()
399 ) {
400 event.setCellData(TraversalObserver::NoData);
401 }
402 }
403
404 #if !defined(SharedMemoryParallelisation)
405 for (int i=0; i<TwoPowerD; i++)
406 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
407 for (int i=0; i<TwoTimesD; i++)
408 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
409 #endif
410
411 logTraceOutWith3Arguments( "createLeaveCellTraversalEvent(...)", state.toString(), event.toString(), _id );
412 return event;
413}
414
415
417 GridTraversalEvent result = event;
418
419 if(
420 spacetreeState==SpacetreeState::EmptyRun or
421 spacetreeState==SpacetreeState::NewFromSplit or
422 spacetreeState==SpacetreeState::Joining
423 ) {
424 result.setIsCellLocal(false);
425 result.setIsParentCellLocal(false);
426 result.setIsFaceLocal(0);
427 result.setIsVertexLocal(0);
428 }
429
430/*
431 if(
432 spacetreeState==SpacetreeState::EmptyRun or
433 spacetreeState==SpacetreeState::NewFromSplit
434 ) {
435 result.setVertexDataFrom(TraversalObserver::NoData);
436 result.setFaceDataFrom(TraversalObserver::NoData);
437 result.setCellData(TraversalObserver::NoData);
438 }
439*/
440
441 return result;
442}
443
444
446 GridTraversalEvent result = event;
447
448 if(
449 spacetreeState==SpacetreeState::EmptyRun or
450 spacetreeState==SpacetreeState::NewFromSplit or
451 spacetreeState==SpacetreeState::Joining
452 ) {
453 result.setIsCellLocal(false);
454 result.setIsParentCellLocal(false);
455 result.setIsFaceLocal(0);
456 result.setIsVertexLocal(0);
457 }
458
459 /*
460 if(
461 spacetreeState==SpacetreeState::EmptyRun or
462// spacetreeState==SpacetreeState::NewFromSplit or
463 spacetreeState==SpacetreeState::Joining
464 ) {
465 result.setVertexDataTo(TraversalObserver::NoData);
466 result.setFaceDataTo(TraversalObserver::NoData);
467 result.setCellData(TraversalObserver::NoData);
468 }
469*/
470
471 return result;
472}
473
474
476 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
477 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
478 [[maybe_unused]] const AutomatonState& state,
479 [[maybe_unused]] const SplitSpecification& splitTriggered,
480 [[maybe_unused]] const std::set<int>& splitting,
481 [[maybe_unused]] const std::set< int >& joinTriggered,
482 [[maybe_unused]] const std::set< int >& joining,
483 [[maybe_unused]] const std::set< int >& hasSplit,
484 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
485 [[maybe_unused]] bool spacetreeStateIsRunning
486) const {
487 logTraceInWith7Arguments( "createEnterCellTraversalEvent(...)", state.toString(), _id, relativePositionToFather, coarseGridVertices[0].toString(), coarseGridVertices[1].toString(), coarseGridVertices[2].toString(), coarseGridVertices[3].toString() );
488 GridTraversalEvent event = createGenericCellTraversalEvent(coarseGridVertices, fineGridVertices, state, splitTriggered, splitting, joinTriggered, joining, relativePositionToFather, spacetreeStateIsRunning);
489
490 event.setIsVertexAdjacentToParallelDomainBoundary( areVerticesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false) );
491 event.setIsFaceAdjacentToParallelDomainBoundary( areFacesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false));
492
493 #if !defined(SharedMemoryParallelisation)
494 for (int i=0; i<TwoPowerD; i++)
495 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
496 for (int i=0; i<TwoTimesD; i++)
497 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
498 #endif
499
500 const std::bitset<Dimensions> coordinates = PeanoCurve::getFirstVertexIndex(state);
501 for (int i=0; i<TwoPowerD; i++) {
502 const std::bitset<Dimensions> vertexIndex( coordinates ^ std::bitset<Dimensions>(i) );
503 const int stackNumber = PeanoCurve::getVertexReadStackNumber(state,vertexIndex);
504 const int vertexPosition = vertexIndex.to_ulong();
505
506 switch ( fineGridVertices[vertexPosition].getState() ) {
509 break;
511 {
512 if ( PeanoCurve::isInOutStack(stackNumber) ) {
514 }
515 else {
516 event.setVertexDataFrom(i,stackNumber);
517 }
518 }
519 break;
527 event.setVertexDataFrom(i,stackNumber);
528 break;
529 }
530 event.setVertexDataTo(i,vertexIndex.to_ulong());
531
532 bool mayResetToNoData =
533 PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
534 and
535 not event.getIsVertexLocal(vertexPosition);
536
537 for (auto p: hasSplit) {
538 mayResetToNoData &= not tarch::la::contains( fineGridVertices[vertexPosition].getAdjacentRanks(), p );
539 }
540
541 if (mayResetToNoData) {
542 event.setVertexDataFrom(i,TraversalObserver::NoData);
543 }
544
545 logDebug(
546 "createEnterCellTraversalEvent(...)",
547 "vertex " << i << " on on tree " << _id << ": " <<
548 event.toString() << ", mayResetToNoData=" << mayResetToNoData <<
549 ", is-local=" << event.getIsVertexLocal(vertexPosition) << ", is in-out=" << PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
550 << ", vertex[0]=" << fineGridVertices[0].toString()
551 << ", vertex[1]=" << fineGridVertices[1].toString()
552 << ", vertex[2]=" << fineGridVertices[2].toString()
553 << ", vertex[3]=" << fineGridVertices[3].toString()
554 << ", vertex[4]=" << fineGridVertices[4].toString()
555 << ", vertex[5]=" << fineGridVertices[5].toString()
556 << ", vertex[6]=" << fineGridVertices[6].toString()
557 << ", vertex[7]=" << fineGridVertices[7].toString()
558 );
559 }
560
561 for (int i=0; i<2*Dimensions; i++) {
563 FaceType type = getFaceType(coarseGridVertices,relativePositionToFather,faceIndex);
564 const int stackNumber = PeanoCurve::getFaceReadStackNumber(state,faceIndex);
565
566 switch (type) {
567 case FaceType::New:
568 {
569 if ( PeanoCurve::isInOutStack(stackNumber) ) {
571 }
572 else {
573 event.setFaceDataFrom(i,stackNumber);
574 }
575 }
576 break;
579 break;
581 case FaceType::Delete:
582 event.setFaceDataFrom(i,stackNumber);
583 break;
584 }
585 event.setFaceDataTo(i,faceIndex);
586
587 bool mayResetToNoData =
588 PeanoCurve::isInOutStack(event.getFaceDataFrom(i))
589 and
590 not event.getIsFaceLocal(faceIndex);
591
592 for (auto p: hasSplit) {
593 mayResetToNoData &= not tarch::la::contains( getAdjacentRanksOfFace(fineGridVertices, faceIndex, false), p );
594 }
595
596 if (mayResetToNoData) {
597 event.setFaceDataFrom(i,TraversalObserver::NoData);
598 }
599 }
600
601 {
602 CellType type = getCellType(coarseGridVertices,relativePositionToFather);
603 const int stackNumber = PeanoCurve::getCellReadStackNumber(state);
604 switch (type) {
605 case CellType::New:
607 break;
609 event.setCellData(stackNumber);
610 break;
611 case CellType::Delete:
612 event.setCellData(stackNumber);
613 break;
614 }
615 }
616
617 bool mayResetToNoData =
618 // always true here, but if I write it here explicitly, then it is consistent with faces/vertices
619 PeanoCurve::isInOutStack(event.getCellData())
620 and
621 not event.getIsCellLocal();
622
623 for (auto p: hasSplit) {
624 mayResetToNoData &= getTreeOwningSpacetreeNode(fineGridVertices, splitTriggered, splitting, joinTriggered, joining)!=p;
625 }
626
627 if (mayResetToNoData) {
628 event.setCellData(TraversalObserver::NoData);
629 }
630
631 #if !defined(SharedMemoryParallelisation)
632 for (int i=0; i<TwoPowerD; i++)
633 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
634 for (int i=0; i<TwoTimesD; i++)
635 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
636 #endif
637
638 logTraceOutWith3Arguments( "createEnterCellTraversalEvent(...)", state.toString(), event.toString(), _id );
639 return event;
640}
641
642
644 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
645 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell,
646 [[maybe_unused]] int faceNumber
647) {
648 logTraceInWith1Argument( "getFaceType(...)", faceNumber );
649
650 bool allVerticesAreHanging = true;
651 bool allVerticesAreDeleteOrHanging = true;
652 bool allVerticesAreNewOrHanging = true;
653
654 const int normal = faceNumber % Dimensions;
655 for (int i=0; i<TwoPowerD; i++) {
656 std::bitset<Dimensions> studiedVertex = i;
657 studiedVertex.set(normal,faceNumber>=Dimensions);
658 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(studiedVertex) ) ) {
660 break;
661 case VertexType::New:
662 allVerticesAreDeleteOrHanging = false;
663 allVerticesAreHanging = false;
664 break;
666 allVerticesAreHanging = false;
667 allVerticesAreDeleteOrHanging = false;
668 allVerticesAreNewOrHanging = false;
669 break;
671 allVerticesAreHanging = false;
672 allVerticesAreNewOrHanging = false;
673 break;
674 }
675 }
676
678 if ( allVerticesAreHanging ) {
679 result = FaceType::Hanging;
680 }
681 else if ( allVerticesAreNewOrHanging ) {
682 result = FaceType::New;
683 }
684 else if ( allVerticesAreDeleteOrHanging ) {
685 result = FaceType::Delete;
686 }
687
688 logTraceOutWith4Arguments( "getFaceType(...)", toString(result), allVerticesAreDeleteOrHanging, allVerticesAreNewOrHanging, allVerticesAreHanging );
689 return result;
690}
691
692
694 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
695 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell
696) {
697 bool allVerticesAreDelete = true;
698 bool allVerticesAreNew = true;
699
700 for (int i=0; i<TwoPowerD; i++) {
701 std::bitset<Dimensions> vectorPosition = i;
702 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(vectorPosition) )) {
704 break;
706 allVerticesAreDelete = false;
707 allVerticesAreNew = false;
708 break;
709 case VertexType::New:
710 allVerticesAreDelete = false;
711 break;
713 allVerticesAreNew = false;
714 break;
715 }
716 }
717
718 assertion( not (allVerticesAreDelete and allVerticesAreNew) );
719
720 if (allVerticesAreDelete) {
721 logDebug( "getCellType(...)", "delete cell" );
722 return CellType::Delete;
723 }
724 else if (allVerticesAreNew) {
725 logDebug( "getCellType(...)", "create new cell" );
726 return CellType::New;
727 }
728 else {
729 logDebug( "getCellType(...)", "keep cell" );
731 }
732}
733
734
736 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
737 [[maybe_unused]] tarch::la::Vector<Dimensions,int> position
738) {
739 #if Dimensions==2 or Dimensions==3
740 if (
741 coarseGridVertices[0].getState()==GridVertex::State::Refined
742 and
743 coarseGridVertices[1].getState()==GridVertex::State::Refined
744 and
745 coarseGridVertices[2].getState()==GridVertex::State::Refined
746 and
747 coarseGridVertices[3].getState()==GridVertex::State::Refined
748 #if Dimensions==3
749 and
750 coarseGridVertices[4].getState()==GridVertex::State::Refined
751 and
752 coarseGridVertices[5].getState()==GridVertex::State::Refined
753 and
754 coarseGridVertices[6].getState()==GridVertex::State::Refined
755 and
756 coarseGridVertices[7].getState()==GridVertex::State::Refined
757 #endif
758 ) {
760 }
761 #endif
762 return getVertexType(
763 coarseGridVertices,
764 position,
765 Dimensions-1
766 );
767}
768
769
771 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
772 [[maybe_unused]] tarch::la::Vector<Dimensions,int> position,
773 [[maybe_unused]] int dimension
774) {
775 if (dimension<0) {
776 switch (coarseGridVertices[ peano4::utils::dLinearised(position,2) ].getState()) {
778 return VertexType::Hanging;
782 return VertexType::Hanging;
786 return VertexType::Hanging;
788 return VertexType::New;
792 return VertexType::Delete;
793 }
794 assertion3(false, peano4::utils::dLinearised(position,2), position, coarseGridVertices[ peano4::utils::dLinearised(position,2) ].toString() );
795 }
796 else if ( position(dimension)==0 ) {
797 position(dimension)=0;
798 return getVertexType(coarseGridVertices,position,dimension-1);
799 }
800 else if ( position(dimension)==3 ) {
801 position(dimension)=1;
802 return getVertexType(coarseGridVertices,position,dimension-1);
803 }
804
805 logTraceInWith2Arguments( "getVertexType(...)", position, dimension );
806 position(dimension)=0;
807 peano4::grid::VertexType lhs = getVertexType(coarseGridVertices,position,dimension-1);
808
809 position(dimension)=1;
810 peano4::grid::VertexType rhs = getVertexType(coarseGridVertices,position,dimension-1);
811
812 VertexType result = lhs;
813 if (
815 ) {
816 result = VertexType::New;
817 }
818 if (
820 ) {
821 result = VertexType::Persistent;
822 }
823 if (
825 ) {
826 result = VertexType::Persistent;
827 }
828 if (
830 ) {
831 result = VertexType::Persistent;
832 }
833 if (
835 ) {
836 result = VertexType::Delete;
837 }
838 if (
840 ) {
841 result = VertexType::Persistent;
842 }
843
844 logTraceOutWith1Argument( "getVertexType(...)", toString(result) );
845 return result;
846}
847
848
850 [[maybe_unused]] GridVertex vertices[TwoPowerD],
851 [[maybe_unused]] const SplitSpecification& splitTriggered,
852 [[maybe_unused]] const std::set<int>& splitting,
853 [[maybe_unused]] const std::set< int >& joinTriggered,
854 [[maybe_unused]] const std::set< int >& joining
855) const {
856 const int NotSetYet = -1;
857 int id = NotSetYet;
858
859 int weakId = NotSetYet;
860 dfor2(k)
861 if (
862 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
863 and
864 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)!=InvalidRank
865 ) {
866 weakId = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
867 }
868 if (
869 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
870 and
871 isVertexAdjacentToLocalSpacetree(vertices[kScalar], splitTriggered, splitting, joinTriggered, joining, true, false)
872 ) {
874 id==NotSetYet
875 or
876 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)==id,
877 id, kScalar, vertices[kScalar].toString(),
878 vertices[0].toString(), vertices[1].toString(), vertices[2].toString(), vertices[3].toString(),
879 _id
880 );
881 id = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
882 }
884 assertion1(id!=NotSetYet or not isSpacetreeNodeLocal(vertices, splitTriggered, splitting, joinTriggered, joining, false, false),id);
885
886 if (id==NotSetYet) {
887 id = weakId;
888 }
889
890 return id;
891}
892
893
896
897 int counter = 0;
898 const int normal = faceNumber % Dimensions;
899 dfore( i, 2, normal, faceNumber<Dimensions ? 0 : 1 ) {
900 int currentVertex = peano4::utils::dLinearised(i,2);
901
902 std::bitset<Dimensions> studiedEntry = TwoPowerD - currentVertex - 1;
903 studiedEntry[normal] = 0;
904 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
905 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
906 int rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
907 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
908
909 if (
910 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
911 or
912 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
913 or
914 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
915 ) {
916 rankEntry = InvalidRank;
917 };
918
919 adjacentRanksOfFace(counter) = rankEntry;
920 counter++;
921
922 studiedEntry[normal] = 1;
923 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
924 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
925 rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
926 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
927
928 if (
929 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
930 or
931 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
932 or
933 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
934 ) {
935 rankEntry = InvalidRank;
936 };
937
938 adjacentRanksOfFace(counter) = rankEntry;
939 counter++;
940 }
941
942 return adjacentRanksOfFace;
943}
#define assertion8(expr, param0, param1, param2, param3, param4, param5, param6, param7)
#define assertion3(expr, param0, param1, param2)
#define assertion1(expr, param)
#define assertion(expr)
#define TwoTimesD
Definition Globals.h:30
#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 logTraceOutWith3Arguments(methodName, argument0, argument1, argument2)
Definition Log.h:382
#define logTraceInWith3Arguments(methodName, argument0, argument1, argument2)
Definition Log.h:372
#define logTraceOutWith4Arguments(methodName, argument0, argument1, argument2, argument3)
Definition Log.h:383
#define logTraceOutWith2Arguments(methodName, argument0, argument1)
Definition Log.h:381
#define logTraceInWith1Argument(methodName, argument0)
Definition Log.h:370
#define logTraceInWith7Arguments(methodName, argument0, argument1, argument2, argument3, argument4, argument5, argument6)
Definition Log.h:376
#define logTraceInWith2Arguments(methodName, argument0, argument1)
Definition Log.h:371
#define dfor2(counter)
Shortcut For dfor(counter,2)
Definition Loop.h:911
#define dfore(counter, max, dim, value)
This is an exclusive d-dimensional for loop.
Definition Loop.h:942
#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
static CellType getCellType(GridVertex coarseGridVertices[TwoPowerD], tarch::la::Vector< Dimensions, int > positionOfCell)
You pass in the vertices and it gives you back the cell type.
int getTreeOwningSpacetreeNode(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining) const
We run over the adjacent vertices of the cell and look at each vertex's adjacency list.
static FaceType getFaceType(GridVertex coarseGridVertices[TwoPowerD], tarch::la::Vector< Dimensions, int > positionOfCell, int faceNumber)
Identify type of vertex.
tarch::la::Vector< TwoPowerD, int > getAdjacentRanksOfFace(GridVertex vertex[TwoPowerD], int faceNumber, bool useBackedUpAdjacencyInformation) const
GridTraversalEvent createGenericCellTraversalEvent(GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD], const AutomatonState &state, const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, const tarch::la::Vector< Dimensions, int > &relativePositionToFather, bool spacetreeStateIsRunning) const
bool isSpacetreeNodeLocal(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, bool splittingIsConsideredLocal, bool joiningIsConsideredLocal) const
A spacetree node as 2^d adjacent vertices.
static VertexType getVertexType(GridVertex coarseGridVertices[TwoPowerD], tarch::la::Vector< Dimensions, int > position, int dimension)
Simple recursive type analysis.
std::bitset< TwoPowerD > areVerticesLocal(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining) const
Vertices are local.
bool isVertexAdjacentToLocalSpacetree(GridVertex vertex, const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, bool splittingIsConsideredLocal, bool joiningIsConsideredLocal) const
Study the adjacency flags and do ignore hanging nodes.
GridTraversalEvent createEnterCellTraversalEvent(GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD], const AutomatonState &state, const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, const std::set< int > &hasSplit, const tarch::la::Vector< Dimensions, int > &relativePositionToFather, bool spacetreeStateIsRunning) const
Create description of an enter cell traversal.
GridTraversalEvent createPrunedEnterCellTraversalEvent(SpacetreeState spacetreeState, const GridTraversalEvent &event) const
When we fork or join, the worker's locality analysis identifies local vertices and faces.
GridTraversalEvent createLeaveCellTraversalEvent(GridVertex coarseGridVertices[TwoPowerD], GridVertex fineGridVertices[TwoPowerD], const AutomatonState &state, const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, const std::set< int > &hasSplit, const tarch::la::Vector< Dimensions, int > &relativePositionToFather, bool spacetreeStateIsRunning) const
Create description of a leave cell traversal.
std::bitset< TwoTimesD > areFacesLocal(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining) const
Identifies for the faces whether they are local or not.
std::bitset< TwoPowerD > areVerticesAdjacentToParallelDomainBoundary(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, bool calledByLeaveCell) const
A vertex is inside the domain, if all of its ids equal _id.
GridTraversalEvent createPrunedLeaveCellTraversalEvent(SpacetreeState spacetreeState, const GridTraversalEvent &event) const
std::bitset< TwoTimesD > areFacesAdjacentToParallelDomainBoundary(GridVertex vertices[TwoPowerD], const SplitSpecification &splitTriggered, const std::set< int > &splitting, const std::set< int > &joinTriggered, const std::set< int > &joining, bool calledByLeaveCell) const
static int getVertexWriteStackNumber(const AutomatonState &state, const std::bitset< Dimensions > &vertex)
static int getCellReadStackNumber(const AutomatonState &state)
static int getFaceWriteStackNumber(const AutomatonState &state, int face)
static int getFaceNumberAlongCurve(const AutomatonState &state, int logicalFaceNumber)
Faces are enumerated following the same paradigm as the vertices.
static bool isInOutStack(int number)
static int getVertexReadStackNumber(const AutomatonState &state, const std::bitset< Dimensions > &vertex)
static int getCellWriteStackNumber(const AutomatonState &state)
static int getFaceReadStackNumber(const AutomatonState &state, int face)
It is important to get the input/output stack ordering per stack type consistent among all grid entit...
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 constexpr int RankOfPeriodicBoundaryCondition
Periodic boundary conditions are technically realised as domain decomposition, i.e.
Definition Spacetree.h:54
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.
static constexpr int NoData
Can this grid entity hold data.
Log Device.
Definition Log.h:516
std::string toString(VertexType type)
Definition grid.cpp:276
bool isSpacetreeNodeLocal(GridVertex vertices[TwoPowerD], bool splittingIsConsideredLocal, bool joiningIsConsideredLocal, int id)
A spacetree node as 2^d adjacent vertices.
@ NewFromSplit
Set if this tree results from a split and if this is the first grid sweep when the former owner actua...
@ EmptyRun
Not yet a new root.
std::bitset< TwoPowerD > haveVerticesBeenRefined(GridVertex vertices[TwoPowerD])
Definition grid.cpp:267
std::bitset< TwoPowerD > willVerticesBeRefined(GridVertex vertices[TwoPowerD])
A vertex is unrefined if it is hanging.
Definition grid.cpp:258
constexpr int InvalidRank(-1)
CPUGPUMethod int dLinearised(const tarch::la::Vector< Dimensions, int > &counter, int max)
Map d-dimensional vector onto integer index.
Definition Loop.cpp:106
std::map< int, SplitInstruction > SplitSpecification
Definition grid.h:44
bool contains(const Vector< Size, Scalar > &vector, const Scalar &value)
tarch::la::Vector< Dimensions, double > getX() const
tarch::la::Vector< Dimensions, double > getH() const
void setIsFaceLocal(const std::bitset< TwoTimesD > &value)
void setX(const tarch::la::Vector< Dimensions, double > &value)
void setIsVertexLocal(const std::bitset< TwoPowerD > &value)