C++20 library of Poisson solvers : finite volume, spectral, AMR + multigrid, Conjugate Gradient.
python/make_banner.py.
| Module | Algorithme | Coût | BC supportées |
|---|---|---|---|
linalg::thomas |
Tridiagonal direct | O(N) | toutes |
fv::Solver1D |
FV + Thomas | O(N) | Dirichlet (ε uniforme ou variable) |
fv::Solver2D |
FV + SOR red-black ω_opt | O(N³) | Dirichlet×Neumann |
iter::solve_poisson_cg |
CG / PCG Jacobi | O(N³), ~5× SOR | Dirichlet×Neumann |
spectral::DSTSolver2D |
DST-I via FFTW | O(N²·logN) | Dirichlet homogène |
amr::Quadtree + sor |
Quadtree Morton + FV hétérogène | O(nb_leaves × iter) | Dirichlet V = 0 au bord |
mg::vcycle_amr_composite |
V-cycle 2-grid composite AMR | O(nb_leaves) par cycle | Dirichlet V = 0 |
Tous matrix-free. Pseudocode de chaque solveur : docs/ALGORITHMS.md. Conventions de grille et schémas modules : docs/ARCHITECTURE.md.
poisson_cpp est l'une de quatre bibliothèques C++20 qui forment un écosystème de solveurs PDE :
| Repo | Rôle | Dépend de |
|---|---|---|
poisson_cpp (ce dépôt) |
Solveurs Poisson (Thomas, SOR, CG, DST spectral, AMR + multigrille) | indépendant |
pde_core_cpp |
Infrastructure C++ partagée entre les solveurs hyperboliques : mesh, fields templés <Cell>, AMR primitives, clustering Berger-Rigoutsos, BC périodique/outflow |
indépendant |
advection_cpp |
Advection scalaire + Burgers + advection rotative (MUSCL, WENO5) + Chorin NS incompressible (opt-in, utilise poisson_cpp pour la projection de pression) |
pde_core_cpp, poisson_cpp (opt-in) |
euler_cpp |
Euler 2D compressible + viscous NS + sources plasma + Euler-Poisson AMR self-gravity (utilise poisson_cpp pour le potentiel gravitationnel) |
pde_core_cpp, poisson_cpp (opt-in) |
Les deux solveurs hyperboliques consomment poisson_cpp via FetchContent quand leurs options de couplage (ADVECTION_USE_POISSON, EULER_USE_POISSON) sont activées.
- Python (Sphinx) : https://wolf75222.github.io/poisson_cpp/
- C++ (Doxygen) : https://wolf75222.github.io/poisson_cpp/cpp/
- C++20 (AppleClang 16+, GCC 12+, Clang 15+, MSVC 19.36+)
- CMake ≥ 3.20
- Eigen ≥ 3.4 (fetched automatiquement si absent)
- FFTW3 (optionnel, active le solveur spectral)
- OpenMP (optionnel, parallel sweeps à partir de N ≥ 384)
- Python 3.9+ (optionnel, bindings pybind11)
git clone https://github.com/wolf75222/poisson_cpp.git
cd poisson_cpp
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build # 66 tests C++ doivent passer
pytest tests/python # 50 tests Python (après pip install .)Options CMake :
| Option | Défaut | Rôle |
|---|---|---|
POISSON_BUILD_TESTS |
ON |
Compile Catch2 + toute la suite |
POISSON_BUILD_BENCHMARKS |
ON |
Compile bench_solvers et profile_cg |
POISSON_USE_OPENMP |
OFF |
Parallélise SOR + gs_smooth au-delà de N ≥ 384 |
POISSON_BUILD_PYTHON |
OFF |
Génère le module poisson_cpp via pybind11 |
# 1D Poisson + dump JSON
./build/examples/poisson_demo --problem poisson1d --N 100 --uL 10 --uR 0 \
--output /tmp/p1d.json
# SOR 2D avec historique de convergence
./build/examples/poisson_demo --problem sor2d --N 128 --uR 10 --tol 1e-10
# Spectral 2D (nécessite FFTW)
./build/examples/poisson_demo --problem spectral2d --N 256
# Scène AMR multi-charges (utilisée pour la bannière)
./build/examples/poisson_demo --problem amr_scatter --Nmin 4 --Nmax 7 \
--sigma 0.025 --output data/snapshots/amr_scatter.jsonpip install git+https://github.com/wolf75222/poisson_cpp.gitLe wheel est compilé localement par scikit-build-core. Prérequis :
compilateur C++20 et CMake ≥ 3.20. Eigen et nlohmann_json sont récupérés
automatiquement. FFTW3 est optionnel ; sans lui, DSTSolver1D/2D sont
désactivés et un RuntimeWarning à l'import donne la commande
d'installation pour ta plateforme.
!apt-get install -y libfftw3-dev > /dev/null # optionnel, pour le DST
!pip install git+https://github.com/wolf75222/poisson_cpp.git
import numpy as np, poisson_cpp as pc
g = pc.Grid2D(1.0, 1.0, 64, 64)
V, rep = pc.Solver2D(g, eps=1.0, uL=0.0, uR=10.0).solve(np.zeros((64,64)), tol=1e-8)
print(rep)Si FFTW est installé après coup, force la recompilation :
pip install --force-reinstall --no-binary poisson-cpp poisson-cppcmake -B build -DPOISSON_BUILD_PYTHON=ON
cmake --build build --target poisson_py -j
export PYTHONPATH=$PWD/build/pythonimport numpy as np
import poisson_cpp as pc
# ---- 1. Thomas (tridiagonal direct, 1D) --------------------------------
N = 100
a = np.zeros(N); b = 2.0 * np.ones(N); c = np.zeros(N); d = np.ones(N)
a[1:] = -1.0; c[:-1] = -1.0
x = pc.thomas(a, b, c, d)
print("thomas:", x[:3]) # [1.0, 2.0, ... ]
# ---- 2. Solver2D : FV + SOR red-black ω_opt auto -----------------------
grid = pc.Grid2D(1.0, 1.0, 64, 64) # [0,1]² cell-centered
sor = pc.Solver2D(grid, eps=1.0, uL=0.0, uR=10.0) # Dirichlet x, Neumann y
rho = np.zeros((64, 64))
V, report = sor.solve(rho, tol=1e-10) # returns (V, SORReport)
print(report) # SORReport(iterations=..., residual=...)
# ---- 3. Conjugate Gradient --------------------------------------------
V_cg = np.zeros((128, 128), order="F") # Fortran-order pour Eigen in-place
grid = pc.Grid2D(1.0, 1.0, 128, 128)
rep, hist = pc.solve_poisson_cg(
V_cg, np.zeros((128, 128), order="F"), grid,
uL=0.0, uR=10.0, tol=1e-10, record_history=True)
print(f"CG: {rep.iterations} iterations, residual {rep.residual:.2e}")
# ---- 4. Spectral DST-I (si FFTW disponible) ----------------------------
if pc.has_fftw3:
dst = pc.DSTSolver2D(127, 127, 1.0, 1.0, eps0=1.0)
rho_dst = np.random.randn(127, 127)
V_dst = dst.solve(rho_dst)
print("DST2D V range:", V_dst.min(), V_dst.max())python3 python/plot_figures.py all # toutes les figures de validation
python3 python/plot_cg.py # convergence CG vs SOR
python3 python/make_banner.py # bannière AMR multi-chargesFigures dans docs/figures/, interprétations dans
docs/RESULTS.md.
![]() |
![]() |
| Poisson 1D, erreur L∞ = 2.1×10⁻¹⁴ (précision machine) | Convergence spectrale, pente log-log = +2.000 |
![]() |
![]() |
| CG : 187 iter / 8 ms vs SOR 1443 / 53 ms | AMR sur Gaussienne centrée, 400 feuilles, ×10 vs uniform |
Détails dans docs/PERFORMANCE.md. A/B mesurés
avec sample / xctrace :
mg::gs_smoothN=128 : in-place red-black, −68 %.Solver2D::solveN=128 : in-place red-black +Vc_inv_précomputé, −46 %.amr::sor: précalculrhs = h²ρ/ε₀etVc_inv, −16 %.Solver2D::solve: fold Dirichlet → rhs pour débloquer SIMD, −5 %.- CG
apply_neg_laplacianN=512 :diag_matprécomputé hors hot loop, −18 %. - OpenMP (opt-in, N ≥ 384) : Solver2D + gs_smooth, ×1.5 à ×1.9.
66 tests Catch2 côté C++ + 50 tests pytest côté bindings Python. Couvrent :
- Invariants mathématiques (réciprocité de Green, linéarité, symétrie de réflexion) à 1e-13.
- Lois de conservation (Gauss, énergie, continuité D aux interfaces diélectriques) à 1e-12.
- 4 snapshots JSON vs les notebooks Python à 1e-10.
- Convergence O(h²) sur un benchmark Fourier (Jackson ch.2).
- Scaling CG en O(N), cross-check vs DST.
- Côté Python : workflow AMR + multigrille bout-en-bout, dataclasses, helpers (Morton, harmonic_mean, dump_amr_snapshot).
ctest --test-dir build # C++
pytest tests/python # PythonDétails : docs/RESULTS.md (figures de validation),
docs/PERFORMANCE.md (benchmarks A/B + profiling).
BSD-3-Clause. Voir LICENSE.




