Weak gravitational lensing mass reconstruction via P3 FEM-BEM coupled boundary value problems, Morozov-regularised Tikhonov inversion, and inverse scattering support recovery.
FEMMI reconstructs the projected mass density
with shear components
The inverse problem (recovering
| Feature | Kaiser-Squires (1993) | FEMMI |
|---|---|---|
| Boundary condition | Periodic / Dirichlet | Exact exterior via BEM |
| Regularisation | Manual smoothing | Morozov discrepancy principle |
| Mass-sheet degeneracy | Present | Resolved ( |
| Inverse method | Direct linear | MAP + SVD support recovery |
Full derivations are in MATH.md. Key ideas:
FEM-BEM coupling. FEMMI couples a P3 FEM interior to a boundary element
method on
where
Shear operators. Physical shear is computed from P3 reference-element
Hessians via the covariant transform
Morozov regularisation. The MAP estimate minimises $|F\kappa - \gamma_{\mathrm{obs}}|^2 + \lambda|\kappa|R^2$ with $R = M + \mathcal{l}^2 K$ (Matern-Wiener prior). $\lambda$ is selected automatically by Brent's method on the discrepancy functional $D(\lambda) = |F\kappa\lambda - \gamma_{\mathrm{obs}}| - c\delta$ (C&K Thm 10.4).
Inverse scattering. The forward operator
femmi/
|-- __init__.py
|-- types.py # Mesh namedtuple
|-- mesh.py # Structured and adaptive P3 mesh generation
|-- basis.py # P3 Lagrange basis functions (10 DOF/element)
|-- assembly.py # P3 element stiffness/mass assembly; Poisson solve
|-- bem.py # BEM: V_h, K_h, M_b; Calderon operator
|-- operators.py # K, M, S1, S2, A_coupled; FEMOperators dataclass
|-- forward.py # DifferentiableForward (JAX custom_vjp)
|-- inverse.py # MAPReconstructor, kaiser_squires
|-- regularization.py # MorozovSelector, estimate_noise_level
`-- svd_analysis.py # SVD of F, Picard diagnostic, FactorizationIndicator, LSM
tests/
|-- test_fem_bem_coupling.py # BEM matrices (V_h, K_h, M_b, Calderon)
|-- test_coupled_pipeline.py # FEM-BEM pipeline invariants
|-- test_morozov.py # Morozov lambda selection, monotonicity
|-- test_factorization.py # SVD, Picard, support recovery indicators
|-- test_convergence_p3.py # O(h^4) L2 Poisson convergence
|-- test_convergence.py # Forward operator gamma convergence
`-- test_regression.py # End-to-end NFW reconstruction
examples/
|-- smpy_comparison.py # FEMMI vs Kaiser-Squires benchmark
|-- generate_presentation_figures.py # Figures (for final presentation in class)
`-- visualize_results.py # SVD modes, Picard, convergence plots
pip install -e ".[dev]"Requires: JAX >= 0.4, SciPy >= 1.11, NumPy >= 1.25, matplotlib.
64-bit arithmetic is mandatory. FEMMI enforces this at import time.
For a
import numpy as np
from femmi.operators import build_operators
from femmi.forward import DifferentiableForward
from femmi.inverse import MAPReconstructor
from femmi.regularization import estimate_noise_level
# Build mesh and operators (20x20 structured P3 mesh on [-2.5, 2.5]^2)
ops = build_operators(nx=20, ny=20, xmin=-2.5, xmax=2.5, ymin=-2.5, ymax=2.5)
# Forward model: kappa -> (gamma1, gamma2)
nodes = np.array(ops.mesh.nodes)
kappa_true = np.exp(-(nodes[:, 0]**2 + nodes[:, 1]**2) / (2 * 0.5**2))
g1, g2 = ops.forward(kappa_true)
# MAP reconstruction with automatic lambda (Morozov)
noise_std = estimate_noise_level(np.concatenate([g1, g2]), method='mad')
fwd = DifferentiableForward(ops, lam_reg=1e-3)
rec = MAPReconstructor(fwd, noise_std=noise_std, wiener_length=0.5)
kappa_map, result = rec.reconstruct(g1_obs, g2_obs)# Adaptive mesh near a circular mask
from femmi.operators import build_operators_adaptive
ops_a = build_operators_adaptive(
nx=20, ny=20, xmin=-2.5, xmax=2.5, ymin=-2.5, ymax=2.5,
mask_center=(0., 0.), mask_radius=0.6, refine_factor=3,
)# SVD and support recovery
from femmi.svd_analysis import compute_svd, FactorizationIndicator
svd = compute_svd(ops, n_singular=40)
fi = FactorizationIndicator(ops, svd_result=svd)
test_grid = np.column_stack([XX.ravel(), YY.ravel()]) # shape (n_test, 2)
W = fi.indicator_map(test_grid) # large inside support(kappa)Forward solve (two solves per MAP iteration):
Adjoint gradient (for L-BFGS):
Morozov
BEM assembly: Diagonal blocks of
Forward operator on mesh sequence
| Mesh |
|
Theory |
|---|---|---|
Poisson solve (P3, smooth RHS, unit square):
| Mesh |
|
Theory |
|---|---|---|
| 3.86 | ||
| 3.90 | ||
| 3.97 |
- Colton, D. & Kress, R. (2013). Inverse Acoustic and Electromagnetic Scattering Theory, 3rd ed. Springer.
- Steinbach, O. (2008). Numerical Approximation Methods for Elliptic Boundary Value Problems. Springer.
- Sauter, S. & Schwab, C. (2011). Boundary Element Methods. Springer.
- Kirsch, A. (1998). Characterization of the shape of a scattering obstacle. Inverse Problems, 14, 1489.
- Colton, D. & Kirsch, A. (1996). A simple method for solving inverse scattering problems. Inverse Problems, 12, 383.
- Morozov, V. A. (1966). On the solution of functional equations by the method of regularization. Soviet Math. Doklady, 7, 414.
- Kaiser, N. & Squires, G. (1993). Mapping the dark matter with weak gravitational lensing. ApJ, 404, 441.
- Dunavant, D. A. (1985). High degree efficient symmetrical Gaussian quadrature rules for the triangle. IJNME, 21(6), 1129.
- Brenner, S. & Scott, R. (2008). The Mathematical Theory of Finite Element Methods, 3rd ed. Springer.