Skip to article frontmatterSkip to article content

Elliptical PDE Solver

CNRS
MEOM

Elliptical PDE Solvers

Motivation

In many PDEs, we have the famous elliptical system of the form:

2u=fLu=F\begin{aligned} \nabla^2u &= f \\ \mathbf{Lu} &=\mathbf{F} \end{aligned}

where 2\nabla^2 is the Laplacian operator, ff is a source term, uu is the unknown, L\mathbf{L} is a matrix representation of the Laplacian operator, and F\mathbf{F} is a matrix representation of the source term. So we need to solve this equation for the unknown u\mathbf{u}. Fortunately, many PDEs have a simple linear operator, 2\nabla^2, so we can simply solve this with an inversion method.

u=L1F\mathbf{u} = \mathbf{L}^{-1}\mathbf{F}

Typically we have to use some sort of linear solver in order to do the inverse. There are traditional inversion schemes, , e.g. Jacobi, Successive OverRelaxation (SOR), Optimized SOR, etc, but these methods can be extremely expensive because they can take a long time to converge. There are other iterative schemes which have magnitudes of order of speed up, e.g. Steepest Descent, Conjugate Gradient (CG), Preconditioned CG, Multi-Grid schemes, etc. However, there is an alternative method to solving simple elliptical PDEs whereby we use the Discrete Sine Transform. These are my notes about the formulation, the use cases and also my imagined pseudo-code.

Formulation

Let’s take a field, uu, which describes some quantity of interest

u=u(x)xΩRD\begin{aligned} u =\boldsymbol{u}(\vec{\mathbf{x}}) && && \vec{\mathbf{x}}\in\Omega\sub\mathbb{R}^D \end{aligned}

and derive a time-independent solution which takes the form of a generic Elliptical PDE.

2u=f(x)xΩb(x)=buxΩ\begin{aligned} \nabla^2u &= \boldsymbol{f}(\vec{\mathbf{x}}) && && \vec{\mathbf{x}}\in\Omega \\ \boldsymbol{b}(\vec{\mathbf{x}}) &= b_u && && \vec{\mathbf{x}}\in\partial\Omega \\ \end{aligned}

Technically, we can decompose the field, uu, into two fields. For example, we could have

{u=u1+u2xΩu=u1+u2xΩ\begin{aligned} \begin{cases} u = u_1 + u_2 && && \vec{\mathbf{x}}\in\Omega \\ u = u_1 + u_2 && && \vec{\mathbf{x}}\in\partial\Omega \end{cases} \end{aligned}

We will propose one such decomposition here. We observe that all known boundary conditions can appear on the right hand side (RHS) of the PDE (5) because they are known. So we can write the decomposition of the PDE as an interior PDE and an exterior PDE:

{u=uI+uBxΩu=uI+uBxΩ\begin{aligned} \begin{cases} u = u_\mathrm{I} + u_\mathrm{B} && && \vec{\mathbf{x}}\in\Omega \\ u = u_\mathrm{I} + u_\mathrm{B} && && \vec{\mathbf{x}}\in\partial\Omega \end{cases} \end{aligned}

We can say that the interior PDE, uIu_\mathrm{I}, is zero along the boundaries and the exterior PDE, uBu_\mathrm{B}, is zero everywhere except the boundaries. Notice: The only nonzero values of the uBu_\mathrm{B} term are along the boundaries. So we can write the PDE constraint as:

2uB=fBxΩuB=buxΩ\begin{aligned} \nabla^2u_\mathrm{B} &= \boldsymbol{f}_\mathrm{B} && && \vec{\mathbf{x}}\in\Omega \\ u_\mathrm{B} &= b_u && && \vec{\mathbf{x}}\in\partial\Omega \\ \end{aligned}

where the values along the boundary Ω\partial\Omega are what we set them as and the values within the domain Ω are “unknown” and the values. So we can rewrite the solution to the PDE in (5) taking into account the decomposition.

2uI=2uB+fxΩuI=0xΩ\begin{aligned} \nabla^2u_\mathrm{I} &= -\nabla^2 u_\mathrm{B} + \boldsymbol{f} && && \vec{\mathbf{x}}\in\Omega \\ u_\mathrm{I} &= 0 && && \vec{\mathbf{x}}\in\partial\Omega \\ \end{aligned}

where we see that we’re left with Dirichlet boundary conditions (BC) for the interior PDE. The extra term 2uB\nabla^2 u_\mathrm{B} can be thought of as removing the contaminated values from the interior points. Now we can see that the solution to this PDE will satisfy the following decomposition

{u=uIxΩu=uBxΩ\begin{aligned} \begin{cases} u = u_\mathrm{I} && && \vec{\mathbf{x}}\in\Omega \\ u = u_\mathrm{B} && && \vec{\mathbf{x}}\in\partial\Omega \end{cases} \end{aligned}

whereby we simply need to solve the interior PDE given by equation (8) and then add the boundary values from our original PDE (5).

Discrete Sine Transformation

Now we have an elliptical PDE which is zero on all of the boundaries, i.e. Dirichlet boundary conditions. This means we can use ultra-fast methods to solve this like the Discrete Sine Transform (DST). This particular solver does work on linear Elliptical PDEs with Dirichlet boundary conditions.

The Laplacian operator in DST space is:

^H2=2[cos(2πnM11)Δx2+cos(2πmN11)Δy2]\hat{\nabla}_H^2 = 2\left[ \cos\left(\frac{2\pi n}{M-1}-1\right)\Delta x^{-2} + \cos\left(\frac{2\pi m}{N-1}-1\right)\Delta y^{-2} \right]

There are two DST types that we can use. The first one is the DST-I transform given by this equation

DST-I[x]k=n=0N1xnsin[πN1(n+1)(k+1)]k=0,,N1\begin{aligned} \text{DST-I}[x]_k &= \sum_{n=0}^{N-1} x_n \sin\left[ \frac{\pi}{N-1}(n+1)(k+1)\right] && && k=0,\ldots, N-1 \end{aligned}

This transformation is useful when we have an unknown, uu, a RHS, rr, and Dirichlet BCs all on the same grid. The other type of DST transform, i.e. DST-II, and it is given by

DST-I[x]k=n=0N1xnsin[πN(n+12)(k+1)]k=0,,N1\begin{aligned} \text{DST-I}[x]_k &= \sum_{n=0}^{N-1} x_n \sin\left[ \frac{\pi}{N}(n+\frac{1}{2})(k+1)\right] && && k=0,\ldots, N-1 \end{aligned}

This transformation is useful with u,ru,r are defined at the cell center but the Dirichlet BCs are on the cell corners.

So both the interior points and the boundary values are both satisfied. Now, let’s say that the interior points, x\vec{\mathbf{x}},

{u1=uxΩu1=0xΩ{u2=0xΩu2=uxΩ\begin{aligned} \begin{cases} u_1 = u && && \vec{\mathbf{x}}\in\Omega \\ u_1 = 0 && && \vec{\mathbf{x}}\in\partial\Omega \end{cases} \\ \begin{cases} u_2 = 0 && && \vec{\mathbf{x}}\in\Omega \\ u_2 = u && && \vec{\mathbf{x}}\in\partial\Omega \end{cases} \end{aligned}

To rename them, let’s call PDE 1, u1u_1, the solution of the PDE at the interior points with dirichlet boundaries, uIu_I, and let’s call PDE 2, u2u_2, the solution of the PDE at the boundaries with all interior points being zero, uBu_B.

So going back to the original PDE (5), we can incorporate these constraints into the solutions:

Use Cases

There are some PDEs where we define a PDE in terms of a derived variable however, we have access to some measurements of the original variable. For example, let’s say that we observe some variable, ξ, that has a relationship with a PDE field, uu.

N[u;θ](x)=ξ\begin{aligned} \mathcal{N}[u;\theta](\vec{\mathbf{x}}) &= \xi \\ \end{aligned}
(α2β)u=ξ\begin{aligned} (\alpha\nabla^2 - \beta)u &= \xi \end{aligned}

where θ={α,β}\theta=\{\alpha,\beta\}

Practical Algorithm

Define field of interest

u=u(x)x=[x,y]xΩ\begin{aligned} u &= u(\mathbf{x}) && && \mathbf{x}= [x, y]^{\top} &&\mathbf{x}\in\Omega \end{aligned}
domain: Domain = ...
u: Field = init_field(domain)
f: Field = init_source(domain)

Solve PDE and BCs on the Full Field

N[u](x)=fxΩBC[u](x)=bxΩ\begin{aligned} \mathcal{N}[u](\mathbf{x}) &= f && && \mathbf{x}\in\Omega \\ \mathcal{BC}[u](\mathbf{x}) &= b && && \mathbf{x}\in\partial\Omega \end{aligned}
u = PDESolver(f, rhs_fn, bcs_fn)

Parse the field into a zero field but maintaining the boundaries

uB=0xΩuB=bxΩ\begin{aligned} u_\mathrm{B} &= 0 && && \mathbf{x}\in\Omega \\ u_\mathrm{B} &= b && && \mathbf{x}\in\partial\Omega \end{aligned}
u_b = zero_interior(u)
u_b = bcs_fn(u)

Apply the same PDE and Boundary Conditions on the empty Field

N[uB](x)=fxΩBC[uB](x)=bxΩ\begin{aligned} \mathcal{N}[u_\mathrm{B}](\mathbf{x}) &= f && && \mathbf{x}\in\Omega \\ \mathcal{BC}[u_\mathrm{B}](\mathbf{x}) &= b && && \mathbf{x}\in\partial\Omega \end{aligned}
f_b = PDESolver(u_b, rhs_fn, bcs_fn)

Remove the Boundary Effects on the Solution

uI=uuBxΩ\begin{aligned} u_\mathrm{I} &= u - u_\mathrm{B} && && \mathbf{x}\in\Omega \end{aligned}
f_I = f[1:-1,1:-1] - f_b[1:-1,1:-1]

Do Inversion for Elliptical PDE

LuI=FuI=L1F\begin{aligned} \mathbf{Lu}_\mathrm{I} &= \mathbf{F} \\ \mathbf{u}_\mathrm{I} &= \mathbf{L}^{-1}\mathbf{F} \end{aligned}
matvec_Ax: Callable = ...
u_I = LinearSolve(matvec_Ax, b=f_I)

Add the boundaries to the field

u=uIxΩu=uBxΩ\begin{aligned} u &= u_\mathrm{I} && && \mathbf{x}\in\Omega \\ u &= u_\mathrm{B} && && \mathbf{x}\in\partial\Omega \end{aligned}
u = zeros_like(u)
u[1:-1,1:-1] = u_I
u[bc_indices] = u_B

PseudoCde

High Level

# get derived variable
q, u_bc = load_state(...)
# define callable function
matvec_Ax: Callable = ...
# solve for variable
u: Field = LinearSolve(q, matvec_Ax)
# add boundary conditions
u: Field = boundary_conditions(u, u_bv)
# calculate RHS
rhs: Field = RHS(u, q)
# step once
u_new: Field = TimeStepper(dt, u, rhs)