5.6 KiB
5.6 KiB
Story 7.1: mass-balance-validation
Status: done
Story
As a simulation engineer, I want automatic mass conservation verification, so that I trust physical correctness of the system simulation.
Acceptance Criteria
- Given converged solution When computing mass balance Then error Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s
- Given converged solution When computing mass balance Then violations trigger a validation error
- Given converged solution When computing mass balance Then check performed after every solve
Tasks / Subtasks
- Task 1: Add Mass Balance Method (AC: 1, 3)
- Add a
check_mass_balancemethod toSystem(or similar orchestrator). - Method should iterate through all nodes/components and verify that the sum of mass flows leaving equals the sum of mass flows entering.
- Establish
1e-9kg/s as the threshold for mass balance violation.
- Add a
- Task 2: Validation Error Definition (AC: 2)
- Ensure
ThermoError::Validation { mass_error: f64, energy_error: f64 }exists incrates/core/src/errors.rs(ensure it handles isolated mass error check or create a specific mass validation error variant if suitable, though PRD saysValidation { mass_error, energy_error }).
- Ensure
- Task 3: Hook into Solver (AC: 3)
- Update
solve/solve_with_fallbackincrates/solver/src/lib.rs(or relevant logic) to perform the mass balance check after convergence. - Return the validation error if criteria are not met.
- Update
- Task 4: Unit Testing
- Implement tests in
tests/validation/energy_balance.rsorcrates/solver/src/system.rsfor a system that converges successfully to verify validation passes. - Add a mock case where mass balance fails to verify error is raised.
- Implement tests in
Dev Notes
Architecture Patterns & Constraints
- Zero-Panic Policy: Return
ThermoError::Validationif 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
ThermoErrorincrates/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(ifThermoError::Validationneeds tweaking)crates/solver/src/system.rs(forcheck_mass_balancelogic)crates/solver/src/strategies/mod.rsorfallback.rs(to call validation logic post-solve)tests/validation/(to add validation check tests)
Testing Standards Summary
- Use
approxcrate with explicit tolerance1e-9kg/s. cargo clippy -- -D warningsmust pass.cargo test --workspacemust 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_flowsfor all core components to standardize mass flow retrieval. - Integrated
check_mass_balanceintoSystemand hooked it into theSolverStrategy::solveentry point. - Updated
thermo_error_to_pyerrand C error mappings to handle the newValidationerror type. - Fixed severe architectural issue in integration tests where
connectmethods were missing, by implementing them forExpansionValve,Compressor, andPipe. - 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/flow_boundary.rs (port_mass_flows for FlowSource, FlowSink)
- 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)
- [AI-Review][HIGH] Implement
port_mass_flowsfor remaining components: FlowSource, FlowSink, Pump, Fan, Evaporator, Condenser, CondenserCoil, EvaporatorCoil, Economizer, FlowSplitter, FlowMerger - [AI-Review][MEDIUM] Add integration test with full refrigeration cycle to verify mass balance validation end-to-end