# Story 7.2: energy-balance-validation

Status: in-progress

<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->

## Story

As a simulation engineer,
I want First AND Second Law verification across the thermodynamic system,
so that thermodynamic consistency is guaranteed, giving me confidence in the simulation results.

## Acceptance Criteria

1. **Given** converged solution **When** computing balances **Then** energy error $\Sigma \dot{Q} + \dot{W} - \Sigma (\dot{m} \cdot h) < 1\mathrm{e-}6$ kW (First Law)
2. **Given** converged solution **When** computing balances **Then** violations trigger a validation error with a breakdown of error contribution
3. **Given** converged solution **When** checking Second Law **Then** entropy generation $\Sigma (\dot{m} \cdot s) - \Sigma \frac{\dot{Q}}{T} \geq 0$
4. **Given** converged solution **When** checking Second Law **Then** trigger a warning (or error) if there is negative entropy destruction
5. **Given** converged solution **When** computing balances **Then** tests are added and checks are performed after every solve alongside mass balance.

## Tasks / Subtasks

- [ ] Task 1: Component Trait Extension for Energy/Entropy (AC: 1, 3)
  - [ ] Add `energy_transfers(&self, state: &SystemState) -> Option<(Power, Power)>` (e.g. returning Heat $\dot{Q}$ and Work $\dot{W}$) or similar to `Component` trait, or allow components to report $\dot{Q}$ and $\dot{W}$.
  - [ ] Add default implementation for adiabatic/passive components (e.g., Pipes, Valves return 0.0).
  - [ ] Update components (Compressor, Condenser, Evaporator, etc.) to report their specific work and heat transfer.
  - [ ] Ensure entropy generation can be calculated (requires fetching `Entropy` from `FluidBackend` if not already exposed).
- [ ] Task 2: Implement `check_energy_balance` in `System` (AC: 1, 2)
  - [ ] Add `check_energy_balance(&self, state: &StateSlice)` to `crates/solver/src/system.rs`.
  - [ ] Iterate over all components/nodes, computing $\Sigma \dot{Q} + \dot{W}$ and subtracting $\Sigma (\dot{m} \cdot h_{out} - \dot{m} \cdot h_{in})$.
  - [ ] Compare total energy residual against the $1\mathrm{e-}6$ kW threshold.
- [ ] Task 3: Implement Second Law Check (AC: 3, 4)
  - [ ] Implement `check_entropy_generation(&self, state: &StateSlice, backend: &dyn FluidBackend)` to verify $\Sigma \Delta s \geq 0$.
  - [ ] Log a warning (`tracing::warn!`) if entropy generation is negative (impossible thermodynamic state).
- [ ] Task 4: Hook into Solver & Error Handling (AC: 2, 5)
  - [ ] Call both `check_energy_balance` and `check_entropy_generation` in `solver.rs` right after `check_mass_balance`.
  - [ ] Update `ThermoError::Validation` to properly report `energy_error` values, providing breakdowns if applicable.
- [ ] Task 5: Unit and Integration Testing (AC: 5)
  - [ ] Write a unit test `test_energy_balance_pass` with a known good state.
  - [ ] Write a unit test `test_energy_balance_fail` creating an artificial energy imbalance.
  - [ ] Write tests verifying Second Law warnings.

### Review Follow-ups (AI)
- [ ] [AI-Review][High] No codebase implementation found for this story. All tasks and ACs remain undone.
- [ ] [AI-Review][Medium] No tests implemented.
- [ ] [AI-Review][High] 25 files modified in git, but File List in story is empty. Ensure changes are committed or documented.

## Dev Notes

- **Architecture Patterns & Constraints**:
  - **Zero-Panic Policy**: Return `ThermoError::Validation` if energy balance fails. No unwraps in the validation logic.
  - **Scientific Testing Patterns**: Use `approx::assert_relative_eq!(..., epsilon = 1e-6)` for energy tolerance.
  - **Physical Types**: Ensure mathematical operations on `Power`, `MassFlow`, `Enthalpy`, `Temperature`, and `Entropy` are type-safe. Convert to primitive floats safely if doing aggregate sums, but ensure unit consistency (e.g. converting `MassFlow * Enthalpy` (`kg/s * J/kg` = `W`) to `kW` properly).
- **Recent Git Intelligence (from Story 7.1)**:
  - In story 7.1 (`check_mass_balance`), a new trait method `port_mass_flows(&self, state: &SystemState)` was added to `Component`. We likely need a similar trait method or pair of methods (`heat_transfer`, `work_transfer`) to query individual component's energy interactions.
  - Ensure compatibility with `MacroComponent` if it needs to flatten energy balances.
- **Source Tree Components to Touch**:
  - `crates/components/src/lib.rs` (Component trait additions for energy/entropy)
  - Specific components like `crates/components/src/compressor.rs`, `heat_exchanger/*.rs` to implement the new trait methods.
  - `crates/solver/src/system.rs` (Energy and entropy balancing logic)
  - `crates/solver/src/solver.rs` (Hooks for validation after convergence)
  - `crates/core/src/types.rs` (If `Entropy` newtype is missing)
- **Testing Standards**:
  - All warnings (`clippy -D warnings`, etc.) must pass.
  - Validation requires checking the overall $\Sigma$-balances. For testing, it's easiest to mock a small 2-3 component topology or use the existing integration tests in `tests/validation/energy_balance.rs` mentioned in prior stories.

### Project Structure Notes
- The changes squarely fit into the defined `Component` and `System` architecture boundary. Modifications are internal to the component and solver logic and do not violate any FFI boundaries directly.

### References
- [Source: _bmad-output/planning-artifacts/epics.md] - Epic 7, Story 7.2 Requirements & FR36, FR39
- [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 (Claude 3.5 Sonnet / Antigravity)

### Debug Log References

### Completion Notes List
- The story `7-2-energy-balance-validation.md` has been created adhering strictly to the architecture and context guidelines.

### File List
- `_bmad-output/implementation-artifacts/7-2-energy-balance-validation.md`
