--- 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 ### 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 | ## 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 --- ### 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 --- ### 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 --- ## 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 --- ## 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