src/test/hydrostatic2.c
Hydrostatic balance with refined embedded boundaries
This test case is related to flow in a complex porous medium. We check that for a “closed pore” medium, hydrostatic balance can be recovered. This is not trivial in particular when the spatial resolution is variable, since pressure values need to be interpolated (at least) to second-order close to embedded boundaries. This behaviour depends on the restriction and prolongation operators used close to embedded boundaries.
#include "embed.h"
#include "navier-stokes/centered.h"
#include "view.h"
We use a similar porous medium as in porous.c but with enough disks so that the pores are entirely closed.
void porous (scalar cs, face vector fs)
{
int ns = 200;
double xc[ns], yc[ns], R[ns];
(0);
srand double a = 0.5, b = 0.04;
for (int i = 0; i < ns; i++)
[i] = a*noise(), yc[i] = a*noise(), R[i] = 0.02 + b*fabs(noise());
xc
vertex scalar phi[];
foreach_vertex() {
[] = HUGE;
phifor (double xp = -L0; xp <= L0; xp += L0)
for (double yp = -L0; yp <= L0; yp += L0)
for (int i = 0; i < ns; i++)
[] = intersection (phi[], (sq(x + xp - xc[i]) +
phi(y + yp - yc[i]) - sq(R[i])));
sq}
fractions (phi, cs, fs);
fractions_cleanup (cs, fs);
}
int main()
{
(-0.5, -0.5);
origin
(1 << 6); init_grid
The events of the Navier-Stokes solver are called “by hand”.
event ("metric");
event ("defaults");
porous (cs, fs);
#if 0
refine (level < 8 && cs[] > 0 && cs[] < 1);
porous (cs, fs);
#else
({cs}, (double[]){0.01}, 8, 6);
adapt_wavelet porous (cs, fs);
({cs}, (double[]){0.01}, 8, 6);
adapt_wavelet porous (cs, fs);
({cs}, (double[]){0.01}, 8, 6);
adapt_wavelet porous (cs, fs);
#endif
[] = {1.,2.}; a
The system is quite stiff.
= 1e-6;
TOLERANCE = 100;
NITERMAX .nrelax = 100;
mgp= fm;
alpha = 1.;
dt
event ("acceleration");
#if 1
event ("projection");
#else
foreach()
[] = G.x[]*x + G.y[]*y; // exact pressure
pforeach_face()
.x[] -= alpha.x[] ? dt*alpha.x[]*face_gradient_x (p, 0) : 0.;
uf
face vector gf[];
foreach_face()
.x[] = fm.x[] ? fm.x[]*a.x[] - alpha.x[]*(p[] - p[-1])/Delta : 0.;
gf
({g});
trash foreach()
foreach_dimension() {
.x[] = (gf.x[] + gf.x[1])/(fm.x[] + fm.x[1] + SEPS);
g// assert (fabs(g.x[]) < 1e-6);
}
correction (dt);
#endif
We check the convergence rate and the norms of the velocity field (which should be negligible).
fprintf (stderr, "mgp %g %g %d %d\n", mgp.resb, mgp.resa, mgp.i, mgp.minlevel);
fprintf (stderr, "umax %g %g\n", normf(u.x).max, normf(u.y).max);
The pressure is hydrostatic, in each of the pores.
