mixle-pde 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mixle_pde-0.7.0/LICENSE +21 -0
- mixle_pde-0.7.0/PKG-INFO +347 -0
- mixle_pde-0.7.0/README.md +321 -0
- mixle_pde-0.7.0/mixle_pde/__init__.py +567 -0
- mixle_pde-0.7.0/mixle_pde/_operator.py +119 -0
- mixle_pde-0.7.0/mixle_pde/attenuation.py +456 -0
- mixle_pde-0.7.0/mixle_pde/basin.py +175 -0
- mixle_pde-0.7.0/mixle_pde/beam.py +160 -0
- mixle_pde-0.7.0/mixle_pde/boundaries.py +274 -0
- mixle_pde-0.7.0/mixle_pde/capabilities.py +2449 -0
- mixle_pde-0.7.0/mixle_pde/dynamics.py +683 -0
- mixle_pde-0.7.0/mixle_pde/earth_scenarios.py +221 -0
- mixle_pde-0.7.0/mixle_pde/elastic.py +336 -0
- mixle_pde-0.7.0/mixle_pde/elastic_aniso.py +450 -0
- mixle_pde-0.7.0/mixle_pde/electrostatics.py +202 -0
- mixle_pde-0.7.0/mixle_pde/em_diffusion.py +206 -0
- mixle_pde-0.7.0/mixle_pde/em_diffusion_3d.py +500 -0
- mixle_pde-0.7.0/mixle_pde/env_data.py +349 -0
- mixle_pde-0.7.0/mixle_pde/fem.py +329 -0
- mixle_pde-0.7.0/mixle_pde/field_assimilation.py +768 -0
- mixle_pde-0.7.0/mixle_pde/field_gauss_newton.py +183 -0
- mixle_pde-0.7.0/mixle_pde/field_inversion.py +308 -0
- mixle_pde-0.7.0/mixle_pde/field_mcmc.py +192 -0
- mixle_pde-0.7.0/mixle_pde/field_priors.py +225 -0
- mixle_pde-0.7.0/mixle_pde/flow.py +106 -0
- mixle_pde-0.7.0/mixle_pde/flow3d.py +183 -0
- mixle_pde-0.7.0/mixle_pde/gas_dynamics.py +465 -0
- mixle_pde-0.7.0/mixle_pde/geo_observations.py +622 -0
- mixle_pde-0.7.0/mixle_pde/geophysics.py +744 -0
- mixle_pde-0.7.0/mixle_pde/guided_wave.py +369 -0
- mixle_pde-0.7.0/mixle_pde/heat.py +168 -0
- mixle_pde-0.7.0/mixle_pde/helmholtz_pml.py +220 -0
- mixle_pde-0.7.0/mixle_pde/induced_polarization.py +179 -0
- mixle_pde-0.7.0/mixle_pde/inverse.py +238 -0
- mixle_pde-0.7.0/mixle_pde/latent.py +585 -0
- mixle_pde-0.7.0/mixle_pde/maxwell.py +191 -0
- mixle_pde-0.7.0/mixle_pde/mesh.py +787 -0
- mixle_pde-0.7.0/mixle_pde/migration.py +252 -0
- mixle_pde-0.7.0/mixle_pde/misfit.py +225 -0
- mixle_pde-0.7.0/mixle_pde/multiphysics.py +190 -0
- mixle_pde-0.7.0/mixle_pde/nonlinear.py +191 -0
- mixle_pde-0.7.0/mixle_pde/normal_modes.py +399 -0
- mixle_pde-0.7.0/mixle_pde/observations.py +906 -0
- mixle_pde-0.7.0/mixle_pde/ops.py +180 -0
- mixle_pde-0.7.0/mixle_pde/parabolic_equation.py +292 -0
- mixle_pde-0.7.0/mixle_pde/pde.py +351 -0
- mixle_pde-0.7.0/mixle_pde/pde_solve.py +231 -0
- mixle_pde-0.7.0/mixle_pde/plate.py +172 -0
- mixle_pde-0.7.0/mixle_pde/pnp.py +155 -0
- mixle_pde-0.7.0/mixle_pde/poroelastic.py +281 -0
- mixle_pde-0.7.0/mixle_pde/posterior_calibration.py +238 -0
- mixle_pde-0.7.0/mixle_pde/posterior_query.py +372 -0
- mixle_pde-0.7.0/mixle_pde/potential_fields.py +239 -0
- mixle_pde-0.7.0/mixle_pde/propagation_inverse.py +190 -0
- mixle_pde-0.7.0/mixle_pde/ray_scattering.py +299 -0
- mixle_pde-0.7.0/mixle_pde/reasoning.py +262 -0
- mixle_pde-0.7.0/mixle_pde/refractivity.py +142 -0
- mixle_pde-0.7.0/mixle_pde/rock_physics.py +137 -0
- mixle_pde-0.7.0/mixle_pde/sample_update.py +265 -0
- mixle_pde-0.7.0/mixle_pde/schrodinger.py +80 -0
- mixle_pde-0.7.0/mixle_pde/shape.py +65 -0
- mixle_pde-0.7.0/mixle_pde/smoluchowski.py +247 -0
- mixle_pde-0.7.0/mixle_pde/sound_speed.py +161 -0
- mixle_pde-0.7.0/mixle_pde/spectral_flow.py +215 -0
- mixle_pde-0.7.0/mixle_pde/two_phase.py +408 -0
- mixle_pde-0.7.0/mixle_pde/viscoelastic.py +235 -0
- mixle_pde-0.7.0/mixle_pde/wave.py +78 -0
- mixle_pde-0.7.0/mixle_pde/wave3d.py +90 -0
- mixle_pde-0.7.0/mixle_pde/wave_pml.py +92 -0
- mixle_pde-0.7.0/mixle_pde/wavenumber_integration.py +296 -0
- mixle_pde-0.7.0/mixle_pde.egg-info/PKG-INFO +347 -0
- mixle_pde-0.7.0/mixle_pde.egg-info/SOURCES.txt +75 -0
- mixle_pde-0.7.0/mixle_pde.egg-info/dependency_links.txt +1 -0
- mixle_pde-0.7.0/mixle_pde.egg-info/requires.txt +15 -0
- mixle_pde-0.7.0/mixle_pde.egg-info/top_level.txt +1 -0
- mixle_pde-0.7.0/pyproject.toml +50 -0
- mixle_pde-0.7.0/setup.cfg +4 -0
mixle_pde-0.7.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Grant Boquet
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mixle_pde-0.7.0/PKG-INFO
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mixle-pde
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: PDE/ODE-constrained Bayesian inverse problems for mixle (a mixle.ppl plugin).
|
|
5
|
+
Author-email: Grant Boquet <grant.boquet@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gmboquet/mixle-pde
|
|
8
|
+
Project-URL: Repository, https://github.com/gmboquet/mixle-pde
|
|
9
|
+
Keywords: pde,inverse problems,bayesian,mixle
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: mixle>=0.7.0
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Requires-Dist: scipy
|
|
16
|
+
Requires-Dist: torch>=2.0
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
19
|
+
Requires-Dist: pytest-xdist; extra == "test"
|
|
20
|
+
Provides-Extra: lint
|
|
21
|
+
Requires-Dist: ruff==0.15.17; extra == "lint"
|
|
22
|
+
Provides-Extra: docs
|
|
23
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
24
|
+
Requires-Dist: furo; extra == "docs"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# mixle-pde
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
PDE and ODE-constrained Bayesian inverse problems for [mixle](https://github.com/gmboquet/mixle).
|
|
33
|
+
|
|
34
|
+
mixle-pde is a `mixle.ppl` plugin. Importing it wires a stack of differentiable forward solvers and
|
|
35
|
+
PDE-constrained state-space models into mixle's probabilistic-programming surface through mixle's
|
|
36
|
+
extension hooks. It never patches mixle: the plugin depends on mixle, not the reverse.
|
|
37
|
+
|
|
38
|
+
The organizing idea is that many quantities are observable only through a dynamical system they drive.
|
|
39
|
+
A rate constant shows up in a decay curve, a contaminant source in downstream concentrations, a
|
|
40
|
+
subsurface velocity in a seismic record, a diffusivity in a steady temperature field. mixle-pde gives
|
|
41
|
+
you the forward physics as differentiable solvers and the inverse machinery to recover a posterior over
|
|
42
|
+
the hidden drivers from noisy, partial, indirect observations.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
mixle-pde depends directly on `mixle`, `numpy`, `scipy`, and `torch` (the `ops` namespace every solver
|
|
47
|
+
runs through is a torch backend), so a plain install brings everything the solvers need.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install -e . # from a checkout
|
|
51
|
+
pip install -e ".[test]" # with the test extras
|
|
52
|
+
pip install -e ".[docs]" # with the docs extras
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
The Sphinx manual starts at [`docs/index.rst`](docs/index.rst). It includes installation notes, the
|
|
58
|
+
package map, solver/API navigation, validation guidance, generated API reference pages, and the
|
|
59
|
+
release-facing 3D/4D field modeling guide.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
make -C docs html SPHINXOPTS="-W --keep-going"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Release notes and the current changelog are in
|
|
66
|
+
[`docs/release-notes.rst`](docs/release-notes.rst) and
|
|
67
|
+
[CHANGELOG.md](CHANGELOG.md).
|
|
68
|
+
|
|
69
|
+
## Quickstart
|
|
70
|
+
|
|
71
|
+
### Recover a hidden driver from a dynamical system
|
|
72
|
+
|
|
73
|
+
`Differential` is an observation whose forward model is the solution of an ODE or PDE. The latent
|
|
74
|
+
drivers are `free` handles (or a shared field a `GP` carries); a single callback supplies the physics
|
|
75
|
+
through a backend-agnostic `ops` namespace, so it never imports a tensor library.
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import numpy as np
|
|
79
|
+
from mixle.ppl import free, joint
|
|
80
|
+
from mixle_pde import Differential
|
|
81
|
+
|
|
82
|
+
t = np.linspace(0.0, 5.0, 40)
|
|
83
|
+
y_obs = np.exp(-0.7 * t) + 0.02 * np.random.default_rng(0).standard_normal(t.size)
|
|
84
|
+
|
|
85
|
+
k = free(1, name="k", support="positive")
|
|
86
|
+
obs = Differential(y_obs, drivers=[k], y0=1.0, t_grid=t, scale=0.05,
|
|
87
|
+
rhs=lambda u, t, p, ops: -p.k * u) # dy/dt = -k y
|
|
88
|
+
post = joint([obs]).fit(how="laplace")
|
|
89
|
+
k_mean, k_sd = post.posterior("k") # ~0.7 with a calibrated sd
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Swap the `rhs`/`forward` callback for a spatial PDE and hand it a `GP` field to recover a whole source
|
|
93
|
+
map instead of a scalar. Fit with `how="laplace"` (or `"map"` for a point estimate, `"gauss_newton"`,
|
|
94
|
+
`"vi"`); `posterior` returns a mean and sd once a curvature-bearing fit like Laplace has run.
|
|
95
|
+
|
|
96
|
+
### Run a forward solver directly
|
|
97
|
+
|
|
98
|
+
Every solver steps through the same `ops` namespace, so the forward run is differentiable end to end.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import numpy as np
|
|
102
|
+
from mixle_pde import WaveEquation3D
|
|
103
|
+
from mixle_pde.ops import make_ops
|
|
104
|
+
|
|
105
|
+
ops = make_ops()
|
|
106
|
+
n = 48
|
|
107
|
+
solver = WaveEquation3D(n, dt=0.4 / (n - 1), absorb_width=6) # CFL-safe step, sponge layer
|
|
108
|
+
|
|
109
|
+
c2 = ops.tensor(np.ones(n**3)) # squared wave speed per cell
|
|
110
|
+
u0 = np.zeros((n, n, n)); u0[n // 2, n // 2, n // 2] = 1.0 # a point disturbance
|
|
111
|
+
state = solver.pack(u0.ravel(), np.zeros(n**3))
|
|
112
|
+
for _ in range(100):
|
|
113
|
+
state = solver.step(state, c2, ops)
|
|
114
|
+
field = solver.displacement(state).reshape(n, n, n)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Fit a PDE-constrained state space
|
|
118
|
+
|
|
119
|
+
`PDE(operator)` is a latent-field model whose linear state transition is fixed by the physics. Fit it on
|
|
120
|
+
a `(T, m)` array of noisy field snapshots: a Kalman/RTS smoother recovers the latent field while EM
|
|
121
|
+
estimates the process and observation noise.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from mixle_pde import PDE, DiffusionOperator
|
|
125
|
+
|
|
126
|
+
model = PDE(DiffusionOperator(0.1, n)).fit(field_snapshots, dt=0.1)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Solver catalog
|
|
130
|
+
|
|
131
|
+
Release-facing documentation for the 3D/4D field posterior stack lives in
|
|
132
|
+
[`docs/field-modeling.rst`](docs/field-modeling.rst). It covers
|
|
133
|
+
latent fields, observations, priors, inversion, assimilation, geoscience
|
|
134
|
+
likelihoods, posterior queries, posterior calibration diagnostics, meshes, and readiness checks.
|
|
135
|
+
|
|
136
|
+
### Forward solvers
|
|
137
|
+
|
|
138
|
+
All are differentiable through the `ops` backend and each ships with a test that checks it against an
|
|
139
|
+
exact analytical solution (a normal-mode frequency, a decaying eigenmode, a Poiseuille profile).
|
|
140
|
+
|
|
141
|
+
| Solver | Equation | Method |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `WaveEquation2D`, `WaveEquation3D` | acoustic wave | leapfrog, sponge absorbing layer |
|
|
144
|
+
| `NavierStokes2D`, `NavierStokes3D` | incompressible Navier-Stokes | streamfunction-vorticity (2D), Chorin projection (3D) |
|
|
145
|
+
| `TwoPhaseFlow2D` | immiscible two-fluid flow (core-annular / lubricated pipelining) | diffuse-interface phase field, variable-property Chorin projection |
|
|
146
|
+
| `Maxwell3D` | source-free Maxwell curl equations | FDTD on a Yee staggered grid |
|
|
147
|
+
| `ElasticWave3D` | isotropic elastodynamics (P and S waves) | velocity-stress staggered grid (Virieux) |
|
|
148
|
+
| `AnisotropicElasticWave3D` | anisotropic (VTI/TTI) elastodynamics | Thomsen / Bond-rotated stiffness, velocity-stress staggered grid |
|
|
149
|
+
| `ViscoacousticWave1D` | constant-Q attenuating wave | GSLS memory variables (tau-method) |
|
|
150
|
+
| `BiotPoroelastic1D` | Biot poroelasticity (fast + slow P) | velocity-stress-pressure staggered grid |
|
|
151
|
+
| `TransientHeat` | transient heterogeneous heat conduction | divergence-form + checkpointed time stepping |
|
|
152
|
+
| `SAFEPlate`, `safe_dispersion` | guided-wave (Lamb / SH) dispersion | semi-analytical finite elements |
|
|
153
|
+
| `EulerBernoulliBeam` | slender-beam bending and vibration | 1D fourth-order (biharmonic) |
|
|
154
|
+
| `KirchhoffPlate` | thin-plate bending, static and dynamic | 2D biharmonic |
|
|
155
|
+
|
|
156
|
+
More equations live in their own modules: `gas_dynamics` (1D compressible Euler with an exact Riemann
|
|
157
|
+
solver), `schrodinger` (time-dependent Schrodinger, split-step Fourier), `spectral_flow` (pseudo-spectral
|
|
158
|
+
2D/3D Navier-Stokes with an optional Smagorinsky LES closure), `wave_pml` (2D acoustic wave with a
|
|
159
|
+
perfectly-matched-layer boundary), and `fem` (P1 triangular finite elements for Poisson).
|
|
160
|
+
|
|
161
|
+
The reusable mesh layer is `SimplexMesh`: `box_simplex_mesh` creates deterministic simplex meshes in any
|
|
162
|
+
dimension, `delaunay_mesh` wraps SciPy Delaunay for scattered point clouds, and `space_time_mesh` extrudes a
|
|
163
|
+
3D tetrahedral mesh through time into a 4D simplex mesh. This is the geometry foundation for moving-domain
|
|
164
|
+
and transient finite-element work; adaptive remeshing, ALE/FSI coupling, and curved/high-order elements are
|
|
165
|
+
still future solver work.
|
|
166
|
+
|
|
167
|
+
The 3D/4D Earth posterior surface is modular, built from these pieces:
|
|
168
|
+
|
|
169
|
+
- **Fields.** `Field3D` / `PosteriorField3D` represent one gridded physical property with units,
|
|
170
|
+
optional bounds, posterior mean/MAP, covariance, credible intervals, and sampling.
|
|
171
|
+
- **Observations and forward operators.** `Observation`, `ForwardOperator`, and
|
|
172
|
+
`ForwardOperatorRegistry` give measurements a common geometry/noise/provenance contract; the
|
|
173
|
+
built-in registry operators cover gravity, magnetics, and direct borehole/sensor samples.
|
|
174
|
+
`dc_resistivity_forward_operator` wraps the DC/ERT forward as a nonlinear log-conductivity
|
|
175
|
+
observation with local finite-difference sensitivities. `layered_mt_forward_operator`,
|
|
176
|
+
`aem_layered_forward_operator`, `mt_2d_te_forward_operator`, `mt_3d_forward_operator`, and
|
|
177
|
+
`csem_3d_forward_operator` do the same for 1D layered MT/AEM, 2D TE-mode, 3D curl-curl
|
|
178
|
+
magnetotelluric, and 3D controlled-source EM soundings, all mapping log-conductivity to
|
|
179
|
+
real-valued geophysical observations.
|
|
180
|
+
- **Linear-Gaussian and Gauss-Newton inversion.** `FieldGaussianPrior` supplies graph-Matern
|
|
181
|
+
smoothness (dense or sparse CSR precision matrices); `linear_gaussian_invert` performs exact
|
|
182
|
+
linear-Gaussian inversion; `gauss_newton_invert` adds bounded MAP/Laplace inversion for
|
|
183
|
+
properties such as porosity, susceptibility, or concentration. `sparse_linear_gaussian_invert`
|
|
184
|
+
stores the posterior in sparse precision-factor form, using sparse covariance solves for
|
|
185
|
+
marginals and linear derived quantities without ever retaining a dense covariance matrix.
|
|
186
|
+
- **4D time-lapse assimilation.** `PosteriorField4D`, `assimilate_4d`, and
|
|
187
|
+
`assimilate_4d_ensemble` add a time axis through exact Kalman/RTS smoothing (linear
|
|
188
|
+
observations) or ensemble Kalman filtering (nonlinear observations), exposing each time slice
|
|
189
|
+
as an ordinary `PosteriorField3D`.
|
|
190
|
+
- **Depth-aware and cross-property priors.** `depth_weights`, `depth_weighted_marginal_precision`,
|
|
191
|
+
`depth_weighted_marginal_precision_sparse`, `CrossPropertyPrior`, and
|
|
192
|
+
`joint_linear_gaussian_invert` let observations of one property regularize another.
|
|
193
|
+
- **Geochemistry and geochronology likelihoods.** `GeochemAssay`, `MultiElementAssay`,
|
|
194
|
+
`assay_log_likelihood`, `multi_element_assay_log_likelihood`, and `additive_log_ratio` add
|
|
195
|
+
detection-limit/compositional and multi-element covariance/batch-effect likelihoods.
|
|
196
|
+
`BiostratConstraint` / `biostrat_log_likelihood` add fossil range-zone constraints;
|
|
197
|
+
`GeochronologyAge`, `StratigraphicCorrelation`, and `FaciesIntervalConstraint` add isotopic age
|
|
198
|
+
measurements, relative-age/horizon constraints, and facies/environment interval evidence. These
|
|
199
|
+
likelihoods can be converted into field observations where a project defines the property mapping.
|
|
200
|
+
- **Posterior extraction and calibration.** `posterior_query` extracts point/section/region
|
|
201
|
+
marginals, linear derived quantities such as total anomalous mass, low-rank or diagonal Gaussian
|
|
202
|
+
summaries, and ensemble samples. `posterior_calibration` measures synthetic-truth coverage,
|
|
203
|
+
held-out observation fit, uncertainty inflation away from data, and insufficient-observation flags.
|
|
204
|
+
|
|
205
|
+
Not yet implemented: full reaction-path geochemistry, paleoecological/basin-process simulators, full
|
|
206
|
+
truncated multivariate censoring for multi-element assays, production-scale adjoint sensitivities,
|
|
207
|
+
iterative sparse posterior solvers, and full airborne loop/flight-line AEM geometry. The ensemble 4D
|
|
208
|
+
path is a stochastic Gaussian-summary reference, not a production particle/MCMC smoother.
|
|
209
|
+
|
|
210
|
+
### Inverse and inference layer
|
|
211
|
+
|
|
212
|
+
| Surface | What it does |
|
|
213
|
+
| --- | --- |
|
|
214
|
+
| `Differential` | an observation whose forward model is an ODE/PDE solution; recover latent drivers (rate constants, source fields, initial states, coefficients) with `joint([...]).fit(how=...)` |
|
|
215
|
+
| `PDE(operator).fit` | PDE-constrained latent-field state space (Kalman/RTS smoother + EM) over `DiffusionOperator`, `AdvectionOperator`, `AdvectionDiffusionOperator`, or any operator you `register_dynamics_operator` |
|
|
216
|
+
| `pde_solve` | adjoint-capable sparse PDE solves (differentiable Poisson / divergence-form) for large-scale inverse problems |
|
|
217
|
+
| `nonlinear_solve` | differentiable nonlinear steady solves `F(u;θ)=0` (Newton forward, implicit-function-theorem adjoint); the base for nonlinear elliptic inverse problems |
|
|
218
|
+
| `rtm_image`, `born_modeling`, `lsrtm_step` | reverse-time migration and least-squares / Born imaging over the wave steppers |
|
|
219
|
+
| `misfit` (`envelope` / `xcorr` / `wasserstein`) | cycle-skip-robust FWI misfit functionals for any wave forward |
|
|
220
|
+
| `helmholtz_pml_operator` | frequency-domain Helmholtz with a PML boundary and a complex modulus (viscoacoustic attenuation) |
|
|
221
|
+
| `shape_optimize`, `level_set_material` | level-set shape optimization and inverse shape inference |
|
|
222
|
+
| `CoupledPDESystem`, `solve_poisson` | nD steady diffusion/Poisson and node-coupled multiphysics |
|
|
223
|
+
|
|
224
|
+
### Geophysics
|
|
225
|
+
|
|
226
|
+
Near-surface forward operators plus an Occam-style regularized inversion engine that inverts any
|
|
227
|
+
differentiable forward without per-problem prior tuning: `gravity_point_sensitivity`,
|
|
228
|
+
`magnetic_dipole_sensitivity`, `dc_resistivity` (ERT), `straight_ray_operator` (traveltime tomography),
|
|
229
|
+
`depth_weighting`, `roughness_operator`, `regularized_gauss_newton`, and `cross_gradient` /
|
|
230
|
+
`joint_inversion` for structural coupling of several property models.
|
|
231
|
+
|
|
232
|
+
Electromagnetics in the diffusive (induction) regime, distinct from the wave-regime `Maxwell3D`:
|
|
233
|
+
`layered_mt_impedance` (1D magnetotelluric / airborne EM), `mt_2d_te` (2D magnetotelluric), and `mt_3d` /
|
|
234
|
+
`csem_3d` (a 3D edge-element / Yee curl-curl solver for CSEM, magnetotellurics, borehole induction, and
|
|
235
|
+
eddy-current NDE), plus `cole_cole_conductivity` / `sip_forward` for spectral induced polarization
|
|
236
|
+
(disseminated-sulphide detection). Potential fields extend to `gravity_gradient_tensor` (full-tensor
|
|
237
|
+
gradiometry) and `magnetic_vector_sensitivity` / `magnetic_gradient_tensor`.
|
|
238
|
+
|
|
239
|
+
### Petroleum systems
|
|
240
|
+
|
|
241
|
+
`geotherm` (steady conductive geotherm for a layered column) and `easy_ro` / `easy_ro_profile` (the
|
|
242
|
+
EASY%Ro vitrinite-reflectance maturation model of Sweeney & Burnham 1990), differentiable forwards for
|
|
243
|
+
heat-flow and thermal-history inversion. `gassmann_ksat` / `fluid_substitute` give closed-form
|
|
244
|
+
differentiable Gassmann fluid substitution, turning elastic-FWI velocities into reservoir variables
|
|
245
|
+
(porosity, saturation).
|
|
246
|
+
|
|
247
|
+
### Biomolecular electrostatics and reaction-diffusion
|
|
248
|
+
|
|
249
|
+
`linearized_pbe` and `nonlinear_pbe` solve the Poisson-Boltzmann equation (linear Debye-Huckel and the
|
|
250
|
+
full sinh form) for biomolecular electrostatics, with `reaction_field_energy` for MM-PBSA-style binding
|
|
251
|
+
free energy. `pnp_equilibrium` is the equilibrium Poisson-Nernst-Planck ion-channel model, and
|
|
252
|
+
`smoluchowski_rate_radial` / `smoluchowski_rate_box` give diffusion-limited association on-rates. All
|
|
253
|
+
build on the differentiable `nonlinear_solve` keystone.
|
|
254
|
+
|
|
255
|
+
### Sonar and radar propagation
|
|
256
|
+
|
|
257
|
+
Long-range sonar and radar are the same problem: propagation through a range-varying medium. The shared
|
|
258
|
+
keystone is `ParabolicEquation2D`, a range-marched split-step Fourier one-way propagator that serves both
|
|
259
|
+
by swapping only the environmental potential and the boundary. Underwater it marches on the acoustic index
|
|
260
|
+
from `mackenzie` / `unesco` sound speed c(T,S,depth); in the troposphere it marches on the modified
|
|
261
|
+
refractivity from `refractivity` / `modified_refractivity` (ITU-R P.453) so radar ducting falls out. It is
|
|
262
|
+
differentiable, so it drops into `Differential`.
|
|
263
|
+
|
|
264
|
+
Around it: `boundaries` (seabed Rayleigh reflection with the critical grazing angle, rough-surface coherent
|
|
265
|
+
loss, and the radar Fresnel surface impedance); `attenuation` (Thorp / Francois-Garrison for seawater,
|
|
266
|
+
ITU-R P.676 gaseous and P.838 rain for the atmosphere) feeding the solvers' complex-modulus `Q` slot;
|
|
267
|
+
`NormalModes1D`, a KRAKEN-style differentiable depth-mode solver verified against the Pekeris waveguide and
|
|
268
|
+
cross-checked against the PE; and `WavenumberIntegration1D`, the OASES-style full-wave reference. For small
|
|
269
|
+
scenes and targets, `po_rcs` / `knife_edge_diffraction` / `two_ray_pattern` / `multipath_power` give
|
|
270
|
+
asymptotic radar cross sections and urban multipath.
|
|
271
|
+
|
|
272
|
+
The inverse problems come for free on the `Differential` stack: `refractivity_from_clutter` recovers an
|
|
273
|
+
atmospheric duct from radar clutter, and `ocean_sound_speed_inversion` recovers a sound-speed anomaly from a
|
|
274
|
+
received acoustic field. `env_data` assembles real profiles and bathymetry/terrain into the range-depth
|
|
275
|
+
coefficient fields (differentiable interpolation + seabed masking), with import-guarded loaders for GEBCO,
|
|
276
|
+
World Ocean Atlas / Argo, DEM, and ERA5 data behind an optional extra.
|
|
277
|
+
|
|
278
|
+
### Cross-modal reasoning
|
|
279
|
+
|
|
280
|
+
`JointPotentialField`, `SpatialFieldStore`, and `MechanisticFieldReasoner` fuse geophysical modalities
|
|
281
|
+
into a spatial belief with uncertainty, feeding mixle's `reason` surface.
|
|
282
|
+
|
|
283
|
+
### Modeling readiness
|
|
284
|
+
|
|
285
|
+
Applications should not infer solver availability from imports or README claims. The package exposes a
|
|
286
|
+
small capability catalog and deterministic readiness checks:
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
from mixle_pde import readiness_report, assert_required_modeling
|
|
290
|
+
|
|
291
|
+
print(readiness_report())
|
|
292
|
+
assert_required_modeling()
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The required modeling gate currently checks:
|
|
296
|
+
|
|
297
|
+
- 3D tetrahedral meshes, direct 4D simplex meshes, and 3D-to-4D space-time extrusion.
|
|
298
|
+
- Censored geochemical assay likelihoods, compositional transforms, biostratigraphic range-zone likelihoods,
|
|
299
|
+
geochronology age likelihoods, stratigraphic correlation constraints, and facies/environment intervals with
|
|
300
|
+
provenance and units.
|
|
301
|
+
- The common observation/forward-operator contract for gravity, magnetics, and borehole/sensor samples.
|
|
302
|
+
- Exact 3D linear-Gaussian field inversion and bounded-field Gauss-Newton MAP/Laplace inversion.
|
|
303
|
+
- Nonlinear DC/ERT log-conductivity posterior observations through the Gauss-Newton path.
|
|
304
|
+
- 4D random-walk Kalman assimilation plus RTS smoothing, and ensemble nonlinear 4D assimilation, with
|
|
305
|
+
posterior time-slice extraction.
|
|
306
|
+
- Depth weighting, graph-Matern smoothness, and cross-property Gaussian coupling.
|
|
307
|
+
- Posterior extraction for points, regions/volumes, sections, linear derived quantities, low-rank/diagonal
|
|
308
|
+
summaries, and ensemble samples.
|
|
309
|
+
- Posterior calibration diagnostics for truth coverage, held-out fit, uncertainty inflation, and insufficient
|
|
310
|
+
observations.
|
|
311
|
+
- PDE-constrained state-space smoothing and forecasting.
|
|
312
|
+
- Transient diffusion / heat-equation decay against a discrete analytical rate.
|
|
313
|
+
- Potential-field geophysics sign and linearity.
|
|
314
|
+
- Mechanistic field reconstruction from sparse sensors.
|
|
315
|
+
- 2D acoustic wave propagation stability.
|
|
316
|
+
|
|
317
|
+
These checks are intentionally cheap smoke-and-physics scenarios. They do not replace the full analytic
|
|
318
|
+
test suite; they give applications and CI a quick answer to "is the required modeling surface actually
|
|
319
|
+
present and runnable in this environment?"
|
|
320
|
+
|
|
321
|
+
## How it works
|
|
322
|
+
|
|
323
|
+
Every solver and inverse callback talks to a single `ops` namespace (`mixle_pde/ops.py`): a float64
|
|
324
|
+
torch backend that provides N-dimensional finite differences (`ops.grad`, `ops.laplacian`), a
|
|
325
|
+
differentiable sparse Poisson solve with adjoint gradients (`ops.sparse_solve`), and the small array
|
|
326
|
+
algebra the steppers need. Because the physics is written against `ops` and never imports torch
|
|
327
|
+
directly, a forward solver is differentiable end to end, which is exactly what lets it drop into the
|
|
328
|
+
`Differential` inverse stack and be fit by gradient-based MAP, Laplace, Gauss-Newton, or VI.
|
|
329
|
+
|
|
330
|
+
## Tests
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
pytest # the full suite (-n auto via pyproject)
|
|
334
|
+
pytest tests/wave3d_test.py -q # one file
|
|
335
|
+
pytest tests/capabilities_test.py -q
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Maintainers & contributors
|
|
339
|
+
|
|
340
|
+
Maintained by **Grant Boquet** ([@gmboquet](https://github.com/gmboquet) ·
|
|
341
|
+
grant.boquet@gmail.com).
|
|
342
|
+
|
|
343
|
+
Contributions, issues, and discussion are welcome — open a PR or an issue.
|
|
344
|
+
|
|
345
|
+
## License
|
|
346
|
+
|
|
347
|
+
MIT — see [LICENSE](https://github.com/gmboquet/mixle-pde/blob/main/LICENSE).
|