sandbox/rcaraccio/src/navier-stokes/centered-phasechange.h
Centered phase change
This file extends the centered Navier-Stokes solver to account for phase change in two-phase flows with porous media. It modifies the projection method to include a gas source term in the continuity equation, and it provides an advection scheme that can account for porosity variations.
#include "poisson.h"
extern double rhoG;
extern scalar porosity, f;
scalar gas_source[];
scalar drhodt[];Projection method with gas source term
We modify the Projection method to account for the gas source term in the continuity equation.
trace
mgstats project_sf (face vector uf, scalar p,
(const) face vector alpha = unityf,
double dt = 1.,
int nrelax = 4)
{
scalar div[];
foreach() {
div[] = 0.;
foreach_dimension()
div[] += uf.x[1] - uf.x[];
div[] /= dt*Delta;We add the gas source term to the divergence field
div[] += gas_source[]/dt;
#ifndef NO_EXPANSION
div[] += drhodt[]/dt;
#endif
}
#ifdef POROUS_ADVECTION
scalar eps[];
foreach()
eps[] = porosity[] + (1. - f[]);
face vector alpha_eff[];
foreach_face()
alpha_eff.x[] = face_value(eps, 0)*alpha.x[];
#else
#define alpha_eff alpha
#endif
mgstats mgp = poisson (p, div, alpha_eff,
tolerance = TOLERANCE/sq(dt), nrelax = nrelax);
foreach_face()
uf.x[] -= dt*alpha_eff.x[]*face_gradient_x (p, 0);
return mgp;
}Advection with non diverging velocity field
We provide an advection scheme that can account for a diverging velocity field.
#include "utils.h"
#include "bcg.h"
void advection_div (scalar * tracers, face vector u, double dt,
scalar * src = NULL)
{
scalar * psrc = src;
if (!src)
for (scalar s in tracers) {
const scalar zero[] = 0.;
src = list_append (src, zero);
}
assert (list_len (tracers) == list_len (src));
scalar f, source;
for (f,source in tracers,src) {
face vector flux[];
tracer_fluxes (f, u, flux, dt, source);
#if !EMBED
foreach() {
#if NO_ADVECTION_DIV
double fold = f[];
#endif
foreach_dimension()
#if NO_ADVECTION_DIV
f[] += dt*(flux.x[] - flux.x[1] + fold*(u.x[1] - u.x[]))/(Delta*cm[]);
#else
f[] += dt*(flux.x[] - flux.x[1])/(Delta*cm[]);
#endif
}
#else // EMBED
update_tracer (f, u, flux, dt);
#endif // EMBED
}
if (!psrc)
free (src);
}Default events and overrides
We set default values for the gas source and drhodt fields
We set placeholder to set the correct order of the events
event set_dtmax (i++, last);
event stability (i++, last);
event reset_sources (i++, last);
event chemistry (i++, last);
event phasechange (i++, last);We overwrite the project and advection events with the one defined above
#define project(...) project_sf(__VA_ARGS__)
#define advection(...) advection_div(__VA_ARGS__)
#include "navier-stokes/centered.h"
#undef advection
#undef projectPorous media advection
We have the option to account for porous media advection by taking into account the porosity field in the advection term. We set stokes=true to suppress the original advection term performed in the centered.h file.
#ifdef POROUS_ADVECTION
event defaults (i = 0) {
stokes = true;
}
event advection_term (i++, last) {
prediction();
mgpf = project_sf (uf, pf, alpha, dt/2., mgpf.nrelax);porosity is a tracer field appended to f. Here we need the one-field form computed in the field ‘eps’.
scalar eps[];
foreach()
eps[] = porosity[] + (1. - f[]);
face vector ufn[];
foreach_face() {
double ef = face_value(eps, 0);
ufn.x[] = uf.x[]/ef;
}
advection ((scalar *){u}, ufn, dt, (scalar *){g});
}the stability event gets disable if stokes is set to true since the solution is implicit. Therefore, we redefine the stability event to set the timestep.
