LoAdSG
sparseGrid.h
1/**********************************************************************************
2* Author: Christoph Pflaum, Riccarda Scherner-Griesshammer
3 * Department Informatik Lehrstuhl 10 - Systemsimulation
4 * Friedrich-Alexander Universität Erlangen-Nürnberg
5 *
6*********************************************/
7
8#ifndef SPARSEGRID_H
9#define SPARSEGRID_H
10
11#include "../primes/prime.h"
12#include "../indices/index.h"
13#include "../iterator/RectangularIterator.h"
14#include "omp.h"
15
16#include <iostream>
17#include <fstream>
18#include "depth.h"
19#include "multiDepthHashGrid.h"
20
21class Coordinate;
22class VectorSparseG;
23class MultiLevelVector;
25
26
27
28class Process {
29
30 friend VectorSparseG;
31 friend MultiLevelVector;
32
33private:
34 int rank;
35 bool all;
36 int myrank;
37public:
38
39 Process(int *my_rank, int rank_) {
40 myrank = *my_rank;
41 rank = rank_;
42 all = false;
43 }
44
45 Process() { all = true; };
46
47 Process(int *my_rank) { myrank = *my_rank, all = true; };
48
49 void runProcess(int rank_) {
50 rank = rank_;
51 all = false;
52 }
53
54 void runALL() { all = true; };
55
56 void setMyRank(int *my_rank) { myrank = *my_rank; }
57
58 int getMyRank() { return myrank; }
59
60 int getRank() { return rank; }
61
62
63};
64
65
66
67
68template <class A> struct ExprSparseG;
69
70enum type_sparseGrid { sparseGrid_withBoundary, sparseGrid_zeroBoundary };
71
72
87
88
89
90
91 friend VectorSparseG;
92 friend MultiLevelVector;
93
94
95
97
98 //defines a non-member function and makes it a friend of this class
99 template<class A, class B>
100 friend double product(const ExprSparseG<A> &a, const ExprSparseG<B> &b);
101
102 template<class A>
103 friend double L_infty(const ExprSparseG<A> &a);
104
105public:
107 void printCoordinates();
108
110 void Print_gnu(string name);
111
112 void PrintSlice_gnu(string name);
113
114 void PrintSlice2_gnu(string name);
115
116 void PrintSlice3_gnu(string name);
117
118 void Print_vtk(std::ostream &Datei);
119
121 void PrintActiveHanging(int level);
122
124 void PrintGridIndices(int level, IndexDimension* Indices, int numberofindices);
125
126
127 int getMaxDepth(int d);
128
129 int getMaxDepth(int d, IndexDimension Index);
130
131 inline bool checkMultiDimFiveStencil(IndexDimension Index);
132
133 virtual inline bool AddPoint(IndexDimension I);
134
141 inline bool occupied(unsigned long &indexOfData, IndexDimension I);
142
143 inline bool occupied2(unsigned long &indexOfData, IndexDimension I);
144
145
146 inline bool occupied(unsigned long &indexOfData, IndexDimension I, bool active);
147
148 dataInteger *getSecondTable() { return secondTable; };
149
150 dataInteger *getPrimeTable() { return primeTable; };
151
152 bool *getActiveTable() { return isActiveNodeTable; };
153
154
155
156
157
158 unsigned long getMaximalOccupiedSecondTable() { return maximalOccupiedSecondTable; };
159
160
161 unsigned long getLengthSecondTable() { return secondTableLength; }
162
163
168 inline IndexDimension getIndexOfTable(unsigned long i);
169
170 inline IndexDimension getSupportIMin(unsigned long i);
171
172 inline IndexDimension getSupportIMax(unsigned long i);
173
174
175
179 inline unsigned long hash(IndexDimension index);
180
181 inline unsigned long hashWithDepth(IndexDimension index, Depth T);
182
183
184 Process *mpi;
185
186 bool WorkOnHangingNodes;
187
188
189 inline bool workonindex(unsigned long i) {
190 if (WorkOnHangingNodes || ((!WorkOnHangingNodes) && isActiveNodeTable[i]))
191 return true;
192 return false;
193 }
194
195 unsigned long getPrimeTableLength() const { return primeTableLength; };;;
196
197
198 MultiDepthHashGrid* getMultiDepthHashGrid() {return multiDepthHashGrid;}
199
200 int getKey(){
201 return grid_key;
202 }
203
204 int getLevel(){
205 return max_LOne-DimensionSparseGrid+1;
206 }
207
208 int getMaxLOne(){
209 return max_LOne;
210 }
211
212
213
214
215
216
217protected:
218 friend MultiDepthHashGrid;
219 MultiDepthHashGrid *multiDepthHashGrid;
220
223
224 unsigned long primeTableLength;
225 unsigned long secondTableLength;
226 unsigned long minimalEmptySecondTable;
227 unsigned long maximalOccupiedSecondTable;
228
229
230 int *depthTable;
231 dataInteger *primeTable;
232 dataInteger *secondTable;
234
235
236 indexInteger *indicesSecondTable;
237 indexInteger *indicesSupportMin;
238 indexInteger *indicesSupportMax;
239
240
244 unsigned long getFreeSpaceNumberInSecondTable();
245
246
247 void setIndexInTable(const IndexDimension I, unsigned long iSetz);
248
249 int grid_key;
250
251 int max_LOne=0;
252 int max_level=0;
253
254
255
256};
257
258/***
259 * Gitter mit Randpunkten
260 ***/
261
278 public:
283
284
285 void copy(AdaptiveSparseGrid& newgrid);
286
287 void copy_inner(AdaptiveSparseGrid& newgrid);
288
289 void add_outer(AdaptiveSparseGrid& newgrid);
290
291 void add_RecursiveSonsBoundary(AdaptiveSparseGrid& newgrid);
292
293 void clear();
294
295
339 bool AddPoint(const IndexDimension I);
340
341 bool AddPoint(const IndexDimension I, bool hangingNode);
342
343 void AddRecursiveSonsOfPoint(IndexDimension I, int level);
344
345
346
347
348
349 int getDOFS();
350
351 int getInnerDOFS();
352
353 int getHangingNodes();
354
355 virtual void completeNeumannGrid();
356
357 virtual void completeDirichletGrid();
358
359 virtual void completeDirichletGrid_NEU();
360
361
362
363
364 inline bool operator==(AdaptiveSparseGrid& second_grid){
365 if(grid_key == second_grid.getKey())
366 return true;
367 else return false;
368 }
369 void AddPointsOfDepth(Depth T);
370 void completeGridWithoutBoundary();
371 std::vector<IndexDimension> pointsToAdd;
372private:
373
374 void completeGrid();
375
376
380
381 void CompleteToLocalTensorProductGrid_NEU(ListOfDepthOrderedSubgrids* listOfDepthOrderedSubgrids);
382 void addHangingNodes();
383
384
385
386
387};
388
389
391// inline functions
393
394
395unsigned long AdaptiveSparseGrid_Base::hash(IndexDimension index) {
396 Depth T(index);
397 unsigned long value = index.getIndex(0);
398 for (int d = 1; d < DimensionSparseGrid; ++d) {
399 value = value + index.getIndex(d) * PrimeNumbers::getPrimeForHash(d);
400 }
401
402 value = value + T.at(0) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid);
403 for (int d = 1; d < DimensionSparseGrid; d++)
404 value = value + T.at(d) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid + d);
405
406
407 return value % primeTableLength;
408}
409
410unsigned long AdaptiveSparseGrid_Base::hashWithDepth(IndexDimension index, Depth T) {
411
412 unsigned long value = index.getIndex(0);
413 for (int d = 1; d < DimensionSparseGrid; ++d) {
414 value = value + index.getIndex(d) * PrimeNumbers::getPrimeForHash(d);
415 }
416
417 value = value + T.at(0) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid);
418 for (int d = 1; d < DimensionSparseGrid; d++)
419 value = value + T.at(d) * PrimeNumbers::getPrimeForHash(DimensionSparseGrid + d);
420
421
422 return value % primeTableLength;
423}
424
425
426
427bool AdaptiveSparseGrid_Base::AddPoint(IndexDimension I) {
428 unsigned long indArray = hash(I);
429 unsigned long i = primeTable[indArray];
430 if(i == 0) { // in prime table is something free;
431 unsigned long freeSpace = getFreeSpaceNumberInSecondTable();
432 primeTable[indArray] = freeSpace + 1;
433 isActiveNodeTable[freeSpace]=true;
434 setIndexInTable(I,freeSpace);
435 return true;
436 }
437 else { // anaylse what is going on
438 i = i-1; // shift since data are stored with shift
439 if(I == getIndexOfTable(i)){
440 // data is already stored but we still want all these nodes to be active!?
441 isActiveNodeTable[i]=true;
442 return false;
443 } else { // search in second table;
444 unsigned long iNext = secondTable[i];
445 while(iNext > 1) {
446 i = iNext - 2;
447 if(I == getIndexOfTable(i)){
448 isActiveNodeTable[i]=true;
449 return false;
450 }
451 iNext = secondTable[i];
452 }
453 myAssert(iNext==1);
454 unsigned long freeSpace = getFreeSpaceNumberInSecondTable();
455 // shift, since we dont want to store 0 or 1 by accident, i.e. freespace = 1, but 1 means no further link
456 secondTable[i] = freeSpace + 2;
457 isActiveNodeTable[freeSpace]=true;
458 setIndexInTable(I,freeSpace);
459 return true;
460 }
461 }
462}
463
464
465bool AdaptiveSparseGrid_Base::occupied(unsigned long& indexOfData, IndexDimension I) {
466
467/*
468 Depth T(I);
469 SingleDepthHashGrid *depthGrid = this->getMultiDepthHashGrid()->tryGetGridForDepth(T);
470 if(depthGrid){
471 unsigned long j;
472 if (depthGrid->occupied(j, I)) {
473 indexOfData = j;
474 return true;
475 } else {
476 return false;
477 }
478 }
479 return false;
480
481*/
482
483
484 unsigned long indArray = hash(I);
485 unsigned long i = primeTable[indArray];
486 if(i == 0) { // in prime table is something free;
487 return false;
488 }
489 else { // anaylse what is going on
490 i = i-1; // shift since data are stored with shift
491 if(I == getIndexOfTable(i)) {
492 indexOfData = i;
493 return true;
494 }
495 else { // search in second table;
496 unsigned long iNext = secondTable[i];
497 while (iNext > 1) {
498 i = iNext - 2;
499 if (I == getIndexOfTable(i)) {
500 indexOfData = i;
501 return true;
502 }
503 iNext = secondTable[i];
504 }
505 return false;
506 }
507 }
508}
509
510
511
512
513bool AdaptiveSparseGrid_Base::occupied(unsigned long& indexOfData, IndexDimension I, bool active) {
514 unsigned long indArray = hash(I);
515 unsigned long i = primeTable[indArray];
516 if(i == 0) { // in prime table is something free;
517 return false;
518 }
519 else { // anaylse what is going on
520 i = i-1; // shift since data are stored with shift
521 if(I == getIndexOfTable(i)) {
522 indexOfData = i;
523 active = isActiveNodeTable[i];
524 return true;
525 }
526 else { // search in second table;
527 unsigned long iNext = secondTable[i];
528 while(iNext > 1) {
529 i = iNext - 2;
530 if(I == getIndexOfTable(i)) {
531 indexOfData = i;
532 active = isActiveNodeTable[i];
533 return true;
534 }
535 iNext = secondTable[i];
536 }
537 return false;
538 }
539 }
540}
541
542
544
545bool AdaptiveSparseGrid_Base::checkMultiDimFiveStencil(IndexDimension Index) {
546 unsigned long j;
547 occupied(j,Index);
548 return isActiveNodeTable[j];
549
550
551
552
553/* unsigned long k;
554 for (MultiDimFiveCompass mc; mc.goon(); ++mc) {
555 Depth T(Index);
556 double value;
557 IndexDimension StencilIndex = Index.nextFive_Neumann(&mc, T, &value);
558 if (!(occupied(k, StencilIndex)))return false;
559 }
560 return true;*/
561}
562
563
565
566inline IndexDimension AdaptiveSparseGrid_Base::getIndexOfTable(unsigned long i) {
567 IndexDimension back;
568 for (int d = 0; d < DimensionSparseGrid; ++d) {
569 back.replace(d, indicesSecondTable[d + i * DimensionSparseGrid]);
570 }
571 return back;
572}
573
574inline IndexDimension AdaptiveSparseGrid_Base::getSupportIMin(unsigned long i) {
575 IndexDimension back;
576 for (int d = 0; d < DimensionSparseGrid; ++d) {
577 back.replace(d, indicesSupportMin[d + i * DimensionSparseGrid]);
578 }
579 return back;
580}
581
582inline IndexDimension AdaptiveSparseGrid_Base::getSupportIMax(unsigned long i) {
583 IndexDimension back;
584 for (int d = 0; d < DimensionSparseGrid; ++d) {
585 back.replace(d, indicesSupportMax[d + i * DimensionSparseGrid]);
586 }
587 return back;
588}
589
590bool AdaptiveSparseGrid_Base::occupied2(unsigned long &indexOfData, IndexDimension I) {
591 Depth T(I);
592 SingleDepthHashGrid &depthGrid = this->getMultiDepthHashGrid()->getGridForDepth(T);
593 const auto &mapping = depthGrid._mapPosToGridPos;
594 unsigned long j;
595 if(depthGrid.occupied(j,I)){
596 indexOfData=mapping[j];
597 return true;
598 }else{
599 return false;
600 }
601
602
603}
604
605#endif // SPARSEGRID_H
606
Definition sparseGrid.h:86
AdaptiveSparseGrid_Base()
Definition sparseGrid.cc:30
bool * isActiveNodeTable
‍0 means empty; 1 means occupied, but no next; v>1 means v-2 is next array index
Definition sparseGrid.h:233
unsigned long getFreeSpaceNumberInSecondTable()
Definition sparseGrid.cc:402
IndexDimension getIndexOfTable(unsigned long i)
Definition sparseGrid.h:566
void Print_gnu(string name)
Prints coordinates of adaptive sparse grid in gnu-file.
Definition sparseGrid.cc:258
int * indicesSupportMin
‍Contains coded indices. Length: secondTableLength*DimensionSparseGrid
Definition sparseGrid.h:237
unsigned long hash(IndexDimension index)
Definition sparseGrid.h:395
unsigned long * secondTable
‍0 means empty; v>0 means v-1 is array index
Definition sparseGrid.h:232
void printCoordinates()
Prints coordinates of adaptive sparse grid.
Definition sparseGrid.cc:125
void PrintGridIndices(int level, IndexDimension *Indices, int numberofindices)
prints all nodes and highlights given Indices
Definition sparseGrid.cc:189
int * indicesSecondTable
‍true means AdaptiveSparseGrid_Base::getIndexOfTable (i) is active node.
Definition sparseGrid.h:236
bool occupied(unsigned long &indexOfData, IndexDimension I)
Definition sparseGrid.h:465
void PrintActiveHanging(int level)
prints active nodes (o) and hanging nodes (x)
Definition sparseGrid.cc:139
Definition sparseGrid.h:277
void CompleteToLocalTensorProductGrid()
‍adds all father points including boundary points
Definition localTensorProduct.cc:189
bool AddPoint(const IndexDimension I)
Definition sparseGrid.cc:482
AdaptiveSparseGrid()
Definition sparseGrid.h:282
Definition ListOfDepthOrderedGrids.h:115