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
416 GridTraversalEvent result = event;
417
418 if(
419 spacetreeState==SpacetreeState::EmptyRun or
420 spacetreeState==SpacetreeState::NewFromSplit or
421 spacetreeState==SpacetreeState::Joining
422 ) {
423 result.setIsCellLocal(false);
424 result.setIsParentCellLocal(false);
425 result.setIsFaceLocal(0);
426 result.setIsVertexLocal(0);
427 }
428
429/*
430 if(
431 spacetreeState==SpacetreeState::EmptyRun or
432 spacetreeState==SpacetreeState::NewFromSplit
433 ) {
434 result.setVertexDataFrom(TraversalObserver::NoData);
435 result.setFaceDataFrom(TraversalObserver::NoData);
436 result.setCellData(TraversalObserver::NoData);
437 }
438*/
439
440 return result;
441}
442
443
445 GridTraversalEvent result = event;
446
447 if(
448 spacetreeState==SpacetreeState::EmptyRun or
449 spacetreeState==SpacetreeState::NewFromSplit or
450 spacetreeState==SpacetreeState::Joining
451 ) {
452 result.setIsCellLocal(false);
453 result.setIsParentCellLocal(false);
454 result.setIsFaceLocal(0);
455 result.setIsVertexLocal(0);
456 }
457
458 /*
459 if(
460 spacetreeState==SpacetreeState::EmptyRun or
461// spacetreeState==SpacetreeState::NewFromSplit or
462 spacetreeState==SpacetreeState::Joining
463 ) {
464 result.setVertexDataTo(TraversalObserver::NoData);
465 result.setFaceDataTo(TraversalObserver::NoData);
466 result.setCellData(TraversalObserver::NoData);
467 }
468*/
469
470 return result;
471}
472
474 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
475 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
476 [[maybe_unused]] const AutomatonState& state,
477 [[maybe_unused]] const SplitSpecification& splitTriggered,
478 [[maybe_unused]] const std::set<int>& splitting,
479 [[maybe_unused]] const std::set< int >& joinTriggered,
480 [[maybe_unused]] const std::set< int >& joining,
481 [[maybe_unused]] const std::set< int >& hasSplit,
482 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
483 [[maybe_unused]] bool spacetreeStateIsRunning
484) const {
485 logTraceInWith7Arguments( "createEnterCellTraversalEvent(...)", state.toString(), _id, relativePositionToFather, coarseGridVertices[0].toString(), coarseGridVertices[1].toString(), coarseGridVertices[2].toString(), coarseGridVertices[3].toString() );
486 GridTraversalEvent event = createGenericCellTraversalEvent(coarseGridVertices, fineGridVertices, state, splitTriggered, splitting, joinTriggered, joining, relativePositionToFather, spacetreeStateIsRunning);
487
488 event.setIsVertexAdjacentToParallelDomainBoundary( areVerticesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false) );
489 event.setIsFaceAdjacentToParallelDomainBoundary( areFacesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false));
490
491 #if !defined(SharedMemoryParallelisation)
492 for (int i=0; i<TwoPowerD; i++)
493 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
494 for (int i=0; i<TwoTimesD; i++)
495 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
496 #endif
497
498 const std::bitset<Dimensions> coordinates = PeanoCurve::getFirstVertexIndex(state);
499 for (int i=0; i<TwoPowerD; i++) {
500 const std::bitset<Dimensions> vertexIndex( coordinates ^ std::bitset<Dimensions>(i) );
501 const int stackNumber = PeanoCurve::getVertexReadStackNumber(state,vertexIndex);
502 const int vertexPosition = vertexIndex.to_ulong();
503
504 switch ( fineGridVertices[vertexPosition].getState() ) {
507 break;
509 {
510 if ( PeanoCurve::isInOutStack(stackNumber) ) {
512 }
513 else {
514 event.setVertexDataFrom(i,stackNumber);
515 }
516 }
517 break;
525 event.setVertexDataFrom(i,stackNumber);
526 break;
527 }
528 event.setVertexDataTo(i,vertexIndex.to_ulong());
529
530 bool mayResetToNoData =
531 PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
532 and
533 not event.getIsVertexLocal(vertexPosition);
534
535 for (auto p: hasSplit) {
536 mayResetToNoData &= not tarch::la::contains( fineGridVertices[vertexPosition].getAdjacentRanks(), p );
537 }
538
539 if (mayResetToNoData) {
540 event.setVertexDataFrom(i,TraversalObserver::NoData);
541 }
542
543 logDebug(
544 "createEnterCellTraversalEvent(...)",
545 "vertex " << i << " on on tree " << _id << ": " <<
546 event.toString() << ", mayResetToNoData=" << mayResetToNoData <<
547 ", is-local=" << event.getIsVertexLocal(vertexPosition) << ", is in-out=" << PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
548 << ", vertex[0]=" << fineGridVertices[0].toString()
549 << ", vertex[1]=" << fineGridVertices[1].toString()
550 << ", vertex[2]=" << fineGridVertices[2].toString()
551 << ", vertex[3]=" << fineGridVertices[3].toString()
552 << ", vertex[4]=" << fineGridVertices[4].toString()
553 << ", vertex[5]=" << fineGridVertices[5].toString()
554 << ", vertex[6]=" << fineGridVertices[6].toString()
555 << ", vertex[7]=" << fineGridVertices[7].toString()
556 );
557 }
558
559 for (int i=0; i<2*Dimensions; i++) {
561 FaceType type = getFaceType(coarseGridVertices,relativePositionToFather,faceIndex);
562 const int stackNumber = PeanoCurve::getFaceReadStackNumber(state,faceIndex);
563
564 switch (type) {
565 case FaceType::New:
566 {
567 if ( PeanoCurve::isInOutStack(stackNumber) ) {
569 }
570 else {
571 event.setFaceDataFrom(i,stackNumber);
572 }
573 }
574 break;
577 break;
579 case FaceType::Delete:
580 event.setFaceDataFrom(i,stackNumber);
581 break;
582 }
583 event.setFaceDataTo(i,faceIndex);
584
585 bool mayResetToNoData =
586 PeanoCurve::isInOutStack(event.getFaceDataFrom(i))
587 and
588 not event.getIsFaceLocal(faceIndex);
589
590 for (auto p: hasSplit) {
591 mayResetToNoData &= not tarch::la::contains( getAdjacentRanksOfFace(fineGridVertices, faceIndex, false), p );
592 }
593
594 if (mayResetToNoData) {
595 event.setFaceDataFrom(i,TraversalObserver::NoData);
596 }
597 }
598
599 {
600 CellType type = getCellType(coarseGridVertices,relativePositionToFather);
601 const int stackNumber = PeanoCurve::getCellReadStackNumber(state);
602 switch (type) {
603 case CellType::New:
605 break;
607 event.setCellData(stackNumber);
608 break;
609 case CellType::Delete:
610 event.setCellData(stackNumber);
611 break;
612 }
613 }
614
615 bool mayResetToNoData =
616 // always true here, but if I write it here explicitly, then it is consistent with faces/vertices
617 PeanoCurve::isInOutStack(event.getCellData())
618 and
619 not event.getIsCellLocal();
620
621 for (auto p: hasSplit) {
622 mayResetToNoData &= getTreeOwningSpacetreeNode(fineGridVertices, splitTriggered, splitting, joinTriggered, joining)!=p;
623 }
624
625 if (mayResetToNoData) {
626 event.setCellData(TraversalObserver::NoData);
627 }
628
629 #if !defined(SharedMemoryParallelisation)
630 for (int i=0; i<TwoPowerD; i++)
631 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
632 for (int i=0; i<TwoTimesD; i++)
633 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
634 #endif
635
636 logTraceOutWith3Arguments( "createEnterCellTraversalEvent(...)", state.toString(), event.toString(), _id );
637 return event;
638}
639
641 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
642 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell,
643 [[maybe_unused]] int faceNumber
644) {
645 logTraceInWith1Argument( "getFaceType(...)", faceNumber );
646
647 bool allVerticesAreHanging = true;
648 bool allVerticesAreDeleteOrHanging = true;
649 bool allVerticesAreNewOrHanging = true;
650
651 const int normal = faceNumber % Dimensions;
652 for (int i=0; i<TwoPowerD; i++) {
653 std::bitset<Dimensions> studiedVertex = i;
654 studiedVertex.set(normal,faceNumber>=Dimensions);
655 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(studiedVertex) ) ) {
657 break;
658 case VertexType::New:
659 allVerticesAreDeleteOrHanging = false;
660 allVerticesAreHanging = false;
661 break;
663 allVerticesAreHanging = false;
664 allVerticesAreDeleteOrHanging = false;
665 allVerticesAreNewOrHanging = false;
666 break;
668 allVerticesAreHanging = false;
669 allVerticesAreNewOrHanging = false;
670 break;
671 }
672 }
673
675 if ( allVerticesAreHanging ) {
676 result = FaceType::Hanging;
677 }
678 else if ( allVerticesAreNewOrHanging ) {
679 result = FaceType::New;
680 }
681 else if ( allVerticesAreDeleteOrHanging ) {
682 result = FaceType::Delete;
683 }
684
685 logTraceOutWith4Arguments( "getFaceType(...)", toString(result), allVerticesAreDeleteOrHanging, allVerticesAreNewOrHanging, allVerticesAreHanging );
686 return result;
687}
688
690 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
691 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell
692) {
693 bool allVerticesAreDelete = true;
694 bool allVerticesAreNew = true;
695
696 for (int i=0; i<TwoPowerD; i++) {
697 std::bitset<Dimensions> vectorPosition = i;
698 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(vectorPosition) )) {
700 break;
702 allVerticesAreDelete = false;
703 allVerticesAreNew = false;
704 break;
705 case VertexType::New:
706 allVerticesAreDelete = false;
707 break;
709 allVerticesAreNew = false;
710 break;
711 }
712 }
713
714 assertion( not (allVerticesAreDelete and allVerticesAreNew) );
715
716 if (allVerticesAreDelete) {
717 logDebug( "getCellType(...)", "delete cell" );
718 return CellType::Delete;
719 }
720 else if (allVerticesAreNew) {
721 logDebug( "getCellType(...)", "create new cell" );
722 return CellType::New;
723 }
724 else {
725 logDebug( "getCellType(...)", "keep cell" );
727 }
728}
729
731 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
732 [[maybe_unused]] tarch::la::Vector<Dimensions,int> position,
733 [[maybe_unused]] int dimension
734) {
735 if (dimension<0) {
736 switch (coarseGridVertices[ peano4::utils::dLinearised(position,2) ].getState()) {
738 return VertexType::Hanging;
742 return VertexType::Hanging;
746 return VertexType::Hanging;
748 return VertexType::New;
752 return VertexType::Delete;
753 }
754 assertion3(false, peano4::utils::dLinearised(position,2), position, coarseGridVertices[ peano4::utils::dLinearised(position,2) ].toString() );
755 }
756 else if ( position(dimension)==0 ) {
757 position(dimension)=0;
758 return getVertexType(coarseGridVertices,position,dimension-1);
759 }
760 else if ( position(dimension)==3 ) {
761 position(dimension)=1;
762 return getVertexType(coarseGridVertices,position,dimension-1);
763 }
764
765 logTraceInWith2Arguments( "getVertexType(...)", position, dimension );
766 position(dimension)=0;
767 peano4::grid::VertexType lhs = getVertexType(coarseGridVertices,position,dimension-1);
768
769 position(dimension)=1;
770 peano4::grid::VertexType rhs = getVertexType(coarseGridVertices,position,dimension-1);
771
772 VertexType result = lhs;
773 if (
775 ) {
776 result = VertexType::New;
777 }
778 if (
780 ) {
781 result = VertexType::Persistent;
782 }
783 if (
785 ) {
786 result = VertexType::Persistent;
787 }
788 if (
790 ) {
791 result = VertexType::Persistent;
792 }
793 if (
795 ) {
796 result = VertexType::Delete;
797 }
798 if (
800 ) {
801 result = VertexType::Persistent;
802 }
803
804 logTraceOutWith1Argument( "getVertexType(...)", toString(result) );
805 return result;
806}
807
809 [[maybe_unused]] GridVertex vertices[TwoPowerD],
810 [[maybe_unused]] const SplitSpecification& splitTriggered,
811 [[maybe_unused]] const std::set<int>& splitting,
812 [[maybe_unused]] const std::set< int >& joinTriggered,
813 [[maybe_unused]] const std::set< int >& joining
814) const {
815 const int NotSetYet = -1;
816 int id = NotSetYet;
817
818 int weakId = NotSetYet;
819 dfor2(k)
820 if (
821 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
822 and
823 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)!=InvalidRank
824 ) {
825 weakId = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
826 }
827 if (
828 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
829 and
830 isVertexAdjacentToLocalSpacetree(vertices[kScalar], splitTriggered, splitting, joinTriggered, joining, true, false)
831 ) {
833 id==NotSetYet
834 or
835 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)==id,
836 id, kScalar, vertices[kScalar].toString(),
837 vertices[0].toString(), vertices[1].toString(), vertices[2].toString(), vertices[3].toString(),
838 _id
839 );
840 id = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
841 }
843 assertion1(id!=NotSetYet or not isSpacetreeNodeLocal(vertices, splitTriggered, splitting, joinTriggered, joining, false, false),id);
844
845 if (id==NotSetYet) {
846 id = weakId;
847 }
848
849 return id;
850}
851
854
855 int counter = 0;
856 const int normal = faceNumber % Dimensions;
857 dfore( i, 2, normal, faceNumber<Dimensions ? 0 : 1 ) {
858 int currentVertex = peano4::utils::dLinearised(i,2);
859
860 std::bitset<Dimensions> studiedEntry = TwoPowerD - currentVertex - 1;
861 studiedEntry[normal] = 0;
862 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
863 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
864 int rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
865 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
866
867 if (
868 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
869 or
870 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
871 or
872 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
873 ) {
874 rankEntry = InvalidRank;
875 };
876
877 adjacentRanksOfFace(counter) = rankEntry;
878 counter++;
879
880 studiedEntry[normal] = 1;
881 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
882 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
883 rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
884 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
885
886 if (
887 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
888 or
889 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
890 or
891 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
892 ) {
893 rankEntry = InvalidRank;
894 };
895
896 adjacentRanksOfFace(counter) = rankEntry;
897 counter++;
898 }
899
900 return adjacentRanksOfFace;
901}
#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.
static VertexType getVertexType(GridVertex coarseGridVertices[TwoPowerD], tarch::la::Vector< Dimensions, int > position, int dimension=Dimensions-1)
Simple recursive type analysis.
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.
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)