/opt/conda/envs/dxtr/lib/python3.12/site-packages/pyvista/plotting/utilities/xvfb.py:48: PyVistaDeprecationWarning: This function is deprecated and will be removed in future version of PyVista. Use vtk-osmesa instead. warnings.warn(
The Poisson equation¶
Abstract: The Poisson equation can be seen as the "Hello world" of scientific computing, i.e. the first test to perform on a new system. In order to assess the Dxtr library, we implement this classic Boundary Value Problem (BVP) on a simple 2D circular domain and compare the results to theoretical expectations.
Note: You can download this notebook and play with it directly on your local machine.
Presentation¶
The poission equation correspond to the following classic boundary value problem: $$ \begin{cases} \Delta\phi = q &\text{in}\; \Omega \\ \phi = \phi_0 &\text{on}\; \partial\Omega \\ \end{cases} \tag{1} $$
We want to compute numerically the solution of this BVP and compare it to the theoretical expectations that can easily be derived for the specific case of a 2D circular domain.
We will consider the following specific numerical values:
- $r_0 = 1$ (radius of the domain)
- $q=-1$
- $\phi_0 = 10$.
The analytical expression of the solution of this BVP reads: $$ \phi(r) = \frac{1}{4}(1 - r^2) + 10, \tag{2} $$ with $r$ the radial distance from the center of the disk.
Dependencies¶
from __future__ import annotations
import numpy as np
import pandas as pd
import scipy.sparse as sp
import scipy.sparse.linalg as lng
import plotly.express as px
import plotly as pl
import pyvista as pv
from dxtr import SimplicialManifold, Cochain
from dxtr.complexes import disk
from dxtr.operators import laplacian
from dxtr.visu import visualize
Domain defintion¶
Using the disk domain generator available in the dxtr.complexes.example_complexes sub-module, we define three 2D circular domains of various resolutions.
Note: Since we are going to use the Hodge-Laplacian operator, that relies on the definition of a dual cellular complex, we need to implement our domains as
SimplicialManifoldinstances.
disks = {size: disk(size=size, manifold=True)
for size in ['small', 'large', 'massive']}
for size, disk in disks.items():
N0, N1, N2 = disk.shape
print(f'the {size} disk is composed of {N0} 0-simplices, {N1} 1-simplices & {N2} 2-simplices.')
the small disk is composed of 1743 0-simplices, 5092 1-simplices & 3350 2-simplices. the large disk is composed of 10308 0-simplices, 30590 1-simplices & 20283 2-simplices. the massive disk is composed of 45401 0-simplices, 135501 1-simplices & 90101 2-simplices.
Let's visualize one the generated simplicial complexes:
size = 'small'
disk = disks[size]
visualize(disk, size=2, width=1,
title=f'<b>{size} disk</b> | (0,1,2)-simplices:{disk.shape}')