mantis-rtm 0.1.1.dev0__py3-none-any.whl
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.
- mantis/__init__.py +5 -0
- mantis/_version.py +24 -0
- mantis/diff_lib.py +1937 -0
- mantis/generate_equation_system.py +1975 -0
- mantis/live_plot_lib.py +623 -0
- mantis/model.py +942 -0
- mantis/monitor_plots.py +171 -0
- mantis/monolithic_solver.py +904 -0
- mantis/parallel_video.py +523 -0
- mantis/plot_data_new.py +1363 -0
- mantis/solvers_numba.py +219 -0
- mantis_rtm-0.1.1.dev0.dist-info/METADATA +175 -0
- mantis_rtm-0.1.1.dev0.dist-info/RECORD +17 -0
- mantis_rtm-0.1.1.dev0.dist-info/WHEEL +5 -0
- mantis_rtm-0.1.1.dev0.dist-info/entry_points.txt +6 -0
- mantis_rtm-0.1.1.dev0.dist-info/licenses/LICENSE +661 -0
- mantis_rtm-0.1.1.dev0.dist-info/top_level.txt +1 -0
mantis/solvers_numba.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Numba-accelerated numerical kernels for direct assembled reactive transport solvers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import numba as nb
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@nb.njit(fastmath=True)
|
|
12
|
+
def solve_tridiagonal_thomas(
|
|
13
|
+
ab: np.ndarray,
|
|
14
|
+
b: np.ndarray,
|
|
15
|
+
out: np.ndarray,
|
|
16
|
+
c_prime: np.ndarray,
|
|
17
|
+
) -> None:
|
|
18
|
+
"""
|
|
19
|
+
O(N) In-place Thomas algorithm (TDMA) for tridiagonal systems in SciPy banded (1, 1) layout.
|
|
20
|
+
|
|
21
|
+
Matrix layout in ab (shape 3, N):
|
|
22
|
+
- row 0: superdiagonal (ab[0, 1:] contains A[i, i+1] for i = 0..N-2)
|
|
23
|
+
- row 1: main diagonal (ab[1, :] contains A[i, i] for i = 0..N-1)
|
|
24
|
+
- row 2: subdiagonal (ab[2, :-1] contains A[i+1, i] for i = 0..N-2)
|
|
25
|
+
|
|
26
|
+
b: RHS vector of shape (N,)
|
|
27
|
+
out: solution vector of shape (N,), updated in-place
|
|
28
|
+
c_prime: work scratch array of shape (N - 1,)
|
|
29
|
+
"""
|
|
30
|
+
n = len(b)
|
|
31
|
+
denom0 = ab[1, 0]
|
|
32
|
+
c_prime[0] = ab[0, 1] / denom0
|
|
33
|
+
out[0] = b[0] / denom0
|
|
34
|
+
|
|
35
|
+
# Forward elimination
|
|
36
|
+
for i in range(1, n - 1):
|
|
37
|
+
ai = ab[2, i - 1]
|
|
38
|
+
denom = ab[1, i] - ai * c_prime[i - 1]
|
|
39
|
+
c_prime[i] = ab[0, i + 1] / denom
|
|
40
|
+
out[i] = (b[i] - ai * out[i - 1]) / denom
|
|
41
|
+
|
|
42
|
+
ai_last = ab[2, n - 2]
|
|
43
|
+
denom_last = ab[1, n - 1] - ai_last * c_prime[n - 2]
|
|
44
|
+
out[n - 1] = (b[n - 1] - ai_last * out[n - 2]) / denom_last
|
|
45
|
+
|
|
46
|
+
# Back substitution
|
|
47
|
+
for i in range(n - 2, -1, -1):
|
|
48
|
+
out[i] -= c_prime[i] * out[i + 1]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@nb.njit(fastmath=True)
|
|
52
|
+
def compute_species_residual_wrms(
|
|
53
|
+
curr_val: np.ndarray,
|
|
54
|
+
prev_val: np.ndarray,
|
|
55
|
+
inner_tol: float,
|
|
56
|
+
atol: float,
|
|
57
|
+
) -> float:
|
|
58
|
+
"""
|
|
59
|
+
Computes WRMS norm for a single species:
|
|
60
|
+
sqrt( (1/N) * sum( ( |c_curr - c_prev| / (inner_tol * |c_curr| + atol) )^2 ) )
|
|
61
|
+
"""
|
|
62
|
+
n = len(curr_val)
|
|
63
|
+
sum_sq = 0.0
|
|
64
|
+
for i in range(n):
|
|
65
|
+
c = curr_val[i]
|
|
66
|
+
diff = abs(c - prev_val[i])
|
|
67
|
+
scale = inner_tol * abs(c) + atol
|
|
68
|
+
ratio = diff / scale
|
|
69
|
+
if np.isnan(ratio) or np.isinf(ratio):
|
|
70
|
+
return np.inf
|
|
71
|
+
sum_sq += ratio * ratio
|
|
72
|
+
return np.sqrt(sum_sq / n)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@nb.njit(fastmath=True)
|
|
76
|
+
def compute_species_residual_linf(
|
|
77
|
+
curr_val: np.ndarray,
|
|
78
|
+
prev_val: np.ndarray,
|
|
79
|
+
inner_tol: float,
|
|
80
|
+
atol: float,
|
|
81
|
+
) -> float:
|
|
82
|
+
"""
|
|
83
|
+
Computes L-infinity norm for a single species:
|
|
84
|
+
max( |c_curr - c_prev| / (inner_tol * |c_curr| + atol) )
|
|
85
|
+
"""
|
|
86
|
+
n = len(curr_val)
|
|
87
|
+
max_ratio = 0.0
|
|
88
|
+
for i in range(n):
|
|
89
|
+
c = curr_val[i]
|
|
90
|
+
diff = abs(c - prev_val[i])
|
|
91
|
+
scale = inner_tol * abs(c) + atol
|
|
92
|
+
ratio = diff / scale
|
|
93
|
+
if np.isnan(ratio) or np.isinf(ratio):
|
|
94
|
+
return np.inf
|
|
95
|
+
if ratio > max_ratio:
|
|
96
|
+
max_ratio = ratio
|
|
97
|
+
return max_ratio
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@nb.njit(fastmath=True)
|
|
101
|
+
def solve_block_tridiagonal_thomas(
|
|
102
|
+
A: np.ndarray,
|
|
103
|
+
B: np.ndarray,
|
|
104
|
+
C: np.ndarray,
|
|
105
|
+
D: np.ndarray,
|
|
106
|
+
out: np.ndarray,
|
|
107
|
+
C_prime: np.ndarray,
|
|
108
|
+
D_prime: np.ndarray,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""
|
|
111
|
+
O(N * S^3) In-place Block Tridiagonal Matrix Algorithm (Block TDMA) for 1D monolithic systems.
|
|
112
|
+
|
|
113
|
+
Solves the block-tridiagonal linear system:
|
|
114
|
+
A_i * U_{i-1} + B_i * U_i + C_i * U_{i+1} = D_i for i = 0 .. N-1
|
|
115
|
+
|
|
116
|
+
where:
|
|
117
|
+
- N is the number of 1D spatial cells
|
|
118
|
+
- S is the number of coupled chemical species
|
|
119
|
+
- A has shape (N, S): diagonal elements of subdiagonal spatial block A_i (coupling to cell i-1)
|
|
120
|
+
- B has shape (N, S, S): dense diagonal block for cell i (transport + chemical Jacobian)
|
|
121
|
+
- C has shape (N, S): diagonal elements of superdiagonal spatial block C_i (coupling to cell i+1)
|
|
122
|
+
- D has shape (N, S): RHS / residual vector at each cell
|
|
123
|
+
- out has shape (N, S): solution vector, updated in-place
|
|
124
|
+
- C_prime has shape (N, S, S): scratch array for forward block elimination
|
|
125
|
+
- D_prime has shape (N, S): scratch array for forward RHS elimination
|
|
126
|
+
"""
|
|
127
|
+
N, S = D.shape
|
|
128
|
+
M = np.empty((S, S), dtype=np.float64)
|
|
129
|
+
piv = np.empty(S, dtype=np.int64)
|
|
130
|
+
y = np.empty(S, dtype=np.float64)
|
|
131
|
+
rhs = np.empty(S, dtype=np.float64)
|
|
132
|
+
|
|
133
|
+
# Forward elimination sweep
|
|
134
|
+
for i in range(N):
|
|
135
|
+
# 1. Form M_i = B_i - A_i * C'_{i-1}
|
|
136
|
+
for r in range(S):
|
|
137
|
+
for c in range(S):
|
|
138
|
+
M[r, c] = B[i, r, c]
|
|
139
|
+
if i > 0:
|
|
140
|
+
for r in range(S):
|
|
141
|
+
ar = A[i, r]
|
|
142
|
+
for c in range(S):
|
|
143
|
+
M[r, c] -= ar * C_prime[i - 1, r, c]
|
|
144
|
+
|
|
145
|
+
# 2. Form rhs = D_i - A_i * D'_{i-1}
|
|
146
|
+
for r in range(S):
|
|
147
|
+
rhs[r] = D[i, r]
|
|
148
|
+
if i > 0:
|
|
149
|
+
for r in range(S):
|
|
150
|
+
rhs[r] -= A[i, r] * D_prime[i - 1, r]
|
|
151
|
+
|
|
152
|
+
# 3. LU factorization of M with partial pivoting
|
|
153
|
+
for k in range(S):
|
|
154
|
+
piv[k] = k
|
|
155
|
+
for k in range(S):
|
|
156
|
+
max_r = k
|
|
157
|
+
max_v = abs(M[k, k])
|
|
158
|
+
for r in range(k + 1, S):
|
|
159
|
+
v = abs(M[r, k])
|
|
160
|
+
if v > max_v:
|
|
161
|
+
max_v = v
|
|
162
|
+
max_r = r
|
|
163
|
+
if max_r != k:
|
|
164
|
+
tmp_p = piv[k]
|
|
165
|
+
piv[k] = piv[max_r]
|
|
166
|
+
piv[max_r] = tmp_p
|
|
167
|
+
for col in range(S):
|
|
168
|
+
tmp = M[k, col]
|
|
169
|
+
M[k, col] = M[max_r, col]
|
|
170
|
+
M[max_r, col] = tmp
|
|
171
|
+
diag = M[k, k]
|
|
172
|
+
if abs(diag) > 1e-30:
|
|
173
|
+
for r in range(k + 1, S):
|
|
174
|
+
M[r, k] /= diag
|
|
175
|
+
f = M[r, k]
|
|
176
|
+
for col in range(k + 1, S):
|
|
177
|
+
M[r, col] -= f * M[k, col]
|
|
178
|
+
|
|
179
|
+
# 4. Solve M * D'_i = rhs
|
|
180
|
+
# Forward substitution Ly = P * rhs
|
|
181
|
+
for r in range(S):
|
|
182
|
+
val = rhs[piv[r]]
|
|
183
|
+
for col in range(r):
|
|
184
|
+
val -= M[r, col] * y[col]
|
|
185
|
+
y[r] = val
|
|
186
|
+
# Back substitution Ux = y
|
|
187
|
+
for r in range(S - 1, -1, -1):
|
|
188
|
+
val = y[r]
|
|
189
|
+
for col in range(r + 1, S):
|
|
190
|
+
val -= M[r, col] * D_prime[i, col]
|
|
191
|
+
D_prime[i, r] = val / (M[r, r] if abs(M[r, r]) > 1e-30 else 1e-30)
|
|
192
|
+
|
|
193
|
+
# 5. If i < N - 1, solve M * C'_i[:, j] = C[i, j] * e_j for each column j
|
|
194
|
+
if i < N - 1:
|
|
195
|
+
for j in range(S):
|
|
196
|
+
cj = C[i, j]
|
|
197
|
+
# Forward Ly = P * (cj * e_j)
|
|
198
|
+
for r in range(S):
|
|
199
|
+
val = cj if piv[r] == j else 0.0
|
|
200
|
+
for col in range(r):
|
|
201
|
+
val -= M[r, col] * y[col]
|
|
202
|
+
y[r] = val
|
|
203
|
+
# Back Ux = y
|
|
204
|
+
for r in range(S - 1, -1, -1):
|
|
205
|
+
val = y[r]
|
|
206
|
+
for col in range(r + 1, S):
|
|
207
|
+
val -= M[r, col] * C_prime[i, col, j]
|
|
208
|
+
C_prime[i, r, j] = val / (M[r, r] if abs(M[r, r]) > 1e-30 else 1e-30)
|
|
209
|
+
|
|
210
|
+
# Back substitution sweep
|
|
211
|
+
for r in range(S):
|
|
212
|
+
out[N - 1, r] = D_prime[N - 1, r]
|
|
213
|
+
for i in range(N - 2, -1, -1):
|
|
214
|
+
for r in range(S):
|
|
215
|
+
val = D_prime[i, r]
|
|
216
|
+
for col in range(S):
|
|
217
|
+
val -= C_prime[i, r, col] * out[i + 1, col]
|
|
218
|
+
out[i, r] = val
|
|
219
|
+
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mantis-rtm
|
|
3
|
+
Version: 0.1.1.dev0
|
|
4
|
+
Summary: MANTIS: A Monolithic Assembly of Nonlinear Transport Interactions Solver
|
|
5
|
+
Author-email: Uli Wortmann <uli.wortmann@utoronto.ca>
|
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/uliw/mantis
|
|
8
|
+
Project-URL: Repository, https://github.com/uliw/mantis
|
|
9
|
+
Project-URL: Issues, https://github.com/uliw/mantis/issues
|
|
10
|
+
Keywords: reactive transport modeling,reaction transport modeling,geochemistry,monolithic solver,diagenesis,block newton,advection diffusion reaction
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy
|
|
25
|
+
Requires-Dist: pandas
|
|
26
|
+
Requires-Dist: matplotlib
|
|
27
|
+
Requires-Dist: numba
|
|
28
|
+
Requires-Dist: pint
|
|
29
|
+
Requires-Dist: watchdog
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: ruff; extra == "dev"
|
|
32
|
+
Requires-Dist: twine; extra == "dev"
|
|
33
|
+
Requires-Dist: build; extra == "dev"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: pytest; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
37
|
+
Requires-Dist: scipy; extra == "test"
|
|
38
|
+
Provides-Extra: doc
|
|
39
|
+
Requires-Dist: sphinx; extra == "doc"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# MANTIS: A *M*onolithic *A*ssembly of *N*onlinear *T*ransport *I*nteractions *S*olver
|
|
43
|
+
|
|
44
|
+
**MANTIS** is a high-performance 1D reactive-transport modeling (RTM) framework written in Python, designed to simulate stiff, tightly coupled advection-diffusion-reaction networks.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What is MANTIS?
|
|
49
|
+
|
|
50
|
+
Reactive-transport systems in natural environments—such as marine sediments, groundwater aquifers, and geochemical reactors—involve simultaneous transport (advection, molecular diffusion, bio-irrigation, and bioturbation) coupled with complex networks of nonlinear chemical, mineral, and biological reactions.
|
|
51
|
+
|
|
52
|
+
MANTIS provides:
|
|
53
|
+
- **Declarative Geochemical Model Definition**: Define chemical species, phases, reaction stoichiometries, and kinetic limiters (Monod, inhibition, threshold laws) in intuitive, human-readable Python configuration files.
|
|
54
|
+
- **Automated Symbolic Jacobian Generation**: Automatically parses reaction networks and compiles analytical chemical Jacobians using symbolic computer algebra (`SymPy`), eliminating error-prone manual differentiation.
|
|
55
|
+
- **Monolithic Block Newton-Raphson Solver**: Solves all chemical species and transport equations simultaneously in a coupled block-tridiagonal system using a Numba-accelerated Block Thomas algorithm.
|
|
56
|
+
- **Adaptive Time Stepping**: Features PID-controlled adaptive time stepping with automatic step rejection and convergence recovery.
|
|
57
|
+
- **Unified Declarative Interface**: Configure and run simulations through `DiageneticModel`, complete with automatic CLI argument handling, checkpointing, publication-ready summary plots, and asynchronous time-lapse video generation.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## How is MANTIS Different from Other Python RTM Packages?
|
|
62
|
+
|
|
63
|
+
Most existing Python and geochemical reactive-transport modeling packages rely on **operator splitting** (such as Sequential Non-Iterative Approach [SNIA] or Sequential Iterative Approach [SIA]) or **decoupled Picard (Gauss-Seidel) iterations**:
|
|
64
|
+
|
|
65
|
+
1. **Monolithic Coupling vs. Operator Splitting**:
|
|
66
|
+
- *Operator splitting* alternates between solving pure transport and pure batch chemistry over a time step. While simple, it introduces splitting errors and often requires tiny time steps ($\Delta t$ on the order of seconds or hours) to avoid artificial oscillations or numerical divergence when reactions are fast and stiff.
|
|
67
|
+
- *Picard iterations* solve each chemical species sequentially, lagging cross-species couplings from the previous iteration. At sharp reaction fronts (e.g., where sulfide meets oxygen or ferric iron), this decoupling frequently causes severe numerical lag oscillations.
|
|
68
|
+
- **MANTIS solves the entire system monolithically**: Transport and reactions for all species are assembled into a single unified block-tridiagonal linear system at each Newton step. This achieves true simultaneous coupling and quadratic Newton convergence.
|
|
69
|
+
|
|
70
|
+
2. **Exact Symbolic Jacobians vs. Finite Differences**:
|
|
71
|
+
- Rather than approximating derivatives via costly numerical perturbations (finite differences) or requiring users to manually code and maintain hundreds of lines of Jacobian terms, MANTIS computes exact analytical Jacobians symbolically via `SymPy` ahead of time and compiles them to optimized machine code.
|
|
72
|
+
|
|
73
|
+
3. **High-Performance Native Numba Engine**:
|
|
74
|
+
- The core block-tridiagonal solver and residual evaluations run directly in compiled machine code via Numba. This delivers C-like performance without external heavy PDE framework dependencies.
|
|
75
|
+
|
|
76
|
+
4. **Unconditional Numerical Stability**:
|
|
77
|
+
- Thanks to its fully implicit monolithic formulation, MANTIS does not suffer from Courant-Friedrichs-Lewy (CFL) or diffusion time step stability restrictions, enabling long-term simulations (centuries to millennia) with large time steps.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Scope and General Applicability
|
|
82
|
+
|
|
83
|
+
While the bundled examples and default templates are geared toward **marine sediment early diagenesis** (e.g., organic matter mineralization cascades, dissimilatory iron and sulfate reduction, iron sulfide and pyrite precipitation, and stable sulfur isotope fractionation $\delta^{34}\text{S}$), **the underlying numerical formulation is domain-agnostic**.
|
|
84
|
+
|
|
85
|
+
The monolithic advection-diffusion-reaction solver can be directly applied to any 1D reactive transport problem involving:
|
|
86
|
+
- Stiff, multi-species nonlinear reaction networks
|
|
87
|
+
- Combined particulate (solid) and solute (porewater/fluid) phases
|
|
88
|
+
- Advection, molecular and eddy diffusion, and nonlocal exchange processes
|
|
89
|
+
- Stable isotope fractionation and multi-isotope tracking
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Current Limitations
|
|
94
|
+
|
|
95
|
+
While MANTIS provides robust and unconditionally stable solutions for stiff reactive transport, the current release has the following limitations:
|
|
96
|
+
|
|
97
|
+
1. **Time-Invariant Spatial Mesh**:
|
|
98
|
+
- The spatial grid $z$ is static throughout the simulation. Dynamic grid adaptation, moving boundaries, or expanding domains (e.g., physical sediment column growth over time) are not currently supported.
|
|
99
|
+
2. **Time-Invariant Porosity**:
|
|
100
|
+
- The porosity profile $\phi(z)$ is stationary in time (steady-state compaction). Transient sediment compaction or compaction-driven dynamic fluid expulsion over time is not currently modeled.
|
|
101
|
+
3. **Time-Invariant Temperature**:
|
|
102
|
+
- The temperature profile $T(z)$ is steady-state. Dynamic thermal evolution and time-dependent diffusion coefficients or rate constants driven by non-isothermal thermal transients are not currently supported.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Installation
|
|
107
|
+
|
|
108
|
+
MANTIS requires Python 3.12 or newer. Clone the repository and install in editable mode:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/uliw/mantis.git
|
|
112
|
+
cd mantis
|
|
113
|
+
pip install -e .
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Dependencies include `numpy`, `pandas`, `matplotlib`, `numba`, `sympy`, `chempy`, and `watchdog`.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Quick Start Example
|
|
121
|
+
|
|
122
|
+
A typical simulation directory contains declarative configuration files defining species, reactions, rate constants, and plot layouts:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from mantis import DiageneticModel
|
|
126
|
+
|
|
127
|
+
# 1. Initialize the model (auto-detects species.py, reactions, constants in the directory)
|
|
128
|
+
model = DiageneticModel(
|
|
129
|
+
reactions="fes_reactions.py",
|
|
130
|
+
constants="kinetic_constants_slow.py",
|
|
131
|
+
layout="plot_layout.py",
|
|
132
|
+
experiment="marine_diagenesis",
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# 2. Configure environmental and grid parameters
|
|
136
|
+
model.configure(
|
|
137
|
+
max_depth="0.5 m",
|
|
138
|
+
t_end="2 kyr",
|
|
139
|
+
dt_init="1 day",
|
|
140
|
+
dt_max="1 year",
|
|
141
|
+
w="0.2 cm/yr",
|
|
142
|
+
phi=0.8,
|
|
143
|
+
bioturbation={
|
|
144
|
+
"BT0": "4 cm^2/year",
|
|
145
|
+
"depth": "6 cm",
|
|
146
|
+
"attenuation": "2 cm",
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# 3. Enable CLI flag overrides (--video, --solver-tol, --t-end, etc.)
|
|
151
|
+
model.parse_cli_args()
|
|
152
|
+
|
|
153
|
+
# 4. Run the simulation
|
|
154
|
+
result = model.run()
|
|
155
|
+
|
|
156
|
+
# 5. Export results and summary plots
|
|
157
|
+
df, csv_path = result.save_csv()
|
|
158
|
+
result.plot_summary()
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Running Tests
|
|
164
|
+
|
|
165
|
+
Run the unit test suite using `pytest`:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pytest
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
This project is licensed under the GPL-3.0 License. See the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
mantis/__init__.py,sha256=Pkpwm4bu1o2hEdFHQL65jl8DSV71rTm2BrrfUYzmIbs,201
|
|
2
|
+
mantis/_version.py,sha256=C7_2xyONPOLOpAzR9m7Juwyz8wzzwt9M7TtjzKDO_so,533
|
|
3
|
+
mantis/diff_lib.py,sha256=qTTH11q01uSVYKIK9a8F8KQ8juX1IOFhC2Co1Y9QuD8,66362
|
|
4
|
+
mantis/generate_equation_system.py,sha256=Ke_lgkCdz-4Jvjdj7l6rK9H-S7KbhJSYo2u8Ft2LXDU,109938
|
|
5
|
+
mantis/live_plot_lib.py,sha256=kSTzb6wHNUzLt5p16mjJW-Ro3JphQ08hmtzyfHQuRS4,21827
|
|
6
|
+
mantis/model.py,sha256=Um0Z4mBfMDERl3oRNHHhokwofD24dYqtnNiQucC3O3w,40771
|
|
7
|
+
mantis/monitor_plots.py,sha256=Thm0PVeZJSQI4FdYWnixKpAaoEL4i0aX1uS6xiydb8Y,5408
|
|
8
|
+
mantis/monolithic_solver.py,sha256=Rbk7rFYIuX-DCY_WcTxPh4L6WF9CVHGzkHka1u4r-xM,37019
|
|
9
|
+
mantis/parallel_video.py,sha256=82hDPUJmzyF1QjmXkIExjGxepeTc8lKA3tSBJh9BuAE,16964
|
|
10
|
+
mantis/plot_data_new.py,sha256=dzM9ZKv_kM16Qp6Y43NfRF2Kmqg7cc-v_6CNsctJiiA,45232
|
|
11
|
+
mantis/solvers_numba.py,sha256=cDUX-tD_SX6OiJ8e4pNQrN6lS9dBw2nnS7qC-np6KQw,7057
|
|
12
|
+
mantis_rtm-0.1.1.dev0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
13
|
+
mantis_rtm-0.1.1.dev0.dist-info/METADATA,sha256=XhBZoVB3XbeVrwMDErCApFsyu0HhiQVJ82HpZOAPDPs,8554
|
|
14
|
+
mantis_rtm-0.1.1.dev0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
15
|
+
mantis_rtm-0.1.1.dev0.dist-info/entry_points.txt,sha256=XKk3i1AqyWf20_zgSsECVGLewZVW7c_qEf6L37IyvkY,304
|
|
16
|
+
mantis_rtm-0.1.1.dev0.dist-info/top_level.txt,sha256=pHGQmbUmUmGR68I95aUwKhubm_r957NOoGxwoGHlRbI,7
|
|
17
|
+
mantis_rtm-0.1.1.dev0.dist-info/RECORD,,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
generate-equation-system = mantis.generate_equation_system:main
|
|
3
|
+
generate-equations = mantis.generate_equation_system:main
|
|
4
|
+
generate_equation_system = mantis.generate_equation_system:main
|
|
5
|
+
generate_equations = mantis.generate_equation_system:main
|
|
6
|
+
plot_data_new = mantis.plot_data_new:main
|