1219 lines
40 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
stepsCompleted:
- step-01-validate-prerequisites
- step-02-design-epics
- step-03-create-stories
inputDocuments:
- /Users/sepehr/dev/Entropyk/_bmad-output/planning-artifacts/prd.md
- /Users/sepehr/dev/Entropyk/_bmad-output/planning-artifacts/architecture.md
---
# Entropyk - Epic Breakdown
## Overview
This document provides the complete epic and story breakdown for Entropyk, decomposing the requirements from the PRD and Architecture requirements into implementable stories.
## Requirements Inventory
### Functional Requirements
**FR1:** The system can model a Compressor according to AHRI 540 standard with manufacturer coefficients
**FR2:** The system can model a Condenser with heat transfer calculation
**FR3:** The system can model an Expansion Valve (isenthalpic expansion)
**FR4:** The system can model an Evaporator with phase change
**FR5:** The system can model an Economizer (internal heat exchanger) with Bypass mode
**FR6:** Each component can be in OperationalState (On, Off, Bypass)
**FR7:** In Off mode, an active component contributes zero mass flow to the system
**FR8:** In Bypass mode, a component behaves as an adiabatic pipe (P_in = P_out, h_in = h_out)
**FR9:** User can define a Machine containing N independent fluid circuits
**FR10:** User can connect components via Ports (inlet/outlet)
**FR11:** System supports connections between circuits (thermal coupling)
**FR12:** System can solve N circuits simultaneously or sequentially
**FR13:** System mathematically handles zero-flow branches without division by zero
**FR14:** System can solve equations using Newton-Raphson method
**FR15:** System can solve equations using Sequential Substitution (Picard) method
**FR16:** Solver automatically switches to Sequential Substitution if Newton-Raphson diverges
**FR17:** Solver respects configurable time budget (timeout)
**FR18:** On timeout, solver returns best known state with NonConverged status
**FR19:** Solver can freeze Jacobian calculation to accelerate (Jacobian Freezing)
**FR20:** Convergence criterion checks Delta Pressure < 1 Pa (1e-5 bar)
**FR21:** For multi-circuits, global convergence is achieved when ALL circuits converge
**FR22:** User can define output constraints (e.g., Superheat = 5K)
**FR23:** System calculates necessary inputs (e.g., valve opening) respecting Bounded Constraints (0.0 Valve 1.0). If solution is out of bounds, solver returns "Saturation" or "ControlLimitReached" error
**FR24:** Inverse Control is solved simultaneously with cycle equations (One-Shot)
**FR25:** System can load fluid properties via CoolProp
**FR26:** System supports Tabular Interpolation tables for 100x performance
**FR27:** System handles pure fluids and mixtures (R32/R125, R454B)
**FR28:** System handles Temperature Glide for zeotropic mixtures
**FR29:** System uses automatic damping near critical point (CO2 R744)
**FR30:** Native Rust API with types and ownership safety
**FR31:** Python bindings via PyO3 with tespy-compatible API
**FR32:** C FFI for integration with external systems (PLC, LabView)
**FR33:** WebAssembly compilation support for web interfaces
**FR34:** CLI for batch simulation execution
**FR35:** System automatically checks mass balance (Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s)
**FR36:** System automatically checks energy balance (Σ + - Σ ( · h) < 1e-6 kW)
**FR37:** Each result contains traceability metadata (solver version, fluid version, SHA-256 input hash)
**FR38:** Debug Verbose mode to display residuals and convergence history
**FR39:** Error handling via Result<T, ThermoError> (Zero-Panic Policy)
**FR40:** System handles Incompressible Fluids (Water, Glycol, Humid Air simplified) via lightweight models (constant Cp or polynomial) for heat sources and sinks
**FR41:** Complete graph (Topology + Parameters + Fluid State) is serializable/deserializable to JSON (or TOML)
**FR42:** System includes Automatic Initialization Heuristic (Smart Guesser) proposing coherent initial pressure values based on source/sink temperatures
**FR43:** Components support calibration parameters (Calib: f_m, f_dp, f_ua, f_power, f_etav) to match simulation to real machine test data
**FR44:** System can validate results against ASHRAE 140 / BESTEST test cases (post-MVP)
**FR45:** System supports inverse calibration (parameter estimation from test bench data)
**FR46:** Explicit Air Coil components (EvaporatorCoil, CondenserCoil) for finned air heat exchangers (post-MVP)
**FR47:** Each refrigeration component natively exposes a complete thermodynamic state (Pressure, Temperature, T_sat, Quality, Superheat, Subcooling, Mass flow, Reynolds, Enthalpy, Entropy) easily accessible without complex recalculations.
### NonFunctional Requirements
**NFR1:** Steady State convergence time < **1 second** for standard cycle in Cold Start
**NFR2:** Simple cycle (Single-stage) solved in **< 100 ms**
**NFR3:** Complex cycle (Multi-circuits) solved in **< 1 second**
**NFR4:** No dynamic allocation in solver loop (pre-calculated allocation only)
**NFR5:** Guaranteed determinism: same inputs same results within 1e-9 precision on all platforms (x86, ARM, WASM)
**NFR6:** HIL latency < **20 ms** for real-time integration with PLC
**NFR7:** Zero-Panic Policy: no crash even with invalid inputs or impossible states
**NFR8:** Memory Safety guaranteed by Rust ownership system (no memory leaks, no use-after-free)
**NFR9:** Capability to run **48h+** without interruption or degradation (HIL/Embedded)
**NFR10:** Graceful error handling: timeout, non-convergence, saturation return explicit Result<T, Error>
**NFR11:** CoolProp 6.4+ compatibility for fluid properties
**NFR12:** Stable C FFI: auto-generated .h headers via cbindgen, C99/C++ compatible
**NFR13:** Deterministic WebAssembly: same behavior as native, no non-determinism sources
**NFR14:** Python bindings PyO3: tespy-compatible API for facilitated migration
**NFR15:** 100% documentation of public APIs (rustdoc)
**NFR16:** Automated CI/CD: tests, benchmarks, memory checks (Valgrind + Miri)
**NFR17:** Zero tolerance warnings: `cargo clippy -- -D warnings`
### Additional Requirements
**Architecture Requirements:**
- Workspace-based multi-crate architecture with 4 crates (core, solver, components, fluids) and 3 bindings (python, c, wasm)
- Trait-based static polymorphism with enum dispatch for zero-cost abstraction
- NewType pattern for all physical quantities (Pressure, Temperature, Enthalpy, MassFlow) - never bare f64 in public APIs
- Type-State pattern for connection safety at compile-time
- Pre-allocated buffers only - no heap allocation in hot paths
- `#![deny(warnings)]` in lib.rs for all crates
- KaTeX configuration in `.cargo/config.toml` for mathematical documentation
- `tracing` for structured logging (never println!)
- `thiserror` for error handling with ThermoError enum
- `approx` crate for floating-point assertions with explicit tolerances
- Sys-crate pattern for CoolProp C++ integration
- cbindgen for C header generation
- Miri validation in CI for undefined behavior detection
- Mass balance tolerance: 1e-9 kg/s
- Energy balance tolerance: 1e-6 kW
- Convergence pressure tolerance: 1 Pa
**Standards Compliance:**
- AHRI 540 standard implementation for compressor modeling with manufacturer coefficients (Bitzer, Copeland, Danfoss)
- NIST REFPROP as gold standard for fluid properties
- CoolProp as open-source reference
- Tabular interpolation achieving < 0.01% deviation from NIST while being 100x faster than direct EOS calls
**Domain-Specific Requirements:**
- Critical Point handling (CO2 R744) with automatic damping to prevent NaN in partial derivatives
- Temperature Glide handling for zeotropic mixtures (R454B, R32/R125) integrating Bubble Point Dew Point without approximation
- Traçability: Each SimulationResult contains solver_version, fluid_backend version, input_hash (SHA-256)
- Smart initialization heuristic for initial pressure guesses based on source/sink temperatures
**CI/CD Requirements:**
- `cargo test`: Unit tests
- `cargo bench`: Performance regression (failure if > 5% degradation)
- `valgrind`: Memory leaks (FFI)
- `cargo clippy -- -D warnings`: Zero tolerance style
- `miri test`: Undefined behavior detection
- 100% public documentation coverage
- Compiled and tested examples in CI
**Packaging & Distribution:**
- Rust: crates.io
- Python: pip install rust-thermo-cycle (Wheels PyPI, manylinux)
- C/C++: Headers + dynamic libraries
- Docker: Image rust-thermo-lab (JupyterLab + Rust kernel + CoolProp)
### FR Coverage Map
| FR | Epic | Description |
|----|------|-------------|
| FR1 | Epic 1 | Compressor AHRI 540 modeling |
| FR2 | Epic 1 | Condenser heat transfer |
| FR3 | Epic 1 | Expansion valve isenthalpic |
| FR4 | Epic 1 | Evaporator phase change |
| FR5 | Epic 1 | Economizer with bypass |
| FR6 | Epic 1 | Component states ON/OFF/BYPASS |
| FR7 | Epic 1 | Zero mass flow in OFF mode |
| FR8 | Epic 1 | Adiabatic pipe in BYPASS mode |
| FR9 | Epic 3 | Multi-circuit machine definition |
| FR10 | Epic 3 | Component connection via Ports |
| FR11 | Epic 3 | Thermal coupling between circuits |
| FR12 | Epic 3 | Simultaneous/sequential circuit solving |
| FR13 | Epic 3 | Zero-flow branch handling |
| FR14 | Epic 4 | Newton-Raphson solver |
| FR15 | Epic 4 | Sequential Substitution solver |
| FR16 | Epic 4 | Auto-fallback solver switching |
| FR17 | Epic 4 | Configurable timeout |
| FR18 | Epic 4 | Best state on timeout |
| FR19 | Epic 4 | Jacobian freezing |
| FR20 | Epic 4 | Delta Pressure < 1 Pa convergence |
| FR21 | Epic 4 | Global multi-circuit convergence |
| FR22 | Epic 5 | Output constraints definition |
| FR23 | Epic 5 | Bounded input calculation |
| FR24 | Epic 5 | One-shot inverse control |
| FR25 | Epic 2 | CoolProp integration |
| FR26 | Epic 2 | Tabular interpolation tables |
| FR27 | Epic 2 | Pure fluids and mixtures support |
| FR28 | Epic 2 | Temperature glide handling |
| FR29 | Epic 2 | Critical point damping |
| FR30 | Epic 6 | Native Rust API |
| FR31 | Epic 6 | Python PyO3 bindings |
| FR32 | Epic 6 | C FFI bindings |
| FR33 | Epic 6 | WebAssembly support |
| FR34 | Epic 6 | CLI for batch execution |
| FR35 | Epic 7 | Mass balance validation |
| FR36 | Epic 7 | Energy balance validation |
| FR37 | Epic 7 | Traceability metadata |
| FR38 | Epic 7 | Debug verbose mode |
| FR39 | Epic 7 | Zero-panic error handling |
| FR40 | Epic 2 | Incompressible fluids support |
| FR41 | Epic 7 | JSON serialization |
| FR42 | Epic 4 | Smart initialization heuristic |
| FR43 | Epic 7 | Component calibration parameters (Calib) |
| FR44 | Epic 7 | ASHRAE 140 / BESTEST validation |
| FR45 | Epic 7 | Inverse calibration (parameter estimation) |
| FR46 | Epic 1 | Air Coils (EvaporatorCoil, CondenserCoil) |
| FR47 | Epic 2 | Rich Thermodynamic State Abstraction |
| FR48 | Epic 3 | Hierarchical Subsystems (MacroComponents) |
## Epic List
### Epic 1: Extensible Component Framework
**Goal:** Create the foundation that allows adding any component (VFD, Battery, Pump, Pipe) by simply implementing a Rust Trait, without touching the calculation engine.
**Innovation:** Trait-based "Lego" architecture to add Compressors, Pumps, VFDs, Pipes, etc.
**FRs covered:** FR1, FR2, FR3, FR4, FR5, FR6, FR7, FR8, FR46
---
### Epic 2: Fluid Properties Backend
**Goal:** Provide precise thermodynamic properties via CoolProp, tabular tables, mixture handling, and critical point management.
**Innovation:** 100x performance with tabular tables, automatic CO2 damping.
**FRs covered:** FR25, FR26, FR27, FR28, FR29, FR40, FR47
---
### Epic 3: System Topology (Graph)
**Goal:** Enable component assembly via Ports and manage multi-circuits with thermal coupling, and support hierarchical subsystems.
**Innovation:** Multi-fluid directed graph in a single model, with natively supported hierarchical sub-blocks.
**FRs covered:** FR9, FR10, FR11, FR12, FR13, FR48
---
### Epic 4: Intelligent Solver Engine
**Goal:** Solve any system with < 1s guarantee, Newton-Raphson Sequential Substitution fallback.
**Innovation:** Solver-agnostic with intelligent fallback - guaranteed convergence.
**FRs covered:** FR14, FR15, FR16, FR17, FR18, FR19, FR20, FR21, FR42
---
### Epic 5: Inverse Control & Optimization
**Goal:** Transform component parameters (VFD speed, Valve position) into simultaneously solved unknowns.
**Innovation:** Native Inverse Control via Residual Embedding - "One-Shot".
**FRs covered:** FR22, FR23, FR24
---
### Epic 6: Multi-Platform APIs
**Goal:** Distribute the library via Python (PyO3), WebAssembly, C FFI, and CLI.
**Innovation:** Multi-target without code duplication (Rust Python/WASM/C).
**FRs covered:** FR30, FR31, FR32, FR33, FR34
---
### Epic 7: Validation & Persistence
**Goal:** Guarantee trust via mass/energy balances, SHA-256 traceability, and JSON persistence.
**Innovation:** Complete traceability and scientific reproducibility.
**FRs covered:** FR35, FR36, FR37, FR38, FR39, FR41, FR43, FR44, FR45
---
### Epic 8: Component-Fluid Integration
**Goal:** Integrate real thermodynamic fluid properties directly into component Residual calculation models.
**Innovation:** True physical interaction between solver mathematics and state equations.
**FRs covered:** FR47
---
<!-- ALL EPICS AND STORIES -->
## Epic 1: Extensible Component Framework
### Story 1.1: Component Trait Definition
**As a** library developer,
**I want** to define a generic Component trait with methods for residuals, ports, and state management,
**So that** future components can be implemented by simply implementing this trait.
**Acceptance Criteria:**
**Given** a new component struct
**When** it implements the Component trait
**Then** it must provide compute_residuals(), get_ports(), and get_state() methods
**And** the trait must be object-safe for dynamic dispatch
---
### Story 1.2: Physical Types (NewType Pattern)
**As a** simulation user,
**I want** type-safe physical quantities (Pressure, Temperature, Enthalpy, MassFlow),
**So that** I cannot accidentally mix units.
**Acceptance Criteria:**
**Given** a function accepting Pressure and Temperature
**When** I try to pass Temperature where Pressure is expected
**Then** the code must not compile (compile-time safety)
**And** conversions must be explicit (e.g., pressure_bar.to_pascals())
---
### Story 1.3: Port and Connection System
**As a** system modeler,
**I want** to define inlet/outlet ports for components and connect them bidirectionally,
**So that** I can build fluid circuit topologies.
**Acceptance Criteria:**
**Given** two components with compatible ports
**When** I call connect(port_a, port_b)
**Then** the connection is established with state validation
**And** attempting to connect incompatible ports fails at compile-time
---
### Story 1.4: Compressor Component (AHRI 540)
**As a** thermodynamic engineer,
**I want** to model a compressor using AHRI 540 standard coefficients,
**So that** I can simulate real compressor behavior with manufacturer data.
**Acceptance Criteria:**
**Given** a compressor with 10 AHRI 540 coefficients
**When** I compute residuals for a given operating point
**Then** the power consumption and mass flow are calculated per AHRI 540 equations
**And** the result matches certified AHRI test data within 1%
---
### Story 1.5: Generic Heat Exchanger Framework
**As a** thermal systems engineer,
**I want** a pluggable heat exchanger framework supporting multiple calculation models (Pinch point, LMTD, ε-NTU),
**So that** I can add new exchanger types without modifying the solver.
**Acceptance Criteria:**
**Given** a heat exchanger component
**When** I plug in a calculation model (Pinch, LMTD, or ε-NTU)
**Then** the residuals are computed using the selected model
**And** new models can be added by implementing a HeatTransferModel trait
**And** Condenser, Evaporator, and Economizer are implemented as specific configurations
---
### Story 1.6: Expansion Valve Component
**As a** control engineer,
**I want** to model an expansion valve with isenthalpic expansion,
**So that** I can simulate pressure reduction in the refrigeration cycle.
**Acceptance Criteria:**
**Given** an expansion valve with inlet subcooled liquid at high pressure
**When** I compute residuals
**Then** the outlet is two-phase or saturated liquid at lower pressure
**And** enthalpy is conserved (h_in = h_out)
---
### Story 1.7: Component State Machine
**As a** simulation user,
**I want** components to support ON, OFF, and BYPASS states,
**So that** I can simulate system configurations and failures.
**Acceptance Criteria:**
**Given** a component in ON state
**When** I switch it to OFF
**Then** it contributes zero mass flow to the system
**And** when in BYPASS, it behaves as an adiabatic pipe (P_in = P_out, h_in = h_out)
---
### Story 1.8: Auxiliary & Transport Components
**As a** system integrator,
**I want** to model Pumps, VFDs, and Pipes,
**So that** I can simulate complete HVAC systems.
**Acceptance Criteria:**
**Given** a Pump with specified hydraulic efficiency
**When** I compute residuals
**Then** power consumption and pressure rise match the pump curve
**And** a VFD can modify Pump or Compressor speed via affinity laws
**And** a Pipe calculates pressure drop via Darcy-Weisbach
---
## Epic 2: Fluid Properties Backend
### Story 2.1: Fluid Backend Trait Abstraction
**As a** library developer,
**I want** to define a FluidBackend trait,
**So that** the solver can switch between CoolProp, tabular, and mock backends.
**Acceptance Criteria:**
**Given** a fluid property query
**When** I call backend.property(fluid, property, state)
**Then** it returns correct values regardless of backend implementation
**And** CoolPropBackend, TabularBackend, and TestBackend all implement the trait
---
### Story 2.2: CoolProp Integration (sys-crate)
**As a** simulation user,
**I want** CoolProp as the primary backend,
**So that** I get NIST-quality thermodynamic data.
**Acceptance Criteria:**
**Given** a refrigerant and thermodynamic state
**When** I query via CoolPropBackend
**Then** results match CoolProp 6.4+ within machine precision
**And** C++ CoolProp is statically linked via sys-crate
---
### Story 2.3: Tabular Interpolation Backend
**As a** performance-critical user,
**I want** pre-computed NIST tables with fast interpolation,
**So that** queries are 100x faster than direct EOS.
**Acceptance Criteria:**
**Given** a tabular data file for a fluid
**When** I query via TabularBackend
**Then** results deviate < 0.01% from NIST REFPROP
**And** query time is < 1μs
---
### Story 2.4: LRU Cache for Fluid Properties
**As a** solver developer,
**I want** lock-free or thread-local caching,
**So that** redundant calculations are avoided without mutex contention.
**Acceptance Criteria:**
**Given** repeated property queries
**When** cache is enabled
**Then** Thread-Local or lock-free (dashmap) caching is used
**And** no mutex contention under high parallelism (Rayon)
**And** cache invalidates on state changes
---
### Story 2.5: Mixture and Temperature Glide Support
**As a** refrigeration engineer,
**I want** robust (P, h) and (P, x) inputs for zeotropic mixtures,
**So that** the solver handles temperature glide reliably.
**Acceptance Criteria:**
**Given** a zeotropic mixture at constant pressure
**When** calculating evaporation
**Then** temperature glide from bubble to dew point is correct
**And** backend supports (P, h) and (P, x) inputs robustly
**And** (P, h) is preferred over (P, T) for two-phase mixtures
---
### Story 2.6: Critical Point Damping (CO2 R744)
**As a** CO2 systems designer,
**I want** smooth, differentiable damping near critical point,
**So that** Newton-Raphson converges without discontinuities.
**Acceptance Criteria:**
**Given** CO2 near critical point (Tc=304.13K, Pc=7.3773 MPa)
**When** querying within 5% of critical point
**Then** damping is applied to partial derivatives
**And** no NaN values
**And** damping function is C1-continuous (sigmoid transition)
---
### Story 2.7: Incompressible Fluids Support
**As a** HVAC engineer,
**I want** water, glycol, and moist air as incompressible fluids,
**So that** heat sources/sinks are fast to compute.
**Acceptance Criteria:**
**Given** an incompressible fluid
**When** querying density, Cp, or enthalpy
**Then** lightweight polynomial models are used
**And** results match references within 0.1%
**And** computation is 1000x faster than compressible EOS
---
### Story 2.8: Rich Thermodynamic State Abstraction
**As a** system engineer,
**I want** components to expose a comprehensive `ThermoState` structure (P, T, T_sat, Quality, tsh, Reynolds, Enthalpy, Entropy, etc.),
**So that** I don't have to manually calculate these from raw state arrays after solver convergence.
**Acceptance Criteria:**
**Given** a converged component (e.g., Compressor or Condenser)
**When** I call `component.outlet_thermo_state()`
**Then** it returns a `ThermoState` object
**And** the object contains dynamically resolved saturated temperature, vapor quality, superheat, and phase
**And** `FluidBackend` natively supports resolving this full snapshot in one trait call `full_state(p, h)`
---
## Epic 3: System Topology (Graph)
### Story 3.1: System Graph Structure
**As a** system modeler,
**I want** edges to index the solver's state vector,
**So that** P and h unknowns assemble into the Jacobian.
**Acceptance Criteria:**
**Given** components with ports
**When** adding to System graph
**Then** edges serve as indices into solver's state vector
**And** each flow edge represents P and h unknowns
**And** solver traverses graph to assemble Jacobian
**And** cycles are detected and validated
---
### Story 3.2: Port Compatibility Validation
**As a** system designer,
**I want** port connection validation at build time,
**So that** incompatible connections are caught early.
**Acceptance Criteria:**
**Given** two ports with incompatible fluids
**When** attempting to connect
**Then** connection fails with clear error
**And** valid connections are accepted
**And** pressure/enthalpy continuity is enforced
---
### Story 3.3: Multi-Circuit Machine Definition
**As a** R&D engineer (Marie),
**I want** machines with N independent circuits,
**So that** I simulate complex heat pumps.
**Acceptance Criteria:**
**Given** a machine with 2+ circuits
**When** defining topology
**Then** each circuit is tracked independently
**And** circuits can be solved simultaneously or sequentially
**And** supports up to N=5 circuits
---
### Story 3.4: Thermal Coupling Between Circuits
**As a** systems engineer,
**I want** thermal coupling with circular dependency detection,
**So that** solver knows to solve simultaneously vs sequentially.
**Acceptance Criteria:**
**Given** two circuits with a heat exchanger
**When** defining thermal coupling
**Then** heat transfer equations link circuits
**And** energy is conserved (Q_hot = -Q_cold)
**And** circular dependencies force simultaneous solving
**And** coupling represented as additional residuals
---
### Story 3.5: Zero-Flow Branch Handling
**As a** simulation user,
**I want** zero-flow handling with regularization,
**So that** OFF components don't cause numerical instabilities.
**Acceptance Criteria:**
**Given** a branch with mass flow = 0
**When** computing residuals
**Then** no division-by-zero
**And** regularization applied (ε minimum in divisions)
**And** auto-switch to pressure continuity when OFF
**And** Jacobian remains well-conditioned
---
### Story 3.6: Hierarchical Subsystems (MacroComponents)
**As a** system designer,
**I want** to encapsulate a complete system (e.g., a Chiller with compressor, condenser, valve, evaporator) into a single reusable block,
**So that** I can compose larger models (like buildings or parallel chiller plants) using these blocks, just like in Modelica.
**Acceptance Criteria:**
**Given** a fully defined `System` with internal components and connections
**When** I wrap it in a `MacroComponent`
**Then** I can expose specific internal ports (e.g., Evaporator Water In/Out, Condenser Water In/Out) as the `MacroComponent`'s external ports
**And** this `MacroComponent` implements the `Component` trait
**And** I can add it to a higher-level `System` just like any regular component
**And** the global solver correctly flattens or delegates the residual and jacobian computations down to the nested components.
---
## Epic 4: Intelligent Solver Engine
### Story 4.1: Solver Trait Abstraction
**As a** numerical developer,
**I want** a generic Solver trait,
**So that** strategies are interchangeable.
**Acceptance Criteria:**
**Given** a system of equations
**When** instantiating solver strategies
**Then** all implement common Solver trait
**And** provides solve() and with_timeout() methods
**And** zero-cost abstraction via enum dispatch
---
### Story 4.2: Newton-Raphson Implementation
**As a** simulation engineer,
**I want** Newton-Raphson with analytical Jacobian support,
**So that** HIL performance is optimized.
**Acceptance Criteria:**
**Given** a system with residuals
**When** running Newton-Raphson
**Then** quadratic convergence near solution
**And** line search prevents overshooting
**And** supports both numerical and analytical Jacobian
**And** components provide analytical Jacobian entries
---
### Story 4.3: Sequential Substitution (Picard) Implementation
**As a** fallback solver user,
**I want** Sequential Substitution for robust convergence,
**So that** when Newton diverges, I have a stable alternative.
**Acceptance Criteria:**
**Given** a system where Newton diverges
**When** using Sequential Substitution
**Then** it converges reliably
**And** variables updated sequentially
**And** relaxation factors configurable
---
### Story 4.4: Intelligent Fallback Strategy
**As a** simulation user,
**I want** automatic fallback with smart return conditions,
**So that** convergence is guaranteed without solver oscillation.
**Acceptance Criteria:**
**Given** Newton-Raphson diverging
**When** divergence detected (> 3 increasing residuals)
**Then** auto-switch to Sequential Substitution
**And** return to Newton ONLY when convergence radius reached
**And** prevent oscillation by requiring stable Picard first
---
### Story 4.5: Time-Budgeted Solving
**As a** HIL engineer (Sarah),
**I want** strict timeout with graceful degradation,
**So that** real-time constraints are never violated.
**Acceptance Criteria:**
**Given** solver with timeout = 1000ms
**When** time budget exceeded
**Then** solver stops immediately
**And** returns best state with ComputationStatus::Timeout
**And** for HIL, returns previous state with ZOH
---
### Story 4.6: Smart Initialization Heuristic
**As a** R&D engineer (Marie),
**I want** automatic initial guesses from temperatures,
**So that** cold start convergence is fast.
**Acceptance Criteria:**
**Given** source and sink temperatures
**When** initializing system
**Then** pressures estimated via Antoine equation
**And** evaporator pressure < P_critical
**And** condenser pressure from T_sink + ΔT_approach
---
### Story 4.7: Convergence Criteria & Validation
**As a** simulation user,
**I want** strict criteria with sparse Jacobian for multi-circuit,
**So that** large systems remain tractable.
**Acceptance Criteria:**
**Given** system approaching solution
**When** checking convergence
**Then** max |ΔP| < 1 Pa
**And** mass error < 1e-9 kg/s, energy < 1e-6 kW
**And** ALL circuits converge for global convergence
**And** Jacobian uses sparse/block structure
**And** uncoupled circuits give block-diagonal
---
### Story 4.8: Jacobian-Freezing Optimization
**As a** performance-critical user,
**I want** to freeze Jacobian updates,
**So that** CPU time is reduced.
**Acceptance Criteria:**
**Given** nearly-converged system
**When** Jacobian freezing enabled
**Then** Jacobian computed once, reused
**And** speed increases ~80%
**And** auto-disabled if residuals increase
---
## Epic 5: Inverse Control & Optimization
### Story 5.1: Constraint Definition Framework
**As a** control engineer,
**I want** to define output constraints,
**So that** I specify target operating conditions.
**Acceptance Criteria:**
**Given** measurable outputs
**When** defining constraint (output - target = 0)
**Then** constraint added to residuals
**And** can reference any component output
**And** multiple constraints supported
---
### Story 5.2: Bounded Control Variables
**As a** control engineer,
**I want** Box Constraints or Step Clipping,
**So that** Newton steps stay physically possible.
**Acceptance Criteria:**
**Given** control variable with bounds [min, max]
**When** computing Newton step (Δx)
**Then** step scaled/clipped if exceeding bounds
**And** variable never outside bounds during iterations
**And** ControlSaturation error if converged solution exceeds bounds
---
### Story 5.3: Residual Embedding for Inverse Control
**As a** systems engineer,
**I want** constraints embedded with DoF validation,
**So that** system is well-posed.
**Acceptance Criteria:**
**Given** constraint and control variable
**When** solving system
**Then** residual added to residual vector
**And** control variable added to unknowns
**And** solved simultaneously (one-shot)
**And** Jacobian includes constraint/∂control
**And** DoF validated (equations = unknowns)
**And** OverConstrainedSystem error if mismatch
---
### Story 5.4: Multi-Variable Control
**As a** control engineer,
**I want** to control multiple outputs simultaneously,
**So that** I optimize complete operation.
**Acceptance Criteria:**
**Given** multiple constraints
**When** defining control problem
**Then** each constraint maps to one control variable
**And** all solved simultaneously
**And** all constraints satisfied within tolerance
---
## Epic 6: Multi-Platform APIs
### Story 6.1: Rust Native API
**As a** Rust developer,
**I want** clean, idiomatic Rust API,
**So that** I integrate into Rust applications.
**Acceptance Criteria:**
**Given** a Rust application
**When** using entropyk crate
**Then** builder pattern for systems
**And** all functions return Result<T, ThermoError>
**And** follows Rust conventions
**And** KaTeX documentation
---
### Story 6.2: Python Bindings (PyO3)
**As a** Python data scientist (Alice),
**I want** zero-copy NumPy support,
**So that** 100x speedup isn't wasted on conversion.
**Acceptance Criteria:**
**Given** Python script with rust_thermo_cycle
**When** creating components
**Then** API similar to tespy
**And** errors mapped to Python exceptions
**And** wheels on PyPI (manylinux)
**And** Buffer Protocol and NumPy arrays supported
**And** zero-copy for 10k+ element vectors
**And** 100x faster than tespy
---
### Story 6.3: C FFI Bindings (cbindgen)
**As a** HIL engineer (Sarah),
**I want** C headers with explicit memory management,
**So that** PLC integration has no memory leaks.
**Acceptance Criteria:**
**Given** C/C++ application
**When** including headers
**Then** extern "C" interface available
**And** headers auto-generated via cbindgen
**And** error codes as enum values
**And** opaque pointers for complex types
**And** every allocation has free function (e.g., entropyk_free_system)
**And** latency < 20ms
---
### Story 6.4: WebAssembly Compilation
**As a** web developer (Charlie),
**I want** WASM with TabularBackend default,
**So that** it works without CoolProp in browser.
**Acceptance Criteria:**
**Given** web application
**When** importing WASM module
**Then** can create and solve in browser
**And** results JSON-serializable
**And** deterministic performance
**And** package on npm
**And** defaults to TabularBackend (CoolProp unavailable in WASM)
**And** works out-of-box in Chrome/Edge
**And** cycle time < 100ms
---
### Story 6.5: CLI for Batch Execution
**As a** data engineer (David),
**I want** CLI for batch simulations,
**So that** I process millions of scenarios.
**Acceptance Criteria:**
**Given** JSON config file
**When** running entropyk-cli run config.json
**Then** simulation executes
**And** outputs results to JSON
**And** batch mode supports parallel execution
**And** progress reported
**And** exit codes indicate success/failure
---
## Epic 7: Validation & Persistence
### Story 7.1: Mass Balance Validation
**As a** simulation engineer,
**I want** automatic mass conservation verification,
**So that** I trust physical correctness.
**Acceptance Criteria:**
**Given** converged solution
**When** computing mass balance
**Then** error Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s
**And** violations trigger validation error
**And** check performed after every solve
---
### Story 7.2: Energy Balance Validation
**As a** simulation engineer,
**I want** First AND Second Law verification,
**So that** thermodynamic consistency is guaranteed.
**Acceptance Criteria:**
**Given** converged solution
**When** computing balances
**Then** energy error < 1e-6 kW
**And** violations trigger error with breakdown
**And** Second Law check: entropy generation 0
**And** warning if negative entropy destruction
**And** violations flagged
---
### Story 7.3: Traceability Metadata
**As a** researcher (Robert),
**I want** complete traceability metadata,
**So that** simulations are reproducible.
**Acceptance Criteria:**
**Given** simulation result
**When** accessing metadata
**Then** includes solver_version, fluid_backend_version, input_hash (SHA-256)
**And** SHA-256 uniquely identifies input
**And** metadata in structured JSON
---
### Story 7.4: Debug Verbose Mode
**As a** researcher (Robert),
**I want** detailed convergence diagnostics,
**So that** I debug non-converging systems.
**Acceptance Criteria:**
**Given** non-converging system
**When** verbose mode enabled
**Then** residuals logged each iteration
**And** Jacobian condition number reported
**And** solver switches logged
**And** final state dumped
---
### Story 7.5: JSON Serialization & Deserialization
**As a** system designer,
**I want** complete system serialization with backend definition,
**So that** models are reproducible across machines.
**Acceptance Criteria:**
**Given** system with components, connections, parameters
**When** serializing to JSON
**Then** complete state saved (Topology + Parameters + Fluid State)
**And** fluid backend fully included (version, hash)
**And** deserialization reconstructs identical system
**And** round-trip produces identical results
**And** human-readable, versioned format
**And** explicit error if backend missing on load
**And** error specifies required backend version
---
### Story 7.6: Component Calibration Parameters (Calib)
**As a** R&D engineer matching simulation to real machine test data,
**I want** calibration factors (Calib: f_m, f_dp, f_ua, f_power, f_etav) on components,
**So that** simulation results align with manufacturer test data and field measurements.
**Acceptance Criteria:**
**Given** a component with nominal model parameters
**When** Calib (calibration factors) are set (default 1.0 = no correction)
**Then** f_m scales mass flow: ṁ_eff = f_m × ṁ_nominal (Compressor, Expansion Valve)
**And** f_dp scales pressure drop: ΔP_eff = f_dp × ΔP_nominal (Pipe, Heat Exchanger)
**And** f_ua scales thermal conductance: UA_eff = f_ua × UA_nominal (Evaporator, Condenser)
**And** f_power scales compressor power: Ẇ_eff = f_power × Ẇ_nominal (Compressor)
**And** f_etav scales volumetric efficiency: η_v,eff = f_etav × η_v,nominal (Compressor, displacement models)
**Given** calibration factors from test data optimization
**When** running simulation with calibrated components
**Then** results match test data within configurable tolerance (e.g., capacity ±2%, power ±3%)
**And** Calib values are serializable in JSON (persisted with system definition)
**And** calibration workflow order documented: f_m f_dp f_ua, then f_power (prevents parameter fighting)
**Given** a calibrated system
**When** loading from JSON
**Then** Calib parameters are restored
**And** traceability metadata includes calibration source (test data hash or identifier)
---
### Story 7.7: ASHRAE 140 / BESTEST Validation (post-MVP)
**As a** simulation engineer seeking industrial credibility,
**I want** to validate Entropyk against ASHRAE Standard 140 and BESTEST test cases,
**So that** results are comparable to EnergyPlus, TRNSYS, and Modelica.
**Acceptance Criteria:**
**Given** ASHRAE 140 / Airside HVAC BESTEST (AE101AE445) test case definitions
**When** running Entropyk on equivalent cycle configurations
**Then** results fall within documented tolerance bands vs reference
**And** discrepancies are documented (algorithmic, modeling assumptions)
**And** CI includes regression tests for selected cases
**Given** a new Entropyk release
**When** running validation suite
**Then** no regression beyond tolerance
**And** validation report generated (JSON or markdown)
---
### Story 7.8: Inverse Calibration (Parameter Estimation)
**As a** R&D engineer with test bench data,
**I want** to estimate Calib (or component) parameters from measured data,
**So that** the model matches my machine without manual tuning.
**Acceptance Criteria:**
**Given** test data (P, T, , , Q at multiple operating points)
**When** running inverse calibration
**Then** optimizer minimizes error (e.g., MAPE) between model and data
**And** estimated Calib (or coefficients) are returned
**And** supports constraints (e.g., 0.8 f_ua 1.2)
**And** calibration order respected (f_m f_dp f_ua f_power)
**Given** calibrated parameters
**When** saving system
**Then** Calib values and calibration_source (data hash) persisted in JSON
---
## Epic 8: Component-Fluid Integration
### Story 8.1: Fluid Backend Component Integration
**As a** systems engineer,
**I want** the thermodynamic components (Compressor, Condenser, etc.) to use the real `FluidBackend`,
**So that** the residuals sent to the solver reflect accurate physical states.
**Acceptance Criteria:**
**Given** a component needing physical properties
**When** the solver computes its residuals
**Then** it natively references the configured `FluidBackend`
**And** returns real values vs placeholders
**And** handles missing backends gracefully with fallbacks
---
### Story 1.9: Air Coils (EvaporatorCoil, CondenserCoil) (post-MVP)
**As a** HVAC engineer modeling split systems or air-source heat pumps,
**I want** explicit EvaporatorCoil and CondenserCoil components,
**So that** air-side heat exchangers (finned) are clearly distinguished from water-cooled.
**Acceptance Criteria:**
**Given** an EvaporatorCoil (refrigerant + air)
**When** defining the component
**Then** 4 ports: refrigerant in/out, air in/out
**And** UA or geometry (fins, tubes) configurable
**And** integrates with Fan for air flow
**And** Calib (f_ua, f_dp) applicable
**Given** a CondenserCoil
**Then** same structure as EvaporatorCoil
**And** refrigerant condenses on hot side, air on cold side
---
### Story 1.10: Pipe Helpers for Water and Refrigerant
**As a** HVAC engineer modeling refrigerant and incompressible fluid circuits (water, seawater, glycol),
**I want** convenient constructors `Pipe::for_incompressible()` and `Pipe::for_refrigerant()` with explicit ρ/μ from a fluid backend,
**So that** I can create pipes without hardcoding fluid properties in the component.
**Acceptance Criteria:**
**Given** an incompressible fluid circuit (water, seawater, glycol)
**When** calling `Pipe::for_incompressible(geometry, port_inlet, port_outlet, density, viscosity)`
**Then** accepts explicit ρ, μ obtained from IncompressibleBackend (Story 2.7)
**And** no hardcoded fluid properties in components crate
**And** doc examples show water and glycol usage
**Given** a refrigerant circuit (R134a, R410A, CO2, etc.)
**When** calling `Pipe::for_refrigerant(geometry, port_inlet, port_outlet, density, viscosity)`
**Then** accepts explicit ρ, μ (from CoolProp/tabular at design point)
**And** doc examples show refrigerant circuit usage
**And** doc states that ρ, μ vary with P,T design-point values are typical
**Given** the Pipe module documentation
**When** reading the crate-level and `Pipe` docs
**Then** explicitly states that Pipe serves for both refrigerant and incompressible fluids
**And** includes a "Fluid Support" section: refrigerant (ρ/μ from backend) vs incompressible (ρ/μ from IncompressibleBackend)
---
## Future Epics (Vision littérature HVAC)
*Non planifiés alignement avec EnergyPlus, Modelica, TRNSYS :*
| Epic | Thème | Référence littérature |
|------|-------|------------------------|
| **Transient** | Simulation dynamique, start-up/shutdown, ODEs | Reddy, Purdue IIAR |
| **Part-load** | Courbes PLF, pertes de cyclage | EnergyPlus PLF |
| **Frost/Defrost** | Givre, dégivrage, enthalpy method | arXiv 2412.00017 |
| **Moving Boundary** | Échangeurs discretisés, zones phase | Modelica Buildings, TIL Suite |
| **Export ML** | Données synthétiques pour surrogates | arXiv 2505.15041 |