Skip to content

Commit e4085bf

Browse files
authored
Refactor matrix building and add Jacobian sparsity
Refactor build_matrices function and add attach_jacobian_sparsity function.
1 parent 4e07936 commit e4085bf

File tree

1 file changed

+33
-56
lines changed

1 file changed

+33
-56
lines changed
Lines changed: 33 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,58 @@
1-
# chromosim/numerics/build_matrices.py
2-
"""
3-
Finite-volume derivative matrices in z for 1D packed-column models.
4-
5-
This is a direct Python/NumPy/SciPy port of the MATLAB build_matrices.m:
6-
7-
- First derivative (D1): backward/upwind stencil, inlet row is zeroed
8-
because the inlet boundary condition is handled explicitly in the ODE.
9-
- Second derivative (D2): central stencil with:
10-
* inlet ghost-cell treatment: D2[0,0] = -2/dz^2 (Dirichlet-type)
11-
* Danckwerts-style outlet: D2[-1,-1] = 1/dz^2
12-
13-
Returns the same 'par' object/dict with .D1 and .D2 as CSR sparse matrices.
14-
"""
15-
161
from __future__ import annotations
2+
from collections.abc import Mapping
173
import numpy as np
184
from scipy.sparse import diags
5+
from .sparsity import sparsity_pattern_multi
196

207
def _get(par, key):
21-
"""Support both dicts and objects with attributes."""
22-
try:
23-
return getattr(par, key)
24-
except AttributeError:
8+
"""Get a parameter from either a Mapping (dict) or an object with attrs."""
9+
if isinstance(par, Mapping):
2510
return par[key]
11+
return getattr(par, key)
2612

2713
def _set(par, key, value):
28-
"""Support both dicts and objects with attributes."""
29-
try:
30-
setattr(par, key, value)
31-
except AttributeError:
14+
"""Set a parameter on either a Mapping (dict) or an object with attrs."""
15+
if isinstance(par, Mapping):
3216
par[key] = value
17+
else:
18+
setattr(par, key, value)
3319

3420
def build_matrices(par):
3521
"""
36-
Build derivative matrices and attach them to `par`.
37-
38-
Parameters
39-
----------
40-
par : dict or object with attributes
41-
Required fields:
42-
- N : int number of axial cells
43-
- dz : float cell length (m)
44-
45-
Side effects
46-
------------
47-
Sets:
48-
par.D1 : (N x N) scipy.sparse.csr_matrix
49-
par.D2 : (N x N) scipy.sparse.csr_matrix
50-
51-
Returns
52-
-------
53-
par : same object/dict, for chaining.
22+
Assemble finite-volume derivative matrices in z and attach to `par`.
23+
Requires: par.N (int), par.dz (float).
24+
Adds:
25+
par.D1 -- first derivative (backward/upwind) [N x N] sparse
26+
par.D2 -- second derivative (central) [N x N] sparse
5427
"""
5528
N = int(_get(par, "N"))
5629
dz = float(_get(par, "dz"))
5730

5831
e = np.ones(N)
5932

60-
# 1) First derivative: backward/upwind
33+
# 1) Backward/upwind first derivative
6134
D1 = diags([-e, e], offsets=[-1, 0], shape=(N, N), format="lil") / dz
62-
D1[0, :] = 0.0 # inlet row is handled via the boundary condition
63-
D1 = D1.tocsr()
35+
D1[0, :] = 0 # inlet row handled via boundary condition
36+
D1 = D1.tocsc()
6437

65-
# 2) Second derivative: central
66-
D2 = diags([e, -2*e, e], offsets=[-1, 0, 1], shape=(N, N), format="lil") / dz**2
67-
D2[0, 0] = -2.0 / dz**2 # inlet ghost cell (Dirichlet)
68-
D2[-1, -1] = 1.0 / dz**2 # Danckwerts-type outlet
69-
D2 = D2.tocsr()
38+
# 2) Central second derivative
39+
D2 = diags([e, -2.0 * e, e], offsets=[-1, 0, 1], shape=(N, N), format="lil") / (dz**2)
40+
D2[0, 0] = -2.0 / (dz**2) # ghost for inlet Dirichlet
41+
D2[-1, -1] = 1.0 / (dz**2) # Danckwerts outlet
42+
D2 = D2.tocsc()
7043

7144
_set(par, "D1", D1)
7245
_set(par, "D2", D2)
7346
return par
7447

75-
if __name__ == "__main__":
76-
# Minimal smoke test
77-
from types import SimpleNamespace
78-
par = SimpleNamespace(N=5, dz=0.01)
79-
par = build_matrices(par)
80-
print("D1:\n", par.D1.toarray())
81-
print("D2:\n", par.D2.toarray())
48+
def attach_jacobian_sparsity(par):
49+
"""
50+
Attach Jacobian sparsity pattern for multi-species model.
51+
Requires: par.N, par.Nsp.
52+
Adds: par.Jpattern
53+
"""
54+
N = int(_get(par, "N"))
55+
Nsp = int(_get(par, "Nsp"))
56+
Jpat = sparsity_pattern_multi(N, Nsp)
57+
_set(par, "Jpattern", Jpat)
58+
return par

0 commit comments

Comments
 (0)