sandbox/hasansh/fast-capwave/fast-poisson.h
Constant density projection method
For the constant density method we need to solve the constant coefficient Poisson equation: \displaystyle \nabla ^2 p^{n+1}= \nabla \cdot \left[\left(1- \frac{\rho_0}{\rho^{n+1}}\right)\nabla \hat{p}\right]+ \frac{\rho_0}{\Delta t} \nabla \cdot u^{*} After solving the Poisson equation, the velocity field will be updated based on the new pressure field \displaystyle u^{n+1} = u^{*}-\Delta t \left[1/\rho_0 \nabla p^{n+1}+ \left(1/\rho^{n+1}-1/\rho_0\right)\nabla \hat{p}\right] Notations are based on the paper of Dodd and Ferrante, 2014.
mgstats fast_project (int method, face vector u, scalar p, scalar pn,
(const) face vector alpha, double rho0, double dt)
{
We initialize \hat{p}=pn for fastpn method and \hat{p}=2 p^n - p^{n-1} for fastpstar method.
scalar phat[];
switch(method){
case 1: {
foreach()
phat[] = p[];
boundary ({phat});
break;
}
case 2: {
foreach() {
#if 1
phat[] = 1.5*p[] - 0.5*pn[];
#else // this was suggested by Michael Dodd but does not seem to work
phat[] = 2.*p[] - pn[];
#endif
pn[] = p[];
}
boundary ({phat, pn});
break;
}
}
We calculate the term \frac{\rho_0}{\Delta t} \nabla \cdot u^{*} and store it in div_ustar variable.
scalar div_ustar[];
foreach() {
div_ustar[] = 0.;
foreach_dimension()
div_ustar[] += u.x[1] - u.x[];
div_ustar[] /= dt*cm[]*Delta;
div_ustar[] *= rho0;
}
boundary ({div_ustar});
We calculate the term \nabla \cdot \left[\left(1-\frac{\rho_0}{\rho^{n+1}}\right)\nabla \hat{p}\right] and store it in div_phat variable.
face vector f[], coef[];
scalar div_phat[];
foreach_face()
coef.x[]= (1. - rho0*alpha.x[]);
#if TREE
foreach_face()
f.x[] = coef.x[]*(phat[] - phat[-1])/(Delta);
boundary_flux ({f});
foreach() {
div_phat[] = 0.;
foreach_dimension()
div_phat[] += f.x[1] - f.x[];
div_phat[] /= cm[]*Delta;
}
#else // Cartesian
foreach() {
div_phat[] = 0.;
foreach_dimension()
div_phat[] += (coef.x[1]*(phat[1] - phat[]) -
coef.x[]*(phat[] - phat[-1]));
div_phat[] /= cm[]*sq(Delta);
}
#endif
boundary ({div_phat});
We construct the right hand side of Poisson equation and store it in variable b.
We solve the Poisson problem. The tolerance (set with TOLERANCE) is the maximum relative change in volume of a cell (due to the divergence of the flow) during one timestep i.e. the non-dimensional quantity \displaystyle |\nabla\cdot\mathbf{u}|\Delta t Given the scaling of the divergence above, this gives
mgstats mgp = poisson (p, b, tolerance = TOLERANCE/sq(dt));
And compute \mathbf{u}^{n+1} using \mathbf{u}^*, p, $p^{hat}, $
foreach_face()
u.x[] -= dt*(1./rho0*(p[] - p[-1]) +
(alpha.x[] - 1./rho0)*(phat[] - phat[-1]))/Delta;
boundary ((scalar *){u});
return mgp;
}