sandbox/Antoonvh/pb.c
A dirichlet BC trick for the Poisson solver
We solve \nabla^2 f = s for f and want to prescribe some value at the top boundary. Normally it would look like this,
#include "poisson.h"
#include "utils.h"
scalar f[], s[];
int main() {
periodic (left);
= 10;
L0 = -5.;
X0 = -2.5;
Y0 (128);
init_grid foreach()
[] = exp(-sq(x) - sq(y));
soutput_ppm (s, file = "s.png", n = 256, linear = true);

We set boundary conditions and solve the problem
[top] = dirichlet (1.);
f[bottom] = dirichlet (0.);
fpoisson (f, s);
output_ppm (f, file = "f.png", n = 256,
= true, min = -2, max = 1.5); linear

Boundary within the domain
We want to prescribe the value of f
halfway the domain (i.e. y =
Y0 + L0/2
) and for some reason we do not use mask or
embedded boundaries. We must then first set a homogeneous dirichlet
condition at the top, so that we solve for a modified field f_{\mathrm{mod}} = f-1.
The dirichlet condition is extented into the domain via a face vector field and a scalar field:
face vector as[];
scalar ls[];
# define OUTSIDE_DOMAIN (y >= (Y0 + L0/2.))
foreach() {
if (OUTSIDE_DOMAIN) { // Outide the internal domain:
[] = 0; // Source term is zero
s[] = -10; // Linear term
ls}else
[] = 0; // No linear term
ls}
foreach_face() // Set the default face weights
.x[] = 1;
asforeach_face(x) // Except for the boundary-perpendicular component,
if (OUTSIDE_DOMAIN) // outside the internal domain.
.x[] = 0.;
asboundary((scalar*) all);
We now solve the modified problem:
poisson (f, s, as, ls);
output_ppm (f, file = "f2.png", n = 256,
= true, min = -3, max = 0.5); linear

we compare it against the proper mask implementation,
mask (OUTSIDE_DOMAIN ? top : none);
boundary(all);
poisson (f, s);
output_ppm (f, file = "f3.png", n = 256,
= true, min = -3, max = 0.5); linear

}