Repository navigation
fix: keep symbolic mesh scaling out of finite-volume matrices - #5781
Conversation
9a9678c to
42f3626
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5781 +/- ##
==========================================
- Coverage 98.00% 97.99% -0.01%
==========================================
Files 346 346
Lines 35300 35309 +9
==========================================
+ Hits 34595 34601 +6
- Misses 705 708 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
martinjrobins
left a comment
There was a problem hiding this comment.
Thanks @BradyPlanden, the kron(...) pattern is repeated quite a few times where you are repeating either a vector or matrix, might be worth having a utility function for this (or actually updating pybamm.kronecker_product to detect the specific patterns and apply restructuring appropriately
| # issue | ||
| matrix = pybamm.kronecker_product( | ||
| pybamm.Matrix(eye(second_dim_repeats, dtype=np.float64)), sub_matrix | ||
| stencil = pybamm.Matrix( |
There was a problem hiding this comment.
there is that same pattern again
There was a problem hiding this comment.
Yeah, agreed. I've add a helper now (_block_diagonal) and refactored all the call sites for this style concatenation.
22d3e29 to
5d7f265
Compare
martinjrobins
left a comment
There was a problem hiding this comment.
happy with this, thanks @BradyPlanden
On a mesh with a symbolic length, build every finite-volume matrix from constants and scale its operand or result, so the Python/JAX evaluators and pybamm's Jacobian handle the model; numeric-mesh trees are unchanged.
comment-slop judges a whole docstring once any line changes, and main's Notes derivation is over its length limit. _scaled_matrix documents the Matrix-or-product return.
… helper Add SpatialMethod._block_diagonal for the kron(eye(repeats), block) pattern and use it for the gradient, divergence and integral stencils, as suggested in review. Matrices are unchanged; a test checks each operator matrix on a mesh with a secondary domain is the block diagonal of its single-point one.
Replace the remaining kron(eye(repeats), block) constructions in FiniteVolume, SpectralVolume and SpatialMethod with _block_diagonal, and drop the row-slicing comment copied at each site. The delta function no longer calls pybamm.kronecker_product. Matrices are unchanged. Add tests with a secondary domain for the internal Neumann condition, EvaluateAt and the node/edge shifts, which had only been exercised with a single repeat.
…olumeUnstructured Replace every kron(eye(repeats), block) in the two methods with _block_diagonal and drop the copied row-slicing comment. The kron(ones((repeats, 1)), ...) tiling calls are a different pattern and stay. Matrices are unchanged. Add tests with a secondary domain: FiniteVolume2D gradient components, boundary values and gradients, integrals, shifts, internal Neumann condition and concatenation had only run with a single repeat, as had the unstructured non-orthogonal Laplacian, divergence, boundary and corner values and both internal Neumann paths.
5d7f265 to
b977002
Compare
|
| Project | PyBaMM |
| Branch | a1/fv-symbolic-mesh-scaling |
| Testbed | bare-metal |
⚠️ WARNING: Truncated view!The full continuous benchmarking report exceeds the maximum length allowed on this platform.
Description
A mesh with a symbolic length (
SymbolicUniform1DSubMesh, used when a length such as a particle radius is anInputParameter) lets a model be discretised once and solved for many geometries. On main,FiniteVolumefolds that input-dependent scaling into its matrices, buildingkron(eye(R), stencil * scale)or(Matrix * scale) @ y. Only CasADi can evaluate those trees.KroneckerProducthas no Jacobian,MatrixMultiplication's Jacobian needs a constant left operand, and the Python/JAX code generator writes the literal textkronecker productinto the generated code, which is aSyntaxError. So an SPM or DFN with an input particle radius fails withconvert_to_format="python"or"jax", and insymbol.jac. Separately, an integral over a symbolic secondary dimension raised aShapeErrorbecause it used the primary domain's edges.This PR keeps every matrix constant on a symbolic mesh and applies the scaling to the operand or the result instead. Numeric meshes are untouched: across 15 model configurations (SPM, SPMe, DFN with 1D/2D current collectors, thermal, SEI and size distributions, MPM, MSMR, lead-acid, spectral volume) the discretised trees have identical node sequences and bit-identical constants.
gradient_matrix,divergence_matrix,definite_integral_matrix, the indefinite-integral matrices) return a constant stencil times a row or column scaling, which folds back into a singleMatrixon a numeric mesh. The operators apply it through_apply_matrix, asscale * (stencil @ y)orstencil @ (scale * y), so a subclass that overrides a public builder is still honoured.This is one of the backend-neutral pre-flight PRs split out of the Rust execution engine (#5732). It has no Rust dependency.
Type of change
Add an entry under
# [Unreleased]in CHANGELOG.md, in one of## Breaking changes,## Deprecated,## Features, or## Bug fixes(include PR number; breaking and deprecation entries need a one-line migration note). Internal-only PRs — refactor, docs, CI, tests — can skip this. See RELEASE.md for the full policy.Important checks:
Please confirm the following before marking the PR as ready for review:
nox -s pre-commitnox -s testsnox -s doctests