101: 1D Laplace equation
Let $\Omega=(\gamma_1,\gamma_2)$ with $\gamma_1=0$, $\gamma_2=1$. This is the simplest second order boundary value problem (BVP) for a partial differential equation (PDE):
\[-\Delta u =0\\ u(\gamma_1)=g_1\\ u(\gamma_2)=g_2.\]
We replace the Dirichlet boundary condition by a Robin boundary condition with a penalty parameter $\frac{1}{\varepsilon}$:
\[\nabla u(\gamma_1) + \frac{1}{\varepsilon}(u(\gamma_1)-g_1)=0 \\ -\nabla u(\gamma_2) + \frac{1}{\varepsilon}(u(\gamma_2)-g_2) =0\]
This penalty method for the implementation of Dirichlet boundary conditions is used throughout VoronoiFVM.
In order to discretize it, we choose collocation points $\gamma_1=x_1 < x_2 < \dots < x_n=\gamma_2$.
For instance, we can choose 6 collocation points in $(0,1)$: From these, we create a discretization grid structure for working with the method.
This implicitly creates a number of control volumes $\omega_k $ around each discretization point $x_k$: Let $\sigma_{k,k+1}=\frac{x_k+x_{k+1}}{2}$. Then $\omega_1=(\gamma_1,\sigma_{1,2})$, $\omega_k= (\sigma_{k-1,k}, \sigma_{k,k+1})$ for $k=2\dots n-1$, $\omega_{n}=(\sigma_{n-1,n},\gamma_2)$.
x1 x2 x3 x4 x5 x6
o-----o-----o-----o-----o-----o
|--|-----|-----|-----|-----|--|
ω1 ω2 ω3 ω4 ω5 ω6
For each $\omega_k$, we integrate the equation
\[\begin{aligned} 0&=\int_{\omega_k} -\Delta u d\omega= -\int_{\partial \omega_k} \nabla u ds\\ &= \begin{cases} u'(\sigma_{1,2}) - u'(0)& k=1\\ u'(\sigma_{k,k+1}) - u'(\sigma_{k-1,k}) & 1<k<n\\ u'(1)- u'(\sigma_{n,n+1})&k=n \end{cases}\\ &\approx \begin{cases} \frac{1}{x_2-x_1} g(u_1,u_2) + \frac{1}{\varepsilon}(u_1-0)& k=1\\ \frac{1}{x_k-x_{k-1}}g(u_k,u_{k-1}) -\frac{1}{x_{k+1}-x_{k}}g(u_{k+1},u_{k}) & 1<k<n\\ \frac{1}{\varepsilon}(u_n-1)+ \frac{1}{x_n-x_{n-1}} g(u_{n},u_{n-1})&k=n \end{cases} \end{aligned}\]
In the last equation, we wrote $u_k=u(x_k)$ and $g(u_k,u_l)=u_k-u_l$. For the interior interfaces between control volumes, we replaced $u'$ by a difference quotient. In the boundary control volumes, we replaced $u'$ by the boundary conditions.
In the example below, we fix a number of species and write a Julia function describing $g$, we create a physics record, and a finite volume system with one unknown species and a dense matrix to describe it's degrees of freedom (the matrix used to calculate the solution is sparse). We give the species the number 1 and enable it for grid region number one 1. Then, we set boundary conditions for species 1 at $\gamma_1, \gamma_2$.
We create a zero initial value and a solution vector and initialize them.
With these data, we solve the system.
We wrap this example and all later ones into a module structure. This allows to load all of them at once into the REPL without name clashes. We shouldn't forget the corresponding end statement.
module Example101_Laplace1D
using VoronoiFVM, ExtendableGrids
function main()
ispec = 1 ## Index of species we are working with
# Flux function which describes the flux
# between neighboring control volumes
function flux!(f, u, edge, data)
f[1] = u[1, 1] - u[1, 2]
end
function bcond!(f, u, node, data)
boundary_dirichlet!(f, u, node; region = 1, value = 0)
boundary_dirichlet!(f, u, node; region = 2, value = 1)
end
# Create a one dimensional discretization grid
# Each grid cell belongs to a region marked by a region number
# By default, there is only one region numbered with 1
grid = simplexgrid(0:0.2:1)
# Create a finite volume system
sys = VoronoiFVM.System(grid; flux = flux!, breaction = bcond!, species = ispec)
# Solve stationary problem
solution = solve(sys; inival = 0)
# Return test value
return sum(solution)
end
using Test
function runtests()
@test main() ≈ 3.0
end
end
This page was generated using Literate.jl.