Commit aeb6929
Add algebraic constraint support to CUDA ProcessSet kernels (#944)
* Add constraint base classes for DAE support
Introduces the constraint class hierarchy for algebraic constraints
in DAE (Differential-Algebraic Equation) systems:
- Constraint: Abstract base class defining the interface
- EquilibriumConstraint: Implements equilibrium relationships (K_eq = products/reactants)
- ConstraintSet: Manager for collections of constraints with Jacobian support
Includes comprehensive unit tests for all constraint functionality.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add state and builder infrastructure for DAE constraints
Prepares the solver infrastructure to support algebraic constraints:
State changes:
- Add number_of_constraints_ to StateParameters
- Add constraint_size_ and upper_left_identity_diagonal_ to State
- Size jacobian for species + constraints
SolverBuilder changes:
- Add SetConstraintCount() and SetConstraintNames() methods
- Update Build() to include constraint variables in state
This is backward compatible - when constraint_count_=0 (default),
behavior is unchanged from before.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Integrate DAE constraints into Rosenbrock solver
Completes the DAE constraint system by wiring constraints into
the Rosenbrock solver loop:
Solver changes:
- Add ConstraintSet member to RosenbrockSolver
- Call AddForcingTerms() and SubtractJacobianTerms() in solve loop
- Add SetConstraints() to SolverBuilder with full Build() integration
Key implementation details:
- AlphaMinusJacobian adds alpha to ALL diagonals (ODE and algebraic)
- This treats algebraic constraints as stiff ODEs (ε*z' = g with ε=hγ)
- Constraint Jacobian elements merged with ODE elements at build time
Integration tests:
- test_equilibrium.cpp demonstrates working DAE equilibrium solving
Documentation:
- ARCHITECTURE.md: Implementation details and sign conventions
- TESTS.md: Test case specifications
- CLAUDE.md: Project context and build instructions
- Custom Claude Code skills for testing and debugging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add documentation for constraint classes and fix param comments
- Add educational walkthrough of Constraint, EquilibriumConstraint, and
ConstraintSet classes (constraint_classes_walkthrough.md)
- Add line-by-line explanation of reactant loop indexing logic
(reactant_loop_explanation.md)
- Add comparison of ProcessSet vs ConstraintSet Jacobian computation
(forcing_jacobian_parallel.md)
- Fix incorrect @param comments in Constraint base class
- Remove unused <map> include from constraint.hpp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Standardize mathematical notation in docs and comments
Use consistent notation across documentation and code:
- y for state variables
- F(y) for forcing (uppercase)
- G(y) for constraints (uppercase)
Add note on DAE notation conventions explaining the y/z distinction
from DAE literature and why MICM uses a unified state vector.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Rename and expand indexing patterns documentation
Rename reactant_loop_explanation.md to indexing_patterns.md to better
reflect its broader scope.
Add detailed comparison of 2-level indirection (ProcessSet) vs 3-level
indirection (Constraint classes), explaining:
- How ProcessSet pre-computes global indices at construction
- How Constraint receives indices as a parameter for decoupling
- The ConstraintSet bridge that connects them
- Performance implications and potential optimization paths
- Design philosophy trade-offs (OO vs data-oriented)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add architecture overview and test coverage to walkthrough
Architecture Overview section:
- Data flow diagram showing how constraints integrate with solver
- Component responsibilities for Constraint, EquilibriumConstraint,
ConstraintSet, and Rosenbrock Solver
- Parallel structure comparison of ProcessSet and ConstraintSet
Test Coverage section:
- Summary table of EquilibriumConstraint tests
- Summary table of ConstraintSet tests
- Key scenarios covered by each test suite
- Notes on what's not yet tested (future work)
- Instructions for running constraint tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add flat array memory layout documentation to walkthrough
New section "Flat Array Memory Layout and Strides" explains:
- How MICM uses flat arrays with stride-based access
- Dense matrix access pattern (rows=cells, cols=species)
- Sparse Jacobian access via AsVector() and FlatBlockSize()
- Pre-computed jacobian_flat_ids_ for efficient sparse access
- Note that vectorized variants exist in ProcessSet but not yet
in ConstraintSet (planned for future optimization)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Rename forcing_jacobian_parallel.md for clarity
Rename to constraintset_mirrors_processset.md to better describe
the document's purpose: showing how ConstraintSet mirrors ProcessSet's
design for Jacobian computation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR review feedback: move docs and use Yield type
- Move documentation files from root to docs/design/
- Remove branch name reference from walkthrough intro
- Replace std::pair<std::string, double> with Yield type for
reactants_ and products_ in EquilibriumConstraint
- Fix dead code in Jacobian calculation (removed unused assignment)
- Update test files to use Yield(Species(...), coeff) syntax
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Use micm-specific error types for constraint validation
- Add MICM_ERROR_CATEGORY_CONSTRAINT and error codes to error.hpp
- Create constraint_error.hpp with MicmConstraintErrc enum and error category
- Replace std::invalid_argument with std::system_error in EquilibriumConstraint
- Replace std::runtime_error with std::system_error in ConstraintSet
- Update tests to expect std::system_error
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Optimize Constraint interface to avoid per-cell allocations
Address PR feedback from K20shores and Copilot regarding performance:
- K20shores (line 199): "make Residual operate on the dense matrix directly"
- K20shores (line 247): "agreed" with Copilot on SubtractJacobianTerms
Refactor Residual() and Jacobian() to use pointers instead of vectors,
eliminating temporary allocations in the inner grid cell loop:
- Change Constraint interface from vector-based to pointer-based
- Add dependency_offset_ and jacobian_flat_offset_ to ConstraintInfo
for O(1) access to pre-computed index arrays
- Add max_dependencies_ for reusable Jacobian buffer allocation
- AddForcingTerms: access row data directly via &cell_state[0]
- SubtractJacobianTerms: use single reusable jac_buffer across all
constraints and grid cells
Performance impact:
- Eliminates per-cell vector copy of concentrations (was N species)
- Eliminates per-constraint vector copy of indices
- Eliminates per-constraint Jacobian vector allocation
Update documentation to reflect the new interface.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add constructor validation for EquilibriumConstraint
Address Copilot review suggestions:
- Validate reactants is not empty (EmptyReactants error)
- Validate products is not empty (EmptyProducts error)
- Validate all stoichiometric coefficients are positive (InvalidStoichiometry error)
Adds corresponding error codes and test cases.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Cleanup.
* Added detailed Codex reviews and recommendations in TODO.
* Added Codex 5.2 at Extra High reasoning depth review pass.
* merge main
* fix the tests
* constraint check is done out of loop
* remove unused function
* Review dae 1 constraint classes (#914)
remove md files, and update the test names
* fix the typo
* add a missing header
* remove unnecessary setter for constraints
* change the type of unique ptr to vector
* remove unncessary docs
* add deep copy for constraint
* temp
* replace unique ptr to variant
* fix the error
* fix test
* code clean up
* revert the previous change for get solver
* make builder copyable
* fix test
* add comments on test
* revert back
* state size
* code cleanup
* address copilot review
* Fix missing constraint Jacobian terms on Rosenbrock rejected-step path (#928)
* Initial plan
* Add constraint Jacobian terms on rejected-step path
Co-authored-by: boulderdaze <55209567+boulderdaze@users.noreply.github.com>
* Fix comment: should say 'Subtract' not 'Add' for constraint Jacobian
Co-authored-by: boulderdaze <55209567+boulderdaze@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: boulderdaze <55209567+boulderdaze@users.noreply.github.com>
* address copilot review
* nvhpc error
* add params for constructor for cuda
* fix a bug
* Implement full mass-matrix DAE row replacement
* Update DAE review and move design docs
* Fix review issues and add DAE integration tests
- Guard std::pow() against negative concentrations in EquilibriumConstraint
- Selective Max(0.0) clamping: only ODE variables, not algebraic
- Add self-diagonal guarantee for constraint rows in sparse Jacobian
- Remove unused constructor params from Rosenbrock and BackwardEuler
- Fix Dervied->Derived typo, stray semicolon, stale comments
- Remove std::cout from tests and unused <iostream> include
- Add 7 new integration tests: DAE parameter variants, coupled constraints,
conservation law, stiff coupling, non-unit stoichiometry, selective clamping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix State copy slicing, Jacobian duplicate deps, and unused-species check
- Add virtual Clone() to TemporaryVariables base class; override in
RosenbrockTemporaryVariables and BackwardEulerTemporaryVariables.
State copy ctor/assignment now use Clone() to preserve derived type.
- Change ConstraintSet::SubtractJacobianTerms replace mode from = to -=
so duplicate dependency columns accumulate correctly.
- Include constraint species in UnusedSpeciesCheck() so species used
only by constraints are not falsely flagged as unused.
- Move updated REVIEW_CLAUDE.md to docs/design/ with fixed/open status.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add multi-grid-cell DAE integration test
3 grid cells with different initial conditions exercise the per-cell
iteration in AddForcingTerms, SubtractJacobianTerms, AlphaMinusJacobian,
and NormalizedError. Verifies per-cell constraint satisfaction, mass
conservation, non-negativity, and independent evolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Jacobian concentration guards and Solve overload clamping
- Apply std::max(0.0, ...) consistently in EquilibriumConstraint::Jacobian
for aggregate product terms and special-case fallbacks, matching the
Residual policy to prevent NaN with negative transient concentrations.
- Extract PostSolveClamp() helper in Solver so both Solve overloads
apply identical post-solve clamping (ODE-only for DAE systems).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove design docs from tracking and add to .gitignore
Design review and architecture docs are working documents not
intended for the main repository.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Resolve all LOW review items: return type, dead code, sparsity filter, regression tests
- Fix GetAlgebraicSpecies() to return const std::string& instead of copy
- Remove dead append-rows code paths from ConstraintSet, rosenbrock temps, state.inl
- Simplify ConstraintSet constructor to 2 params (always replace mode)
- Filter kinetic sparsity from algebraic rows in solver builder
- Add regression tests: State copy+solve, overlapping species Jacobian, constraint-only unused species
- Update all unit tests to use replace mode exclusively
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix DAE algebraic-row Jacobian flat-id pruning regression
* Add DAE reorder-state and algebraic-reactant regression tests
* Track architecture doc and untrack internal review notes
* Untrack architecture doc from PR scope
* Fix the test failure for DAE constraint enforcement PR (#933)
* merge main
* fixes missing inline and template args
* fix the cuda constructor signature
* fixes the syntax error
* Review and rework DAE Constraint enforcement PR (#937)
* review and rework
* add missing file
* add unit test
* address the copilot review
* add support for cuda algebraic constrait
* replace bool to uint8_t to supports .data()
* add a missing header
* update set algebraic functions for cuda
* address code review
* add setting algebraic ids tests in process set
---------
Co-authored-by: David Fillmore <fillmore@ucar.edu>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>1 parent 257400f commit aeb6929
File tree
8 files changed
+249
-7
lines changed- include/micm
- cuda
- process
- util
- process
- src/process
- test/unit
- cuda/process
- process
8 files changed
+249
-7
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
24 | 29 | | |
25 | 30 | | |
26 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
65 | 72 | | |
66 | 73 | | |
67 | 74 | | |
| |||
91 | 98 | | |
92 | 99 | | |
93 | 100 | | |
| 101 | + | |
94 | 102 | | |
95 | 103 | | |
96 | 104 | | |
97 | 105 | | |
98 | 106 | | |
99 | 107 | | |
| 108 | + | |
100 | 109 | | |
101 | 110 | | |
102 | 111 | | |
| |||
128 | 137 | | |
129 | 138 | | |
130 | 139 | | |
| 140 | + | |
131 | 141 | | |
132 | 142 | | |
133 | 143 | | |
134 | 144 | | |
135 | 145 | | |
136 | 146 | | |
| 147 | + | |
137 | 148 | | |
138 | 149 | | |
139 | 150 | | |
| |||
172 | 183 | | |
173 | 184 | | |
174 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
175 | 202 | | |
176 | 203 | | |
177 | 204 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| 37 | + | |
36 | 38 | | |
37 | 39 | | |
38 | 40 | | |
| |||
43 | 45 | | |
44 | 46 | | |
45 | 47 | | |
| 48 | + | |
46 | 49 | | |
47 | 50 | | |
48 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
46 | | - | |
| 47 | + | |
47 | 48 | | |
48 | 49 | | |
49 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
56 | 61 | | |
57 | 62 | | |
58 | 63 | | |
59 | 64 | | |
60 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
61 | 70 | | |
62 | 71 | | |
63 | 72 | | |
| |||
79 | 88 | | |
80 | 89 | | |
81 | 90 | | |
| 91 | + | |
82 | 92 | | |
83 | 93 | | |
| 94 | + | |
84 | 95 | | |
85 | 96 | | |
86 | 97 | | |
| |||
109 | 120 | | |
110 | 121 | | |
111 | 122 | | |
112 | | - | |
| 123 | + | |
113 | 124 | | |
114 | | - | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
115 | 130 | | |
116 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
117 | 137 | | |
118 | 138 | | |
119 | | - | |
120 | | - | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
121 | 145 | | |
122 | 146 | | |
123 | 147 | | |
| 148 | + | |
124 | 149 | | |
125 | 150 | | |
126 | 151 | | |
| |||
137 | 162 | | |
138 | 163 | | |
139 | 164 | | |
| 165 | + | |
140 | 166 | | |
141 | 167 | | |
142 | 168 | | |
| |||
151 | 177 | | |
152 | 178 | | |
153 | 179 | | |
| 180 | + | |
154 | 181 | | |
155 | 182 | | |
156 | 183 | | |
| |||
180 | 207 | | |
181 | 208 | | |
182 | 209 | | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
183 | 213 | | |
184 | 214 | | |
185 | 215 | | |
186 | 216 | | |
187 | 217 | | |
188 | 218 | | |
| 219 | + | |
189 | 220 | | |
190 | 221 | | |
191 | 222 | | |
| |||
263 | 294 | | |
264 | 295 | | |
265 | 296 | | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
266 | 315 | | |
267 | 316 | | |
268 | 317 | | |
| |||
279 | 328 | | |
280 | 329 | | |
281 | 330 | | |
| 331 | + | |
| 332 | + | |
282 | 333 | | |
283 | 334 | | |
284 | 335 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
44 | 52 | | |
0 commit comments