Entropyk/_bmad-output/implementation-artifacts/7-1-mass-balance-validation.md

97 lines
5.7 KiB
Markdown

# Story 7.1: mass-balance-validation
Status: done
<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
## Story
As a simulation engineer,
I want automatic mass conservation verification,
so that I trust physical correctness of the system simulation.
## Acceptance Criteria
1. **Given** converged solution **When** computing mass balance **Then** error Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s
2. **Given** converged solution **When** computing mass balance **Then** violations trigger a validation error
3. **Given** converged solution **When** computing mass balance **Then** check performed after every solve
## Tasks / Subtasks
- [x] Task 1: Add Mass Balance Method (AC: 1, 3)
- [x] Add a `check_mass_balance` method to `System` (or similar orchestrator).
- [x] Method should iterate through all nodes/components and verify that the sum of mass flows leaving equals the sum of mass flows entering.
- [x] Establish `1e-9` kg/s as the threshold for mass balance violation.
- [x] Task 2: Validation Error Definition (AC: 2)
- [x] Ensure `ThermoError::Validation { mass_error: f64, energy_error: f64 }` exists in `crates/core/src/errors.rs` (ensure it handles isolated mass error check or create a specific mass validation error variant if suitable, though PRD says `Validation { mass_error, energy_error }`).
- [x] Task 3: Hook into Solver (AC: 3)
- [x] Update `solve` / `solve_with_fallback` in `crates/solver/src/lib.rs` (or relevant logic) to perform the mass balance check after convergence.
- [x] Return the validation error if criteria are not met.
- [x] Task 4: Unit Testing
- [x] Implement tests in `tests/validation/energy_balance.rs` or `crates/solver/src/system.rs` for a system that converges successfully to verify validation passes.
- [x] Add a mock case where mass balance fails to verify error is raised.
## Dev Notes
### Architecture Patterns & Constraints
- **Zero-Panic Policy**: Return `ThermoError::Validation` if mass balance fails. Never panic.
- **Scientific Testing Patterns**: Use `approx::assert_relative_eq!(..., epsilon = 1e-9)` for testing mass tolerance.
- **Physical Types (NewType Pattern)**: Remember to handle `MassFlow(f64)` unwrapping properly when computing sums or errors.
- **Error Handling Strategy**: Use existing `ThermoError` in `crates/core/src/errors.rs`.
- Do not add dynamic allocations in the checks if they run in hot paths, although this runs strictly *after* convergence, so it's less critical but ideally iterate over existing graph structure without allocating new vectors.
### Source Tree Components to Touch
- `crates/core/src/errors.rs` (if `ThermoError::Validation` needs tweaking)
- `crates/solver/src/system.rs` (for `check_mass_balance` logic)
- `crates/solver/src/strategies/mod.rs` or `fallback.rs` (to call validation logic post-solve)
- `tests/validation/` (to add validation check tests)
### Testing Standards Summary
- Use `approx` crate with explicit tolerance `1e-9` kg/s.
- `cargo clippy -- -D warnings` must pass.
- `cargo test --workspace` must pass.
### References
- [Source: _bmad-output/planning-artifacts/epics.md#Epic-7] - Epic 7 Requirements and Story 7.1
- [Source: _bmad-output/planning-artifacts/architecture.md#Error-Handling-Strategy] - Error Handling
- [Source: _bmad-output/planning-artifacts/architecture.md#Scientific-Testing-Patterns] - Testing Patterns definition
## Dev Agent Record
### Agent Model Used
BMad Create Story Workflow
### Debug Log References
### Completion Notes List
- Implemented `port_mass_flows` for all core components to standardize mass flow retrieval.
- Integrated `check_mass_balance` into `System` and hooked it into the `SolverStrategy::solve` entry point.
- Updated `thermo_error_to_pyerr` and C error mappings to handle the new `Validation` error type.
- Fixed severe architectural issue in integration tests where `connect` methods were missing, by implementing them for `ExpansionValve`, `Compressor`, and `Pipe`.
- Verified violation detection with passing unit test `test_mass_balance_violation`.
### File List
- crates/entropyk/src/error.rs (Validation error variant)
- crates/components/src/lib.rs (port_mass_flows trait method)
- crates/components/src/compressor.rs (port_mass_flows implementation)
- crates/components/src/expansion_valve.rs (port_mass_flows implementation)
- crates/components/src/pipe.rs (port_mass_flows implementation)
- crates/components/src/pump.rs (port_mass_flows implementation)
- crates/components/src/fan.rs (port_mass_flows implementation)
- crates/components/src/refrigerant_boundary.rs (port_mass_flows for RefrigerantSource, RefrigerantSink)
- crates/components/src/flow_junction.rs (port_mass_flows for FlowSplitter, FlowMerger)
- crates/components/src/heat_exchanger/evaporator.rs (delegation to inner)
- crates/components/src/heat_exchanger/evaporator_coil.rs (delegation to inner)
- crates/components/src/heat_exchanger/condenser.rs (delegation to inner)
- crates/components/src/heat_exchanger/condenser_coil.rs (delegation to inner)
- crates/components/src/heat_exchanger/economizer.rs (delegation to inner)
- crates/components/src/heat_exchanger/exchanger.rs (port_mass_flows base implementation)
- crates/solver/src/solver.rs (post-solve validation hook)
- crates/solver/src/system.rs (check_mass_balance method, tests, logging)
- bindings/python/src/errors.rs (ValidationError mapping)
### Review Follow-ups (AI)
- [x] [AI-Review][HIGH] Implement `port_mass_flows` for remaining components: RefrigerantSource, RefrigerantSink, Pump, Fan, Evaporator, Condenser, CondenserCoil, EvaporatorCoil, Economizer, FlowSplitter, FlowMerger
- [x] [AI-Review][MEDIUM] Add integration test with full refrigeration cycle to verify mass balance validation end-to-end