AMR-Solver  1.0
Block-based Octree AMR grid flow solver
octree.cpp
Go to the documentation of this file.
1 #include "octree.h"
2 #include <iostream>
3 #include "direction.h"
4 
5 namespace myOctree {
6 
7 
8 
9 //Member functions
11 
12  return children[0][0][0] == NULL;
13 }
14 
16 
17  return parent == NULL;
18 }
19 
21 
22  return block_data;
23 }
24 
25 bool Octree::contains(double x, double y, double z) {
26 
27  /*change it to (x-x_min)*(x-x_max)<=....*/
28  return x<=x_max && x>=x_min && y<=y_max && y>=y_min && z<=z_max && z>=z_min;
29 
30 }
31 
33 
34  return this->level;
35 
36 }
37 
38 Octree* Octree::get_child_at(int i, int j, int k) {
39 
40  return this->children[i][j][k];
41 
42 }
43 
44 void Octree::set_child_null_at(int i, int j, int k) {
45 
46  this->children[i][j][k] = NULL;
47 
48 }
49 
51 
52  return this->parent;
53 
54 }
55 
57 
58  //set refinement criteria
59  this->setToRefine = true;
60 
61  //check nesting
62  if(!(this->isRootNode())) {
63 
64 
65  // if(this->east==NULL && this->east_bc==NONE) {
66 
67  // if(!(this->parent->east->setToRefine==true)) {
68  // this->parent->east->set_to_refine_with_nesting();
69  // }
70 
71  // }
72 
73  // if(this->west==NULL && this->west_bc==NONE) {
74  //
75  // if(!(this->parent->west->setToRefine==true)) {
76  // this->parent->west->set_to_refine_with_nesting();
77  // }
78 
79  // }
80 
81  // if(this->north==NULL && this->north_bc==NONE) {
82  //
83  // if(!(this->parent->north->setToRefine==true)) {
84  // this->parent->north->set_to_refine_with_nesting();
85  // }
86 
87  // }
88 
89  // if(this->south==NULL && this->south_bc==NONE) {
90  //
91  // if(!(this->parent->south->setToRefine==true)) {
92  // this->parent->south->set_to_refine_with_nesting();
93  // }
94 
95  // }
96  //
97  // if(this->top==NULL && this->top_bc==NONE) {
98  //
99  // if(!(this->parent->top->setToRefine==true)) {
100  // this->parent->top->set_to_refine_with_nesting();
101  // }
102 
103  // }
104  //
105  // if(this->bottom==NULL && this->bottom_bc==NONE) {
106  //
107  // if(!(this->parent->bottom->setToRefine==true)) {
108  // this->parent->bottom->set_to_refine_with_nesting();
109  // }
110 
111  // }
112 
113  for(int m=0;m<3;m++) {
114  for(int n=0;n<2;n++) {
115  if(this->neighbour[m][n]==NULL && this->bc[m][n]==NONE) {
116  if(!(this->parent->neighbour[m][n]->setToRefine==true)) {
118  }
119  }
120  }
121  }
122  }
123 }
124 
125 //checks if all of its neighbours are leaf nodes before setting the criteria
127 
128  bool criteria;
129  criteria = true;
130 
131 // if(this->east) {
132 // if(!(this->east->isLeafNode())) {
133 // criteria = false;
134 // }
135 // }
136 // if(this->west) {
137 // if(!(this->west->isLeafNode())) {
138 // criteria = false;
139 // }
140 // }
141 // if(this->north) {
142 // if(!(this->north->isLeafNode())) {
143 // criteria = false;
144 // }
145 // }
146 // if(this->south) {
147 // if(!(this->south->isLeafNode())) {
148 // criteria = false;
149 // }
150 // }
151 // if(this->top) {
152 // if(!(this->top->isLeafNode())) {
153 // criteria = false;
154 // }
155 // }
156 // if(this->bottom) {
157 // if(!(this->bottom->isLeafNode())) {
158 // criteria = false;
159 // }
160 // }
161 
162  for(int m=0;m<3;m++) {
163  for(int n=0;n<2;n++) {
164  if(this->neighbour[m][n]) {
165  //std::cerr << "\n" << "hi" << std::endl;
166  if(!(this->neighbour[m][n]->isLeafNode())) {
167  criteria = false;
168  }
169  }
170  }
171  }
172 
173  this->setToCoarsen = criteria;
174 
175 }
176 
183 
184  int i, j, k;
185  double xmin, xmax, ymin, ymax, zmin, zmax;
186  double lev = this->level + 1;
187 
188  //creating children nodes
189  for(k=0; k<2; k++) {
190  for(j=0; j<2; j++) {
191  for(i=0; i<2; i++) {
192 
193  if(i==0) {
194  xmin = this->x_min;
195  xmax = this->x_centre;
196  }
197  else {
198  xmin = this->x_centre;
199  xmax = this->x_max;
200  }
201 
202  if(j==0) {
203  ymin = this->y_min;
204  ymax = this->y_centre;
205  }
206  else {
207  ymin = this->y_centre;
208  ymax = this->y_max;
209  }
210 
211  if(k==0) {
212  zmin = this->z_min;
213  zmax = this->z_centre;
214  }
215  else {
216  zmin = this->z_centre;
217  zmax = this->z_max;
218  }
219 
220 
221  //creating new child object
222  Octree child(xmin, xmax, ymin, ymax, zmin, zmax, lev);
223 
224  //deleting the pushed node to the list
225  nodes.pop_back();
226 
227  //assigning parent to the child
228  child.parent = this;
229 
230  //invoking copy constructor
231  this->children[i][j][k] = new Octree(child);
232  //*(this->children[i][j][k]) = child;
233 
234 
235  }
236  }
237  }
238 
239  //setting neighbours to children - this could be redundant - yet to test
240  for(k=0; k<2; k++) {
241  for(j=0; j<2; j++) {
242  for(i=0; i<2; i++) {
243 
244  // if(i==0) {
245  // this->children[i][j][k]->east = this->children[i+1][j][k];
246  // if(this->west != NULL) this->children[i][j][k]->west = this->west->children[i+1][j][k];
247  // }
248  // if(j==0) {
249  // this->children[i][j][k]->north = this->children[i][j+1][k];
250  // if(this->south != NULL) this->children[i][j][k]->south = this->south->children[i][j+1][k];
251  // }
252  // if(k==0) {
253  // this->children[i][j][k]->top = this->children[i][j][k+1];
254  // if(this->bottom != NULL) this->children[i][j][k]->bottom = this->bottom->children[i][j][k+1];
255  // }
256  // if(i==1) {
257  // this->children[i][j][k]->west = this->children[i-1][j][k];
258  // if(this->east != NULL) this->children[i][j][k]->east = this->east->children[i-1][j][k];
259  // }
260  // if(j==1) {
261  // this->children[i][j][k]->south = this->children[i][j-1][k];
262  // if(this->north != NULL) this->children[i][j][k]->north = this->north->children[i][j-1][k];
263  // }
264  // if(k==1) {
265  // this->children[i][j][k]->bottom = this->children[i][j][k-1];
266  // if(this->top != NULL) this->children[i][j][k]->top = this->top->children[i][j][k-1];
267  // }
268  if(i==0) {
269  this->children[i][j][k]->neighbour[XDIR][RIGHT] = this->children[i+1][j][k];
270  if(this->neighbour[XDIR][LEFT] != NULL) this->children[i][j][k]->neighbour[XDIR][LEFT] = this->neighbour[XDIR][LEFT]->children[i+1][j][k];
271  }
272  if(j==0) {
273  this->children[i][j][k]->neighbour[YDIR][RIGHT] = this->children[i][j+1][k];
274  if(this->neighbour[YDIR][LEFT] != NULL) this->children[i][j][k]->neighbour[YDIR][LEFT] = this->neighbour[YDIR][LEFT]->children[i][j+1][k];
275  }
276  if(k==0) {
277  this->children[i][j][k]->neighbour[ZDIR][RIGHT] = this->children[i][j][k+1];
278  if(this->neighbour[ZDIR][LEFT] != NULL) this->children[i][j][k]->neighbour[ZDIR][LEFT] = this->neighbour[ZDIR][LEFT]->children[i][j][k+1];
279  }
280  if(i==1) {
281  this->children[i][j][k]->neighbour[XDIR][LEFT] = this->children[i-1][j][k];
282  if(this->neighbour[XDIR][RIGHT] != NULL) this->children[i][j][k]->neighbour[XDIR][RIGHT] = this->neighbour[XDIR][RIGHT]->children[i-1][j][k];
283  }
284  if(j==1) {
285  this->children[i][j][k]->neighbour[YDIR][LEFT] = this->children[i][j-1][k];
286  if(this->neighbour[YDIR][RIGHT] != NULL) this->children[i][j][k]->neighbour[YDIR][RIGHT] = this->neighbour[YDIR][RIGHT]->children[i][j-1][k];
287  }
288  if(k==1) {
289  this->children[i][j][k]->neighbour[ZDIR][LEFT] = this->children[i][j][k-1];
290  if(this->neighbour[ZDIR][RIGHT] != NULL) this->children[i][j][k]->neighbour[ZDIR][RIGHT] = this->neighbour[ZDIR][RIGHT]->children[i][j][k-1];
291  }
292  }
293  }
294  }
295 
296  //setting boundaries to children
297  for(k=0; k<2; k++) {
298  for(j=0; j<2; j++) {
299  for(i=0; i<2; i++) {
300 
301  // if(i==0) {
302  // this->children[i][j][k]->east_bc = NONE;
303  // this->children[i][j][k]->west_bc = this->west_bc;
304  // }
305  // if(j==0) {
306  // this->children[i][j][k]->north_bc = NONE;
307  // this->children[i][j][k]->south_bc = this->south_bc;
308  // }
309  // if(k==0) {
310  // this->children[i][j][k]->top_bc = NONE;
311  // this->children[i][j][k]->bottom_bc = this->bottom_bc;
312  // }
313  // if(i==1) {
314  // this->children[i][j][k]->west_bc = NONE;
315  // this->children[i][j][k]->east_bc = this->east_bc;
316  // }
317  // if(j==1) {
318  // this->children[i][j][k]->south_bc = NONE;
319  // this->children[i][j][k]->north_bc = this->north_bc;
320  // }
321  // if(k==1) {
322  // this->children[i][j][k]->bottom_bc = NONE;
323  // this->children[i][j][k]->top_bc = this->top_bc;
324  // }
325  if(i==0) {
326  this->children[i][j][k]->bc[XDIR][RIGHT] = NONE;
327  this->children[i][j][k]->bc[XDIR][LEFT] = this->bc[XDIR][LEFT];
328  }
329  if(j==0) {
330  this->children[i][j][k]->bc[YDIR][RIGHT] = NONE;
331  this->children[i][j][k]->bc[YDIR][LEFT] = this->bc[YDIR][LEFT];
332  }
333  if(k==0) {
334  this->children[i][j][k]->bc[ZDIR][RIGHT] = NONE;
335  this->children[i][j][k]->bc[ZDIR][LEFT] = this->bc[ZDIR][LEFT];
336  }
337  if(i==1) {
338  this->children[i][j][k]->bc[XDIR][LEFT] = NONE;
339  this->children[i][j][k]->bc[XDIR][RIGHT] = this->bc[XDIR][RIGHT];
340  }
341  if(j==1) {
342  this->children[i][j][k]->bc[YDIR][LEFT] = NONE;
343  this->children[i][j][k]->bc[YDIR][RIGHT] = this->bc[YDIR][RIGHT];
344  }
345  if(k==1) {
346  this->children[i][j][k]->bc[ZDIR][LEFT] = NONE;
347  this->children[i][j][k]->bc[ZDIR][RIGHT] = this->bc[ZDIR][RIGHT];
348  }
349  }
350  }
351  }
352 
353  //setting boundary conditions to children fields
354  for(k=0; k<2; k++) {
355  for(j=0; j<2; j++) {
356  for(i=0; i<2; i++) {
357 
358  for(int l = 0; l<scalar_fields.size() ; l++) {
359  for (int m=0; m<3; m++) {
360  for (int n=0; n<2; n++) {
361 
362  if(this->children[i][j][k]->bc[m][n] == BOUNDARY) {
363  this->children[i][j][k]->get_block_data()->scalarfields[l]->bc[m][n] = \
364  this->get_block_data()->scalarfields[l]->bc[m][n];
365  }
366 
367  if(this->children[i][j][k]->bc[m][n] == NONE) {
368  this->children[i][j][k]->get_block_data()->scalarfields[l]->bc[m][n] = none;
369  }
370 
371  if(this->children[i][j][k]->bc[m][n] == MPI_BOUNDARY) {
372  this->children[i][j][k]->get_block_data()->scalarfields[l]->bc[m][n] = mpi_boundary;
373  }
374  }
375  }
376  }
377 
378  for(int l = 0; l<vector_fields.size() ; l++) {
379  for (int m=0; m<3; m++) {
380  for (int n=0; n<2; n++) {
381 
382  if(this->children[i][j][k]->bc[m][n] == BOUNDARY) {
383  this->children[i][j][k]->get_block_data()->vectorfields[l]->xbc[m][n] = \
384  this->get_block_data()->vectorfields[l]->xbc[m][n];
385  this->children[i][j][k]->get_block_data()->vectorfields[l]->ybc[m][n] = \
386  this->get_block_data()->vectorfields[l]->ybc[m][n];
387  this->children[i][j][k]->get_block_data()->vectorfields[l]->zbc[m][n] = \
388  this->get_block_data()->vectorfields[l]->zbc[m][n];
389  }
390 
391  if(this->children[i][j][k]->bc[m][n] == NONE) {
392  this->children[i][j][k]->get_block_data()->vectorfields[l]->xbc[m][n] = none;
393  this->children[i][j][k]->get_block_data()->vectorfields[l]->ybc[m][n] = none;
394  this->children[i][j][k]->get_block_data()->vectorfields[l]->zbc[m][n] = none;
395  }
396 
397  if(this->children[i][j][k]->bc[m][n] == MPI_BOUNDARY) {
398  this->children[i][j][k]->get_block_data()->vectorfields[l]->xbc[m][n] = mpi_boundary;
399  this->children[i][j][k]->get_block_data()->vectorfields[l]->ybc[m][n] = mpi_boundary;
400  this->children[i][j][k]->get_block_data()->vectorfields[l]->zbc[m][n] = mpi_boundary;
401  }
402  }
403  }
404  }
405  }
406  }
407  }
408 }
409 
410 /*check what is happening - destroy is necessary*/
412 // std::cerr << " destructor of octree is working " << std::endl;
413 
414  delete block_data;
415 }
416 
417 /*copy constructor not working*/
418 Octree::Octree(const Octree &obj) {
419 
420 // std::cerr << " copy constructor of octree is working " << std::endl;
421 
422  x_min = obj.x_min;
423  y_min = obj.y_min;
424  z_min = obj.z_min;
425  x_max = obj.x_max;
426  y_max = obj.y_max;
427  z_max = obj.z_max;
428  x_centre = obj.x_centre;
429  y_centre = obj.y_centre;
430  z_centre = obj.z_centre;
431  level = obj.level;
432 
433  for(int i=0; i<2; i++) {
434  for(int j=0; j<2; j++) {
435  for(int k=0; k<2; k++)
436  children[i][j][k] = obj.children[i][j][k];
437  }
438  }
439 
440  parent = obj.parent;
441  block_data = new Block(*(obj.block_data));
442  setToRefine = obj.setToRefine;
444 
445  number = obj.number;
446 
447  //neighbors
448 // east = obj.east;
449 // west = obj.west;
450 // north = obj.north;
451 // south = obj.south;
452 // top = obj.top;
453 // bottom = obj.bottom;
454 
455  for(int m=0;m<3;m++) {
456  for(int n=0;n<2;n++) {
457  neighbour[m][n] = obj.neighbour[m][n];
458  }
459  }
460 
461  //boundary conditions
462 // east_bc = obj.east_bc;
463 // west_bc = obj.west_bc;
464 // north_bc = obj.north_bc;
465 // south_bc = obj.south_bc;
466 // top_bc = obj.top_bc;
467 // bottom_bc = obj.bottom_bc;
468 
469  for(int m=0;m<3;m++) {
470  for(int n=0;n<2;n++) {
471  bc[m][n] = obj.bc[m][n];
472  }
473  }
474 
475 
476  nodes.push_back(this);
477 
478 }
479 
480 Octree::Octree( double x1, double x2, double y1, double y2, double z1, double z2, int l ) : x_min(x1), x_max(x2), y_min(y1), y_max(y2), z_min(z1), z_max(z2), level(l) {
481 // std::cerr << " parametrized constructor of octree is working " << std::endl;
482 
483  for(int i=0; i<2; i++) {
484  for(int j=0; j<2; j++) {
485  for(int k=0; k<2; k++)
486  children[i][j][k] = NULL;
487  }
488  }
489 
490  parent = NULL;
491  setToRefine = false;
492  setToCoarsen = false;
493 
494  //neighbors
495 // east = NULL;
496 // west = NULL;
497 // north = NULL;
498 // south = NULL;
499 // top = NULL;
500 // bottom = NULL;
501 
502  for(int m=0;m<3;m++) {
503  for(int n=0;n<2;n++) {
504  neighbour[m][n] = NULL;
505  }
506  }
507 
508  //boundary conditions
509 // east_bc = NONE;
510 // west_bc = NONE;
511 // north_bc = NONE;
512 // south_bc = NONE;
513 // top_bc = NONE;
514 // bottom_bc = NONE;
515 
516  for(int m=0;m<3;m++) {
517  for(int n=0;n<2;n++) {
518  bc[m][n] = NONE;
519  }
520  }
521 
522  number = 0;
523 
524  x_centre = (x_min + x_max ) / 2.0;
525  y_centre = (y_min + y_max ) / 2.0;
526  z_centre = (z_min + z_max ) / 2.0;
527 
528 
529  //creating block to assign it to the data
530  Block new_block(x_min, x_max, y_min, y_max, z_min, z_max);
531  block_data = new Block(new_block);
532 
533  nodes.push_back(this);
534 
535 }
536 
538 // std::cerr << " default constructor of octree is working " << std::endl;
539 
540  for(int i=0; i<2; i++) {
541  for(int j=0; j<2; j++) {
542  for(int k=0; k<2; k++)
543  children[i][j][k] = NULL;
544  }
545  }
546 
547  parent = NULL;
548  setToRefine = false;
549  setToCoarsen = false;
550 
551  //neighbors
552 // east = NULL;
553 // west = NULL;
554 // north = NULL;
555 // south = NULL;
556 // top = NULL;
557 // bottom = NULL;
558 
559  for(int m=0;m<3;m++) {
560  for(int n=0;n<2;n++) {
561  neighbour[m][n] = NULL;
562  }
563  }
564 
565  x_centre = 0.0;
566  y_centre = 0.0;
567  z_centre = 0.0;
568  x_min = 0.0;
569  y_min = 0.0;
570  z_min = 0.0;
571  x_max = 0.0;
572  y_max = 0.0;
573  z_max = 0.0;
574 
575  level = 0;
576 
577  //boundary conditions
578 // east_bc = NONE;
579 // west_bc = NONE;
580 // north_bc = NONE;
581 // south_bc = NONE;
582 // top_bc = NONE;
583 // bottom_bc = NONE;
584 
585 
586  for(int m=0;m<3;m++) {
587  for(int n=0;n<2;n++) {
588  bc[m][n] = NONE;
589  }
590  }
591 
592  number = 0;
593 
594  //creating block to assign it to the data
595  Block new_block;
596  block_data = new Block(new_block);
597 
598  nodes.push_back(this);
599 }
600 
601 
602 }
bool isRootNode()
Definition: octree.cpp:15
This class is a generic data block of a octree node in the block-based AMR mesh.
Definition: block.h:26
std::vector< std::string > scalar_fields
Definition: block.cpp:8
void set_child_null_at(int, int, int)
Definition: octree.cpp:44
int get_level()
Definition: octree.cpp:32
Octree * children[2][2][2]
Definition: octree.h:108
FieldBc zbc[3][2]
Definition: vecfield.h:37
Octree * neighbour[3][2]
Definition: octree.h:73
bool contains(double x, double y, double z)
Definition: octree.cpp:25
NodeBc bc[3][2]
Definition: octree.h:84
VecField ** vectorfields
Definition: block.h:35
Block * block_data
Definition: octree.h:110
double z_min
Definition: octree.h:100
Octree * get_child_at(int, int, int)
Definition: octree.cpp:38
double y_centre
Definition: octree.h:97
bool isLeafNode()
Definition: octree.cpp:10
double z_max
Definition: octree.h:100
bool setToCoarsen
Definition: octree.h:62
FieldBc bc[3][2]
Definition: field.h:22
bool setToRefine
Definition: octree.h:60
double x_max
Definition: octree.h:98
void set_to_coarsen_with_nesting()
Definition: octree.cpp:126
void set_to_refine_with_nesting()
Definition: octree.cpp:56
std::vector< std::string > vector_fields
Definition: block.cpp:9
double x_centre
Definition: octree.h:97
double z_centre
Definition: octree.h:97
Class to store octree datastructure as nodes of the tree.
Definition: octree.h:26
double y_max
Definition: octree.h:99
AMR grid stuff.
Definition: adapt.cpp:6
std::list< Octree * > nodes
Definition: octreegrid.cpp:14
Octree * get_parent()
Definition: octree.cpp:50
Block * get_block_data()
Definition: octree.cpp:20
FieldBc xbc[3][2]
Definition: vecfield.h:35
FieldBc ybc[3][2]
Definition: vecfield.h:36
double y_min
Definition: octree.h:99
double x_min
Definition: octree.h:98
Field ** scalarfields
Definition: block.h:34
Octree * parent
Definition: octree.h:112