Peano 4
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 logTraceOutWith2Arguments( "createGenericCellTraversalEvent(...)", event.toString(), _id );
266 return event;
267}
268
270 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
271 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
272 [[maybe_unused]] const AutomatonState& state,
273 [[maybe_unused]] const SplitSpecification& splitTriggered,
274 [[maybe_unused]] const std::set<int>& splitting,
275 [[maybe_unused]] const std::set< int >& joinTriggered,
276 [[maybe_unused]] const std::set< int >& joining,
277 [[maybe_unused]] const std::set< int >& hasSplit,
278 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
279 [[maybe_unused]] bool spacetreeStateIsRunning
280) const {
281 logTraceInWith3Arguments( "createLeaveCellTraversalEvent(...)", state.toString(), _id, relativePositionToFather );
282 GridTraversalEvent event = createGenericCellTraversalEvent(coarseGridVertices, fineGridVertices, state, splitTriggered, splitting, joinTriggered, joining, relativePositionToFather, spacetreeStateIsRunning);
283
284 event.setIsVertexAdjacentToParallelDomainBoundary( areVerticesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, true) );
285 event.setIsFaceAdjacentToParallelDomainBoundary( areFacesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, true));
286
287 const std::bitset<Dimensions> coordinates = PeanoCurve::getFirstVertexIndex(state);
288 for (int i=0; i<TwoPowerD; i++) {
289 const std::bitset<Dimensions> vertexIndex( coordinates ^ std::bitset<Dimensions>(i) );
290 const int stackNumber = PeanoCurve::getVertexWriteStackNumber(state,vertexIndex);
291
292 event.setVertexDataFrom(i,vertexIndex.to_ulong());
293 switch ( fineGridVertices[vertexIndex.to_ulong()].getState() ) {
296 break;
304 event.setVertexDataTo(i,stackNumber);
305 break;
307 {
308 if ( PeanoCurve::isInOutStack(stackNumber) ) {
310 }
311 else {
312 event.setVertexDataTo(i,stackNumber);
313 }
314 }
315 break;
316 }
317
318 if (
319 PeanoCurve::isInOutStack(event.getVertexDataTo(i))
320 and
321 not event.getIsVertexLocal(vertexIndex.to_ulong())
322 ) {
323 logDebug(
324 "createLeaveCellTraversalEvent(...)",
325 "reset event entry " << i << " to no-data as we have " << event.toString()
326 << ". vertex=" << fineGridVertices[vertexIndex.to_ulong()].toString()
327 );
328 event.setVertexDataTo(i,TraversalObserver::NoData);
329 }
330 }
331
332 for (int i=0; i<2*Dimensions; i++) {
334 FaceType type = getFaceType(coarseGridVertices,relativePositionToFather,faceIndex);
335 const int stackNumber = PeanoCurve::getFaceWriteStackNumber(state,faceIndex);
336
337 event.setFaceDataFrom(i,faceIndex);
338
339 switch (type) {
342 break;
343 case FaceType::New:
345 event.setFaceDataTo(i,stackNumber);
346 break;
347 case FaceType::Delete:
348 if ( PeanoCurve::isInOutStack(stackNumber) ) {
350 }
351 else {
352 event.setFaceDataTo(i,stackNumber);
353 }
354 break;
355 }
356
357 if (
358 PeanoCurve::isInOutStack(event.getFaceDataTo(i))
359 and
360 not event.getIsFaceLocal(faceIndex)
361 ) {
362 event.setFaceDataTo(i,TraversalObserver::NoData);
363 }
364 }
365
366 {
367 CellType type = getCellType(coarseGridVertices,relativePositionToFather);
368 const int stackNumber = PeanoCurve::getCellWriteStackNumber(state);
369
370 switch (type) {
371 case CellType::New:
372 event.setCellData(stackNumber);
373 break;
375 event.setCellData(stackNumber);
376 break;
377 case CellType::Delete:
379 break;
380 }
381
382 if (
383 // always true here, but if I write it here explicitly, then it is consistent with faces/vertices
384 PeanoCurve::isInOutStack(event.getCellData())
385 and
386 not event.getIsCellLocal()
387 ) {
388 event.setCellData(TraversalObserver::NoData);
389 }
390 }
391
392 #if !defined(SharedMemoryParallelisation)
393 for (int i=0; i<TwoPowerD; i++)
394 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
395 for (int i=0; i<TwoTimesD; i++)
396 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
397 #endif
398
399 logTraceOutWith3Arguments( "createLeaveCellTraversalEvent(...)", state.toString(), event.toString(), _id );
400 return event;
401}
402
404 GridTraversalEvent result = event;
405
406 if(
407 spacetreeState==SpacetreeState::EmptyRun or
408 spacetreeState==SpacetreeState::NewFromSplit or
409 spacetreeState==SpacetreeState::Joining
410 ) {
411 result.setIsCellLocal(false);
412 result.setIsParentCellLocal(false);
413 result.setIsFaceLocal(0);
414 result.setIsVertexLocal(0);
415 }
416
417/*
418 if(
419 spacetreeState==SpacetreeState::EmptyRun or
420 spacetreeState==SpacetreeState::NewFromSplit
421 ) {
422 result.setVertexDataFrom(TraversalObserver::NoData);
423 result.setFaceDataFrom(TraversalObserver::NoData);
424 result.setCellData(TraversalObserver::NoData);
425 }
426*/
427
428 return result;
429}
430
431
433 GridTraversalEvent result = event;
434
435 if(
436 spacetreeState==SpacetreeState::EmptyRun or
437 spacetreeState==SpacetreeState::NewFromSplit or
438 spacetreeState==SpacetreeState::Joining
439 ) {
440 result.setIsCellLocal(false);
441 result.setIsParentCellLocal(false);
442 result.setIsFaceLocal(0);
443 result.setIsVertexLocal(0);
444 }
445
446 /*
447 if(
448 spacetreeState==SpacetreeState::EmptyRun or
449// spacetreeState==SpacetreeState::NewFromSplit or
450 spacetreeState==SpacetreeState::Joining
451 ) {
452 result.setVertexDataTo(TraversalObserver::NoData);
453 result.setFaceDataTo(TraversalObserver::NoData);
454 result.setCellData(TraversalObserver::NoData);
455 }
456*/
457
458 return result;
459}
460
462 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
463 [[maybe_unused]] GridVertex fineGridVertices[TwoPowerD],
464 [[maybe_unused]] const AutomatonState& state,
465 [[maybe_unused]] const SplitSpecification& splitTriggered,
466 [[maybe_unused]] const std::set<int>& splitting,
467 [[maybe_unused]] const std::set< int >& joinTriggered,
468 [[maybe_unused]] const std::set< int >& joining,
469 [[maybe_unused]] const std::set< int >& hasSplit,
470 [[maybe_unused]] const tarch::la::Vector<Dimensions,int>& relativePositionToFather,
471 [[maybe_unused]] bool spacetreeStateIsRunning
472) const {
473 logTraceInWith7Arguments( "createEnterCellTraversalEvent(...)", state.toString(), _id, relativePositionToFather, coarseGridVertices[0].toString(), coarseGridVertices[1].toString(), coarseGridVertices[2].toString(), coarseGridVertices[3].toString() );
474 GridTraversalEvent event = createGenericCellTraversalEvent(coarseGridVertices, fineGridVertices, state, splitTriggered, splitting, joinTriggered, joining, relativePositionToFather, spacetreeStateIsRunning);
475
476 event.setIsVertexAdjacentToParallelDomainBoundary( areVerticesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false) );
477 event.setIsFaceAdjacentToParallelDomainBoundary( areFacesAdjacentToParallelDomainBoundary(fineGridVertices, splitTriggered, splitting, joinTriggered, joining, false));
478
479 #if !defined(SharedMemoryParallelisation)
480 for (int i=0; i<TwoPowerD; i++)
481 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
482 for (int i=0; i<TwoTimesD; i++)
483 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
484 #endif
485
486 const std::bitset<Dimensions> coordinates = PeanoCurve::getFirstVertexIndex(state);
487 for (int i=0; i<TwoPowerD; i++) {
488 const std::bitset<Dimensions> vertexIndex( coordinates ^ std::bitset<Dimensions>(i) );
489 const int stackNumber = PeanoCurve::getVertexReadStackNumber(state,vertexIndex);
490 const int vertexPosition = vertexIndex.to_ulong();
491
492 switch ( fineGridVertices[vertexPosition].getState() ) {
495 break;
497 {
498 if ( PeanoCurve::isInOutStack(stackNumber) ) {
500 }
501 else {
502 event.setVertexDataFrom(i,stackNumber);
503 }
504 }
505 break;
513 event.setVertexDataFrom(i,stackNumber);
514 break;
515 }
516 event.setVertexDataTo(i,vertexIndex.to_ulong());
517
518 bool mayResetToNoData =
519 PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
520 and
521 not event.getIsVertexLocal(vertexPosition);
522
523 for (auto p: hasSplit) {
524 mayResetToNoData &= not tarch::la::contains( fineGridVertices[vertexPosition].getAdjacentRanks(), p );
525 }
526
527 if (mayResetToNoData) {
528 event.setVertexDataFrom(i,TraversalObserver::NoData);
529 }
530
531 logDebug(
532 "createEnterCellTraversalEvent(...)",
533 "vertex " << i << " on on tree " << _id << ": " <<
534 event.toString() << ", mayResetToNoData=" << mayResetToNoData <<
535 ", is-local=" << event.getIsVertexLocal(vertexPosition) << ", is in-out=" << PeanoCurve::isInOutStack(event.getVertexDataFrom(i))
536 << ", vertex[0]=" << fineGridVertices[0].toString()
537 << ", vertex[1]=" << fineGridVertices[1].toString()
538 << ", vertex[2]=" << fineGridVertices[2].toString()
539 << ", vertex[3]=" << fineGridVertices[3].toString()
540 << ", vertex[4]=" << fineGridVertices[4].toString()
541 << ", vertex[5]=" << fineGridVertices[5].toString()
542 << ", vertex[6]=" << fineGridVertices[6].toString()
543 << ", vertex[7]=" << fineGridVertices[7].toString()
544 );
545 }
546
547 for (int i=0; i<2*Dimensions; i++) {
549 FaceType type = getFaceType(coarseGridVertices,relativePositionToFather,faceIndex);
550 const int stackNumber = PeanoCurve::getFaceReadStackNumber(state,faceIndex);
551
552 switch (type) {
553 case FaceType::New:
554 {
555 if ( PeanoCurve::isInOutStack(stackNumber) ) {
557 }
558 else {
559 event.setFaceDataFrom(i,stackNumber);
560 }
561 }
562 break;
565 break;
567 case FaceType::Delete:
568 event.setFaceDataFrom(i,stackNumber);
569 break;
570 }
571 event.setFaceDataTo(i,faceIndex);
572
573 bool mayResetToNoData =
574 PeanoCurve::isInOutStack(event.getFaceDataFrom(i))
575 and
576 not event.getIsFaceLocal(faceIndex);
577
578 for (auto p: hasSplit) {
579 mayResetToNoData &= not tarch::la::contains( getAdjacentRanksOfFace(fineGridVertices, faceIndex, false), p );
580 }
581
582 if (mayResetToNoData) {
583 event.setFaceDataFrom(i,TraversalObserver::NoData);
584 }
585 }
586
587 {
588 CellType type = getCellType(coarseGridVertices,relativePositionToFather);
589 const int stackNumber = PeanoCurve::getCellReadStackNumber(state);
590 switch (type) {
591 case CellType::New:
593 break;
595 event.setCellData(stackNumber);
596 break;
597 case CellType::Delete:
598 event.setCellData(stackNumber);
599 break;
600 }
601 }
602
603 bool mayResetToNoData =
604 // always true here, but if I write it here explicitly, then it is consistent with faces/vertices
605 PeanoCurve::isInOutStack(event.getCellData())
606 and
607 not event.getIsCellLocal();
608
609 for (auto p: hasSplit) {
610 mayResetToNoData &= getTreeOwningSpacetreeNode(fineGridVertices, splitTriggered, splitting, joinTriggered, joining)!=p;
611 }
612
613 if (mayResetToNoData) {
614 event.setCellData(TraversalObserver::NoData);
615 }
616
617 #if !defined(SharedMemoryParallelisation)
618 for (int i=0; i<TwoPowerD; i++)
619 assertion1( event.getIsVertexLocal(i) or not event.getIsVertexAdjacentToParallelDomainBoundary(i), event.toString() );
620 for (int i=0; i<TwoTimesD; i++)
621 assertion1( event.getIsFaceLocal(i) or not event.getIsFaceAdjacentToParallelDomainBoundary(i), event.toString() );
622 #endif
623
624 logTraceOutWith3Arguments( "createEnterCellTraversalEvent(...)", state.toString(), event.toString(), _id );
625 return event;
626}
627
629 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
630 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell,
631 [[maybe_unused]] int faceNumber
632) {
633 logTraceInWith1Argument( "getFaceType(...)", faceNumber );
634
635 bool allVerticesAreHanging = true;
636 bool allVerticesAreDeleteOrHanging = true;
637 bool allVerticesAreNewOrHanging = true;
638
639 const int normal = faceNumber % Dimensions;
640 for (int i=0; i<TwoPowerD; i++) {
641 std::bitset<Dimensions> studiedVertex = i;
642 studiedVertex.set(normal,faceNumber>=Dimensions);
643 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(studiedVertex) ) ) {
645 break;
646 case VertexType::New:
647 allVerticesAreDeleteOrHanging = false;
648 allVerticesAreHanging = false;
649 break;
651 allVerticesAreHanging = false;
652 allVerticesAreDeleteOrHanging = false;
653 allVerticesAreNewOrHanging = false;
654 break;
656 allVerticesAreHanging = false;
657 allVerticesAreNewOrHanging = false;
658 break;
659 }
660 }
661
663 if ( allVerticesAreHanging ) {
664 result = FaceType::Hanging;
665 }
666 else if ( allVerticesAreNewOrHanging ) {
667 result = FaceType::New;
668 }
669 else if ( allVerticesAreDeleteOrHanging ) {
670 result = FaceType::Delete;
671 }
672
673 logTraceOutWith4Arguments( "getFaceType(...)", toString(result), allVerticesAreDeleteOrHanging, allVerticesAreNewOrHanging, allVerticesAreHanging );
674 return result;
675}
676
678 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
679 [[maybe_unused]] tarch::la::Vector<Dimensions,int> positionOfCell
680) {
681 bool allVerticesAreDelete = true;
682 bool allVerticesAreNew = true;
683
684 for (int i=0; i<TwoPowerD; i++) {
685 std::bitset<Dimensions> vectorPosition = i;
686 switch ( getVertexType( coarseGridVertices, positionOfCell + tarch::la::Vector<Dimensions,int>(vectorPosition) )) {
688 break;
690 allVerticesAreDelete = false;
691 allVerticesAreNew = false;
692 break;
693 case VertexType::New:
694 allVerticesAreDelete = false;
695 break;
697 allVerticesAreNew = false;
698 break;
699 }
700 }
701
702 assertion( not (allVerticesAreDelete and allVerticesAreNew) );
703
704 if (allVerticesAreDelete) {
705 logDebug( "getCellType(...)", "delete cell" );
706 return CellType::Delete;
707 }
708 else if (allVerticesAreNew) {
709 logDebug( "getCellType(...)", "create new cell" );
710 return CellType::New;
711 }
712 else {
713 logDebug( "getCellType(...)", "keep cell" );
715 }
716}
717
719 [[maybe_unused]] GridVertex coarseGridVertices[TwoPowerD],
720 [[maybe_unused]] tarch::la::Vector<Dimensions,int> position,
721 [[maybe_unused]] int dimension
722) {
723 if (dimension<0) {
724 switch (coarseGridVertices[ peano4::utils::dLinearised(position,2) ].getState()) {
726 return VertexType::Hanging;
730 return VertexType::Hanging;
734 return VertexType::Hanging;
736 return VertexType::New;
740 return VertexType::Delete;
741 }
742 assertion3(false, peano4::utils::dLinearised(position,2), position, coarseGridVertices[ peano4::utils::dLinearised(position,2) ].toString() );
743 }
744 else if ( position(dimension)==0 ) {
745 position(dimension)=0;
746 return getVertexType(coarseGridVertices,position,dimension-1);
747 }
748 else if ( position(dimension)==3 ) {
749 position(dimension)=1;
750 return getVertexType(coarseGridVertices,position,dimension-1);
751 }
752
753 logTraceInWith2Arguments( "getVertexType(...)", position, dimension );
754 position(dimension)=0;
755 peano4::grid::VertexType lhs = getVertexType(coarseGridVertices,position,dimension-1);
756
757 position(dimension)=1;
758 peano4::grid::VertexType rhs = getVertexType(coarseGridVertices,position,dimension-1);
759
760 VertexType result = lhs;
761 if (
763 ) {
764 result = VertexType::New;
765 }
766 if (
768 ) {
769 result = VertexType::Persistent;
770 }
771 if (
773 ) {
774 result = VertexType::Persistent;
775 }
776 if (
778 ) {
779 result = VertexType::Persistent;
780 }
781 if (
783 ) {
784 result = VertexType::Delete;
785 }
786 if (
788 ) {
789 result = VertexType::Persistent;
790 }
791
792 logTraceOutWith1Argument( "getVertexType(...)", toString(result) );
793 return result;
794}
795
797 [[maybe_unused]] GridVertex vertices[TwoPowerD],
798 [[maybe_unused]] const SplitSpecification& splitTriggered,
799 [[maybe_unused]] const std::set<int>& splitting,
800 [[maybe_unused]] const std::set< int >& joinTriggered,
801 [[maybe_unused]] const std::set< int >& joining
802) const {
803 const int NotSetYet = -1;
804 int id = NotSetYet;
805
806 int weakId = NotSetYet;
807 dfor2(k)
808 if (
809 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
810 and
811 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)!=InvalidRank
812 ) {
813 weakId = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
814 }
815 if (
816 vertices[kScalar].getState()!=GridVertex::State::HangingVertex
817 and
818 isVertexAdjacentToLocalSpacetree(vertices[kScalar], splitTriggered, splitting, joinTriggered, joining, true, false)
819 ) {
821 id==NotSetYet
822 or
823 vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1)==id,
824 id, kScalar, vertices[kScalar].toString(),
825 vertices[0].toString(), vertices[1].toString(), vertices[2].toString(), vertices[3].toString(),
826 _id
827 );
828 id = vertices[kScalar].getAdjacentRanks(TwoPowerD-kScalar-1);
829 }
831 assertion1(id!=NotSetYet or not isSpacetreeNodeLocal(vertices, splitTriggered, splitting, joinTriggered, joining, false, false),id);
832
833 if (id==NotSetYet) {
834 id = weakId;
835 }
836
837 return id;
838}
839
842
843 int counter = 0;
844 const int normal = faceNumber % Dimensions;
845 dfore( i, 2, normal, faceNumber<Dimensions ? 0 : 1 ) {
846 int currentVertex = peano4::utils::dLinearised(i,2);
847
848 std::bitset<Dimensions> studiedEntry = TwoPowerD - currentVertex - 1;
849 studiedEntry[normal] = 0;
850 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
851 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
852 int rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
853 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
854
855 if (
856 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
857 or
858 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
859 or
860 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
861 ) {
862 rankEntry = InvalidRank;
863 };
864
865 adjacentRanksOfFace(counter) = rankEntry;
866 counter++;
867
868 studiedEntry[normal] = 1;
869 assertion3(studiedEntry.to_ullong()>=0, studiedEntry,currentVertex,i);
870 assertion3(studiedEntry.to_ullong()<TwoPowerD, studiedEntry,currentVertex,i);
871 rankEntry = calledByReceivingProcess ? fineGridVertices[currentVertex].getBackupOfAdjacentRanks(studiedEntry.to_ullong())
872 : fineGridVertices[currentVertex].getAdjacentRanks(studiedEntry.to_ullong());
873
874 if (
875 ( fineGridVertices[currentVertex].getState()==GridVertex::State::HangingVertex )
876 or
877 ( calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::New )
878 or
879 ( not calledByReceivingProcess and fineGridVertices[currentVertex].getState()==GridVertex::State::Delete )
880 ) {
881 rankEntry = InvalidRank;
882 };
883
884 adjacentRanksOfFace(counter) = rankEntry;
885 counter++;
886 }
887
888 return adjacentRanksOfFace;
889}
#define assertion8(expr, param0, param1, param2, param3, param4, param5, param6, param7)
#define assertion3(expr, param0, param1, param2)
#define assertion1(expr, param)
#define assertion(expr)
And from this we can write down f$ nabla phi_i nabla phi_i dx but since we are constructing matrix let s investigate the f$ j
we integrate over each cell and then take the sum across each of the cells We also consider the terms that enter the f$ k
#define TwoTimesD
Definition Globals.h:29
#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:906
#define dfore(counter, max, dim, value)
This is an exclusive d-dimensional for loop.
Definition Loop.h:937
#define enddforx
I prefer to use this macro for dforx instead of a closing bracket as many syntax parser fail otherwis...
Definition Loop.h:928
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:277
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:268
std::bitset< TwoPowerD > willVerticesBeRefined(GridVertex vertices[TwoPowerD])
A vertex is unrefined if it is hanging.
Definition grid.cpp:259
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)