A Dirichlet Poisson problem

Now, let's put together a lot of the tools we've discussed earlier to solve a standard problem: the solution of Laplace's equation, with Dirichlet boundary conditions on a surface. Our objective is to solve this problem with one Dirichlet value for the region external to the surface, and another Dirichlet value internal to the surface.

To be specific, our problem is

\[\nabla^2\varphi^+ = 0,\qquad \nabla^2\varphi^- = 0\]

where $+$ denotes the exterior and $-$ the interior of the surface. (We will consider a circle of radius 1.) The boundary conditions on this surface are

\[\varphi^+ = x, \qquad \varphi^- = 0\]

In other words, we seek to set the value on the exterior to the local $x$ coordinate of the surface, while the interior should have zero field.

Discretizing this problem by the techniques developed in [1], we seek to solve

\[\begin{bmatrix} L & R \\ R^T & 0 \end{bmatrix} \begin{pmatrix} f \\ -s \end{pmatrix} = \begin{pmatrix} D_s d \\ \overline{f}_b \end{pmatrix}\]

where $\overline{f}_b = (f^+_b + f^-_b)/2 = x/2$ and $d = f^+_b - f^-_b = x$.

This saddle-point problem can be solved by block-LU decomposition. First solve

\[L f^{*} = D_s d\]

for $f^*$. Then solve

\[R^TL^{-1}R s = \overline{f}_b - R^T f^{*}\]

for $s$, and finally, compute

\[f = f^{*} + L^{-1}R s\]

We will demonstrate these steps here.

using ImmersedLayers
using Plots
using LinearAlgebra

Set up the grid, shape, and cache

We do this just as we did in Immersed layer caches

Δx = 0.01
Lx = 4.0
xlim = (-Lx/2,Lx/2)
ylim = (-Lx/2,Lx/2)
g = PhysicalGrid(xlim,ylim,Δx)
RadC = 1.0
Δs = 1.4*cellsize(g)
body = Circle(RadC,Δs)
cache = SurfaceScalarCache(body,g,scaling=GridScaling);

Let's set up the right-hand side values, $D_s d$ and $\overline{f}_b$. We will use fstar as a placeholder for the right-hand side of the upper equations.

pts = points(cache)
x = zeros_surface(cache)
fb = zeros_surface(cache)
fstar = zeros_grid(cache)
x .= pts.u
surface_divergence!(fstar,x,cache)
fb .= 0.5*x;

First step in the algorithm, find $f^*$

inverse_laplacian!(fstar,cache);

Now, generate the Schur complement matrix, $S = -R^TL^{-1}R$, using create_RTLinvR,

S = create_RTLinvR(cache);

Now we set up the right-hand side of the Schur complement system, and solve for the Lagrange multipliers, $s$. We will use s as a placeholder for the right-hand side, first holding $R^T f^*$, then $\overline{f}_b - R^T f^*$, and finally, the solution of $- S s = \overline{f}_b - R^T f^*$.

s = zeros_surface(cache)
interpolate!(s,fstar,cache)
s .= fb - s
s .= -(S\s);

Finally, correct $f^*$ with $L^{-1}Rs$

f = zeros_grid(cache)
regularize!(f,s,cache)
inverse_laplacian!(f,cache)
f .+= fstar;

Now, let's look at the resulting field

plot(f,cache)
Example block output

We can see that the field external to the circle has the expected behavior, and the solution inside the circle is blank, indicating it is zero.

Let's also plot the solution for $s$ on the surface. We will plot the 'raw' result, which is rather noisy, and also apply the filtering matrix $C = \tilde{R}^T R$ several times to smooth it out.

C = create_surface_filter(cache)
plot(s,cache,label="Original solution")
s .= C^5*s;
plot!(s,cache,label="Filtered solution")
Example block output

This page was generated using Literate.jl.

  • 1Eldredge, J. D. (2021) "A method of immersed layers on Cartesian grids, with application to incompressible flows," arXiv:2103.04521.