sandbox/Antoonvh/enlarge_domain.h
Sometimes it may be usefull to extend the domain to get increased statistics. This functions copies a grid and solution 2^{dimension-1} times and extends it over the bottom boundary.
See the example for reference.
void enlarge_hor(scalar * list){
double * data;
unsigned * flags;
long unsigned int n = 0, j = 0, jj = 0;
int len = list_len(list);
foreach_cell(reduction(+:n))
n++;
data = malloc (n*len*sizeof(double));
flags = malloc (n*sizeof(unsigned));
foreach_cell(){ //"Dump" to arrays
flags[jj++] = is_leaf(cell) ? leaf : 0;
for (scalar s in list)
data[j++] = s[];
if (is_leaf(cell)) // No halo data
continue;
}
unrefine(level >= 1);
foreach_cell(){
if (point.level >= 1 && y < Y0 + L0/2.){
if (point.level == 1)
j = jj = 0;
for (scalar s in list)
s[] = data[j++];
if (!(flags[jj++] & leaf) && is_leaf(cell))
refine_cell(point, list, 0, NULL);
if (is_leaf(cell))// Still No halos
continue;
}
}
free(data); free(flags);
L0 *= 2.; X0 *= 2.; Z0 *= 2.;
}
This very similar function extends the domain in all dimension
directions. See this example
void enlarge_all(scalar * list){
double * data;
unsigned * flags;
long unsigned int n = 0, j = 0, jj = 0;
int len = list_len(list);
foreach_cell(reduction(+:n))
n++;
data = malloc (n*len*sizeof(double));
flags = malloc (n*sizeof(unsigned));
foreach_cell(){ //"Dump" to arrays
flags[jj++] = is_leaf(cell) ? leaf : 0;
for (scalar s in list)
data[j++] = s[];
if (is_leaf(cell)) // No halo data
continue;
}
unrefine(level >= 1);
foreach_cell(){
if (point.level >= 1){ // Do not start at root cell
if (point.level == 1)
j = jj = 0;
for (scalar s in list)
s[] = data[j++];
if (!(flags[jj++] & leaf) && is_leaf(cell))
refine_cell(point, list, 0, NULL);
if (is_leaf(cell))// Still No halos
continue;
}
}
free(data); free(flags);
foreach_coarse_level(0){ //Also restrict the root cell
for (scalar s in list){
double sum = 0;
foreach_child()
sum += s[];
s[] = sum /(double)(1 << dimension);
}
}
L0 *= 2.; X0 *= 2.; Y0 *= 2.; Z0 *= 2.;
}
Child points -> rotated 1st = -1 -1 -1 -> -1 -1 -1 = 1st 2nd = -1 -1 1 -> 1 -1 -1 = 5th 3rd = -1 1 -1 -> -1 -1 1 = 2nd 4th = -1 1 1 -> 1 -1 1 = 6th 5th = 1 -1 -1 -> -1 1 -1 = 3rd 6th = 1 -1 1 -> 1 1 -1 = 7th 7th = 1 1 -1 -> -1 1 1 = 4th 8th = 1 1 1 -> 1 1 1 = 8th
int swap_array[8] = {0, 4, 1, 5, 2, 6, 3, 7};
int ind[8][3];
void swap_direction (scalar * list) {
double * data;
unsigned * flags;
long unsigned int n = 0, j = 0, jj = 0;
foreach_cell(reduction(+:n))
n++;
data = malloc (n*list_len(list)*sizeof(double));
flags = malloc (n*sizeof(unsigned));
for (int i = 0; i < 2 ; i++)
for (int j = 0; j < 2 ; j++)
for (int k = 0; k < 2 ; k++) {
ind[jj][0] = i, ind[jj][1] = j, ind[jj][2] = k;
jj++;
}
jj = 0;
We will traverse the tree and keep track of the number of iterated cells at each level. Per traversal, the maximum is eight.
int child_nr[depth() + 1];
for (int d = 0; d <= depth(); d++)
child_nr[d] = 0;
We write our own cell iterator
Point point; point.i = point.j = point.k = GHOSTS, point.level = 0;
The root is not rotated…
child_nr[point.level] = 8; //We are done at level = 0.
write_data (point, list, data, flags, &j, &jj);
bool next_cell = true;
while (next_cell) {
if (!is_leaf(cell)) { //Go to child
point.level++;
point.i = 2*point.i - GHOSTS + ind[swap_array[0]][0];
point.j = 2*point.j - GHOSTS + ind[swap_array[0]][1];
point.k = 2*point.k - GHOSTS + ind[swap_array[0]][2];
child_nr[point.level]++; //Mark as being iterated
} else { //a leaf: We go to a sibling or a parent...
if (child_nr[point.level] < 8) { //Goto sibling
int old = swap_array[child_nr[point.level] - 1];
int new = swap_array[child_nr[point.level]];
point.i += ind[new][0] - ind[old][0];
point.j += ind[new][1] - ind[old][1];
point.k += ind[new][2] - ind[old][2];
child_nr[point.level]++;
} else {
while (child_nr[point.level] == 8 && point.level > 0) { //reset and move down
child_nr[point.level] = 0;
point.i = (point.i + GHOSTS)/2;
point.j = (point.j + GHOSTS)/2;
point.k = (point.k + GHOSTS)/2;
point.level-- ;
}
if (point.level > 0) { //Goto the next sibling at this coarser level
int old = swap_array[child_nr[point.level] - 1];
int new = swap_array[child_nr[point.level]];
point.i += ind[new][0] - ind[old][0];
point.j += ind[new][1] - ind[old][1];
point.k += ind[new][2] - ind[old][2];
child_nr[point.level]++;
} else
next_cell = false;
}
}
if (next_cell) { //Write the data
flags[jj++] = is_leaf(cell) ? leaf : 0;
for (scalar s in list)
data[j++] = s[];
}
}
//"Restore"
unrefine(level >= 1);
foreach_cell(){
if (point.level == 0)
j = jj = 0;
for (scalar s in list)
s[] = data[j++];
if (!(flags[jj++] & leaf) && is_leaf(cell))
refine_cell(point, list, 0, NULL);
if (is_leaf(cell))// Still No halos
continue;
}
}