Features: - BMAD (Build Modular AI-driven Development) framework setup - BMM, BMB, CIS, Core modules configured - Story 1.1: Component trait with error handling - Workspace Cargo.toml with components crate - 31 tests passing (19 unit + 12 doc tests) Technical: - Component trait with compute_residuals, jacobian_entries, n_equations - ComponentError enum with thiserror - JacobianBuilder for sparse matrix construction - Object-safe trait supporting Box<dyn Component> - Comprehensive documentation and examples
1010 lines
31 KiB
Markdown
1010 lines
31 KiB
Markdown
---
|
|
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<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
|
|
|
|
### 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 |
|
|
|
|
## 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
|
|
|
|
---
|
|
|
|
<!-- 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
|
|
|
|
---
|
|
|
|
## 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<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
|