sandbox/Antoonvh/prolongate_halo_flux.h
Flux prolongation
Cell-face fluxes may be approximated from a coarser-level solution. This method may be attractive for the computation of fluxes at resolution boundaries. It is the ‘upside-down’ version of halo_flux()
, reducing the importance of the accuracy of halo-cell-centered values.
The function prolongates/injects coarse-face fluxes to finer ones at resolution boundaries. Inspiration is taken from src/tree.h
.
void halo_flux_prolongate_level (vector * list, int l) {
foreach_halo (prolongation, l) {
foreach_dimension() {
#if dimension == 1
In 1D injectiontion is exact.
if (is_refined(neighbor(-1)))
for (vector v in list)
fine(v.x, 0, 0 ,0) = v.x[];
if (is_refined(neighbor(1)))
for (vector v in list)
fine(v.x, 2, 0 ,0) = v.x[1];
#elif dimension == 2
In 2D we use a 3rd-order-accurate conservative formulation.
if (is_refined(neighbor(-1))) {
for (vector v in list) {
double dv = (v.x[0,1] - v.x[0,-1])/8.;
for (int j = 0; j <= 1; j++)
fine(v.x, 0, j, 0) = j == 0 ? v.x[] - dv : v.x[] + dv;
}
}
if (is_refined(neighbor(1))) {
for (vector v in list) {
double dv = (v.x[1,1] - v.x[1,-1])/8.;
for (int j = 0; j<=1; j++)
fine(v.x, 2, j, 0) = j == 0 ? v.x[1] - dv : v.x[1] + dv;
}
}
#elif dimension == 3
In 3D we inject again. We will update with 3x3x3 linear
if (is_refined(neighbor(-1))) {
for (vector v in list) {
fine(v.x, 0, 0, 0) = v.x[];
fine(v.x, 0, 1, 0) = v.x[];
fine(v.x, 0, 0, 1) = v.x[];
fine(v.x, 0, 1, 1) = v.x[];
}
}
if (is_refined(neighbor(1))) {
for (vector v in list) {
fine(v.x, 2, 0, 0) = v.x[1];
fine(v.x, 2, 1, 0) = v.x[1];
fine(v.x, 2, 0, 1) = v.x[1];
fine(v.x, 2, 1, 1) = v.x[1];
}
}
#endif
}
}
}
static void halo_flux_prolongate (vector * list) {
vector * listv = NULL;
for (vector v in list)
if (!is_constant(v.x))
listv = vectors_add (listv, v);
if (listv)
for (int l = 0; l < depth(); l++)
halo_flux_prolongate_level (listv, l);
}
Usage
It may be used in a future, ad-hoc, prove-of-the-point adaptive advection-diffusion, KdV solver and a Poisson solver.