--- 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 (Σ Q̇ + Ẇ - Σ (ṁ · 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 (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 **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 | ## 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. **Innovation:** Multi-fluid directed graph in a single model. **FRs covered:** FR9, FR10, FR11, FR12, FR13 --- ### 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 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 --- ## 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 **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 (AE101–AE445) 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 --- ### 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 |