Some checks failed
CI / check (push) Has been cancelled
Capture uncommitted solver robustness work (regularization, domain errors, linear solver lifecycle, tube DP/MSH), web workbench updates, and synced BMAD skills across IDE agent folders before starting BPHX pressure-drop. Co-authored-by: Cursor <cursoragent@cursor.com>
373 lines
22 KiB
Markdown
373 lines
22 KiB
Markdown
# Entropyk — Development Handoff
|
||
|
||
> **Purpose.** This document hands off the current state of Entropyk to a new
|
||
> coding tool / session. It summarizes **what was done**, **why it was done that
|
||
> way** (key technical decisions), and **what remains to do**, so work can resume
|
||
> without loss of context.
|
||
>
|
||
> **Conventions (from `AGENTS.md`).** Communicate with the user (**Sepehr**) in
|
||
> **French**; write all code / docs / commit messages in **English**. Rust package
|
||
> manager = **cargo**; Python = **uv** (venv at repo-root `.venv`).
|
||
>
|
||
> **Last updated:** 2026-07-07
|
||
|
||
---
|
||
|
||
## 1. Project overview
|
||
|
||
**Entropyk** is a Rust steady-state thermodynamic-cycle simulation library for
|
||
refrigeration, heat pumps and HVAC. The goal (Sepehr's) is to make it a
|
||
best-in-class HVAC **design + control** simulator — **very accurate and very
|
||
fast** — to replace an internal tool. Hard rule from the user: **no "bricolage"**
|
||
(no hacks such as auto-injecting design-point temperatures). Every model must be
|
||
**genuinely physically coupled** and must **respect the First Law**.
|
||
|
||
### Workspace layout
|
||
|
||
```
|
||
entropyk/
|
||
├── crates/
|
||
│ ├── core/ # Strong types (Pressure, Temperature, Enthalpy…), smoothing primitives
|
||
│ ├── components/ # Thermodynamic components (Compressor, HX, valves, ReversingValve…)
|
||
│ ├── fluids/ # Fluid backends (CoolProp, tabular, incompressible)
|
||
│ ├── solver/ # Newton-Raphson / Picard / Homotopy, System topology, DoF, controls
|
||
│ ├── entropyk/ # Main library facade (System, SystemBuilder, rating)
|
||
│ ├── cli/ # CLI: run / qualify / rate / scop / seer commands
|
||
│ ├── vendors/ # Vendor data parsers
|
||
│ └── bindings/ # Python (PyO3), C (cbindgen), WASM — DO NOT build in this env
|
||
├── apps/web/ # Dymola-style web UI (SvelteKit + Vitest)
|
||
├── _bmad/ , _bmad-output/ # BMAD methodology workflows + artifacts
|
||
└── AGENTS.md # Project instructions (READ FIRST)
|
||
```
|
||
|
||
---
|
||
|
||
## 2. What has been DONE (verified)
|
||
|
||
### 2.1 Genuine secondary-side coupling of heat exchangers (ε-NTU)
|
||
The core goal: HX respond to **secondary** (water / brine / air) temperature & flow.
|
||
- `Condenser`, `Evaporator` and `FloodedEvaporator` brought to the same coupled
|
||
ε-NTU level. Secondary fields (`secondary_inlet_temp_k`, `secondary_capacity_rate`),
|
||
builders `with_secondary_stream` / `set_secondary_stream`, helpers `coupled_ready`,
|
||
`coupled_duty`, `effectiveness`, `cond_temperature` / `evap_temperature`.
|
||
- Coupled residual path active only when a secondary stream is set AND indices
|
||
resolved AND P_in > 10 kPa (otherwise legacy path — **backward compatible, DoF
|
||
unchanged**). `Q = ε·C_sec·ΔT`, `ε = 1 − exp(−UA/C_sec)` (C_min = C_sec for a
|
||
phase-changing refrigerant). Analytical Jacobian (dT/dP via central FD).
|
||
- Files: `crates/components/src/heat_exchanger/{condenser,evaporator}.rs`.
|
||
|
||
### 2.2 Emergent pressures (end-to-end coupling) — the "vrais modèles échangeurs" epic
|
||
Condensing / evaporating **pressures are now emergent** from the HX↔secondary
|
||
balance instead of fixed by compressor design points. Opt-in `emergent_pressure`
|
||
mode on each component:
|
||
- **Compressor** (`comp-emergent`): mass-flow closure `ṁ = ρ_suc·V_s·N·η_vol`;
|
||
r0 = ṁ_state − ṁ_calc.
|
||
- **Condenser** (`cond-emergent`) / **Evaporator** (`evap-emergent`): 3 thermo eqs
|
||
(ΔP, energy balance, outlet closure), `n_equations` +1.
|
||
- **EXV** (`exv-emergent`): drops the P_evap fix, keeps only isenthalpic h3=h2,
|
||
`n_equations` −1.
|
||
- Integration test: 4-component emergent loop converges; varying secondary T/flow
|
||
changes COP/capacity; **DoF balanced (9=9)**.
|
||
|
||
### 2.3 Modular control architecture (arch-1 … arch-6) — ALL DONE
|
||
- **arch-1** Saturated-PI controller wired into System DoF (2 residuals + 2 unknowns
|
||
per loop; actuator u → CalibIndices, measurement y ← measure_output; co-solved).
|
||
- **arch-2** Typed ports `PortKind{Refrigerant, Secondary, Mechanical, Signal}` +
|
||
edge validation by kind; Signal ports for control wiring.
|
||
- **arch-3** `controls[]` schema + control-block library (Min/Max/Setpoint/Limiter),
|
||
CLI design/control command co-solving design + control.
|
||
- **arch-4** subsystems/instances hierarchical templates (reusable parameterized
|
||
assemblies flattened to graph; multi-circuit A/B).
|
||
- **arch-5** unified model IR across CLI / Python / WASM / UI (schema v2 loader,
|
||
v1-compatible).
|
||
- **arch-6** **Physical actuators — all 6 done**, each with exact analytic Jacobian
|
||
(FD only for property derivatives) and CLI wiring + example + integration test:
|
||
1. **EXV orifice** — `ṁ = Cd·A(θ)·√(2ρΔP)`, opening as bounded solver var.
|
||
2. **Fan head-pressure** — air-cooled condenser: secondary air capacity rate scales
|
||
with fan speed; fan speed controls condensing pressure. `UA_eff=(1−λ)·UA_nom`.
|
||
3. **Slide-valve** (screw compressor) — capacity modulation of swept volume.
|
||
4. **Liquid-injection** EXV — economized screw, controls discharge temperature
|
||
(factor-actuator: closed by a `controls[]` loop, does NOT grow `n_equations`).
|
||
5. **Flooded-condenser level** (`cond-level`) — head-pressure via liquid level;
|
||
mirrors the fan actuator, mutually exclusive with it (shares `fan_actuator_idx`).
|
||
Exact flood Jacobian `∂r1/∂λ = +UA_nom·(T_cond−T_sec)·exp(−UA_eff/C_sec)`.
|
||
6. **Four-way reversing valve** — see §2.6.
|
||
- **p0a** real constraint measurement via fluid backend (removed mocked
|
||
superheat / subcooling / capacity in `system.rs`).
|
||
- **p0b** compressor variable-speed capacity actuator (bounded `speed_hz` DoF).
|
||
|
||
### 2.4 Modular seasonal rating (SEER / SCOP / IPLV / NPLV / ESEER) — DONE
|
||
Per Sepehr's request that **the standards be swappable when norms change**:
|
||
- `rate.rs` — AHRI 550/590 IPLV/NPLV/ESEER: re-solve base scenario at each part-load
|
||
point overriding secondary temps + compressor speed; rayon-parallel points.
|
||
- `seasonal.rs` — EN 14825 bin method (SCOP/SEER): per-bin coupled re-solve driven by
|
||
outdoor temp, linear building load line, Cd cycling degradation, backup heater.
|
||
**Modular climate selection** (`BinClimateStandard`) so climates/standards are
|
||
pluggable.
|
||
- CLI subcommands `rate`, `scop`, `seer` + example configs + unit & integration tests.
|
||
- French `CLI_TUTORIAL` section for these commands.
|
||
- **Full documentation written** (per user request).
|
||
|
||
### 2.5 Circuit on/off staging — DONE
|
||
- `CircuitConfig.enabled: bool` (`#[serde(default = "default_true")]`) in
|
||
`crates/cli/src/config.rs`. A disabled circuit's components / edges / thermal
|
||
couplings are **never added to the `System`** → excluded from the solve entirely
|
||
(zero mass flow / duty). Physically-correct steady-state for an unenergized
|
||
circuit, **not** a hack.
|
||
- 5 circuit-iteration loops in `run.rs` skip-guarded; all-disabled → early rejection.
|
||
- Example `chiller_r134a_dual_circuit_staging.json`. Verified e2e: both on = 15.139 kW
|
||
/ COP 4.379 (8 edges); circuit B off = 7.569 kW (4 edges) = exactly half.
|
||
- 2 CLI integration tests pass.
|
||
- NOTE: the component-level `OperationalState{On,Off,Bypass}` in
|
||
`state_machine.rs` exists but is **dead code w.r.t. the solver** — staging is done
|
||
at CLI/config level, not via that enum.
|
||
|
||
### 2.6 Four-way reversing valve (arch-6 #6) — DONE
|
||
- `crates/components/src/reversing_valve.rs`: `ReversingValve` + `ReversingMode{Cooling,
|
||
Heating}`. Deterministic inline 2-port pass-through:
|
||
- r0 = P_out − (P_in − ΔP), `ΔP = ΔP_base + k·ṁ·|ṁ|`
|
||
- r1 = h_out − (h_in + Δh_leak)
|
||
- r2 = ṁ_out − ṁ_in (dropped when the inlet/outlet share a mass-flow index)
|
||
- `n_equations` = 2 or 3. Exact analytic Jacobian (`∂ΔP/∂ṁ = k·2|ṁ|`).
|
||
- **DoF-neutral**: emits a pressure *relation* (not a fix), so it works unchanged
|
||
in both fixed-pressure and emergent-pressure cycles.
|
||
- **Key modeling decision (honest, no bricolage):** the validated cycle uses
|
||
`Δh_leak = 0` (**isenthalpic ΔP-only**). A non-zero single-stream leak enthalpy
|
||
injects `ṁ·Δh_leak` with **no matching source** → it broke machine-level First Law
|
||
(measured 0.077 kW imbalance, wrong sign on the discharge line). The rigorous
|
||
discharge→suction leak needs a **bypass-mass split (two streams)** — deferred to a
|
||
future topology layer. The ΔP alone (~0.25 bar valve-body drop) already reproduces
|
||
the cited ~1–3 % COP/capacity penalty **and closes the First Law exactly**. The
|
||
`leak_enthalpy` parameter is retained + documented for the future bypass-mass model.
|
||
- CLI arm `"ReversingValve" | "FourWayValve"`. Example
|
||
`heatpump_r410a_reversing_valve.json` (reversible R410A air→water HP, heating mode,
|
||
RV on discharge line, all emergent). **Verified e2e:** converges 5 iters, ΔP
|
||
39.068 → 38.788 bar, Q_cool 9.918 kW / Q_heat 15.486 kW / Power 5.491 kW, EER 1.806,
|
||
First Law closes. 5 unit tests + 1 CLI integration test
|
||
(`test_reversing_valve_imposes_pressure_drop_penalty`).
|
||
|
||
### 2.7 Fluids accuracy fix — DONE
|
||
- `entropyk-fluids :: tabular_backend::tests::test_tabular_vs_coolprop_accuracy` was
|
||
failing (embedded `r134a.json` density >1 % off vs CoolProp). Fixed **properly** by
|
||
regenerating the table from CoolProp (not by widening epsilon).
|
||
|
||
### 2.8 Web UI (apps/web) — DONE (earlier turns)
|
||
- Secondary ports (`secondary_inlet` / `secondary_outlet`, labeled htf·in / htf·out)
|
||
on all HX; `resolveSecondaryStreams` maps a connected boundary source into HX
|
||
secondary params and hides secondary edges from the solver graph.
|
||
- Dymola-style light UI, grid snap, node rotation. Vitest suite green (61 tests).
|
||
|
||
### 2.9 Workspace warning cleanup — 0 warnings
|
||
- `cargo build --workspace --all-targets` (bindings excluded) emits **0 warnings**.
|
||
- Notable real fix: `crates/components/src/brine_boundary.rs` `mod tests` was missing
|
||
`#[cfg(test)]` (compiled into normal builds). Migrated deprecated
|
||
`TEMP_MASS_FLOW_SEED_KG_S` → `DEFAULT_MASS_FLOW_SEED_KG_S` across 8 solver test files.
|
||
|
||
---
|
||
|
||
## 3. Key technical patterns & conventions (carry these forward)
|
||
|
||
- **Free-actuator DoF pattern**: +1 unknown appended at the END of the state vector.
|
||
*Setpoint* actuators (slide / fan / cond-level) grow `n_equations()` by 1; *factor*
|
||
actuators (liquid-injection) do NOT — a `controls[]` loop closes them.
|
||
- **Two Component conventions coexist**:
|
||
- *Port-based* (e.g. `ExpansionValve<Connected>` reads `self.port_inlet`).
|
||
- *Index-based* (`IsenthalpicExpansionValve`, `Condenser`, `ReversingValve`):
|
||
`set_system_context(offset, &[(m_idx,p_idx,h_idx); edges])`, edge[0]=inlet,
|
||
edge[1]=outlet, then reads `state[idx]`. **The emergent CLI cycle uses the
|
||
index-based convention.** `IsenthalpicExpansionValve` is the template for new
|
||
inline components (its `get_ports()` returns `&[]`).
|
||
- **`same_branch_m`**: true when inlet_m_idx == outlet_m_idx (series-branch collapse,
|
||
CM1.4) → drop the mass-conservation residual.
|
||
- **Jacobian policy**: exact analytic required. FD allowed ONLY for property
|
||
derivatives (dT/dP, dρ/dP). Never numerical-diff a whole residual.
|
||
- **Emergent vs fixed pressure**: emit pressure *relations* (ΔP), not absolute
|
||
pressure *fixes*, to stay DoF-neutral across both topologies.
|
||
- **First Law is a hard gate**: `System::cycle_performance` sums every component's
|
||
`energy_transfers`; any unsourced enthalpy injection breaks closure. Do not add
|
||
energy without a physical source (this is what killed the leak-enthalpy model).
|
||
- **Smoothing**: use `entropyk_core::smoothing` (smoothstep, smootherstep,
|
||
cubic/quintic_blend, smooth_max/min/abs/clamp) for C¹/C² correlation transitions —
|
||
never ad-hoc `if`/`tanh` — to keep the Newton Jacobian continuous.
|
||
- **CRLF gotcha**: example JSONs are written with CRLF on Windows; test string-patches
|
||
using `\n` fail silently. Split on a distinctive marker (e.g. `"Circuit B"`) then
|
||
`replacen`.
|
||
- **`edit` tool gotcha**: verify match-arm headers (`"Pipe" => {`) survive edits;
|
||
re-view files after risky edits.
|
||
- **AGENTS.md integration protocol**: a new component must be integrated across Rust
|
||
core+solver, CLI, Python (PyO3), and WASM. Several new components currently have
|
||
Rust core + CLI only (bindings pending — see §5).
|
||
|
||
---
|
||
|
||
## 4. Build / test / run
|
||
|
||
```bash
|
||
# Build & test core crates (bindings excluded — they DON'T build in this env)
|
||
cargo build --workspace --all-targets --exclude entropyk-python --exclude entropyk-c --exclude entropyk-wasm
|
||
cargo test -p entropyk-core -p entropyk-components -p entropyk-solver -p entropyk-cli -p entropyk
|
||
|
||
# Targeted (fast) examples
|
||
cargo test -p entropyk-components reversing_valve
|
||
cargo test -p entropyk-cli --test single_run test_reversing_valve_imposes_pressure_drop_penalty
|
||
cargo run -q -p entropyk-cli -- run --config crates/cli/examples/heatpump_r410a_reversing_valve.json
|
||
|
||
# Frontend
|
||
cd apps/web && npm run test # Vitest
|
||
cd apps/web && npm run dev # http://localhost:3000
|
||
cargo run --package entropyk-demo --bin ui-server # backend http://localhost:3030
|
||
|
||
# Python bindings (uv only — never pip)
|
||
uv run maturin develop --release
|
||
uv run pytest crates/bindings/python/tests/
|
||
```
|
||
|
||
**Guardrails:** NEVER `cargo test --workspace` (pyo3 fails on Python 3.14). CLI
|
||
integration tests are slow (~1–2 min each, real CoolProp solve) and self-skip when
|
||
CoolProp is unavailable (`if status != Converged { return; }`). `cargo test` accepts
|
||
only ONE positional TESTNAME filter per invocation.
|
||
|
||
---
|
||
|
||
## 5. What REMAINS to do (prioritized)
|
||
|
||
### 5.1 In progress / immediate
|
||
- **`adv-override-control`** *(DONE 2026-07-07)* — Modelica-style **override/selector
|
||
control** + **offset-free** saturated-PI. (1) Fixed the control law to the
|
||
canonical offset-free form `r_y = K(y_ref−y) − (x − S(x))` (was `x + S(x)`, a
|
||
droop with steady-state offset that forced fragile high gains → the reported
|
||
convergence/slowness). (2) New `inverse/override_network.rs`: one actuator
|
||
arbitrated by several `Objective{output,setpoint,gain,combine:min|max}` folded
|
||
through C^∞ `softMin/softMax` with **exact analytic selector weights** (Jacobian-
|
||
smoothing; literature-backed robustness). (3) `SaturatedController` gains opt-in
|
||
`objectives`+`alpha`; `system.rs` residual/Jacobian branch for network mode
|
||
(`∂E/∂col = Σ w_i(−gain_i)∂y_i/∂col`). (4) Config `controls[].objectives[]`+`alpha`
|
||
(schema-exposed), `run.rs` wiring. Example `chiller_r134a_exv_override.json`;
|
||
unit + FD-Jacobian + CLI integration tests (286 solver tests pass). Spec:
|
||
`_bmad-output/implementation-artifacts/spec-advanced-override-control.md`.
|
||
ROBUSTNESS (done): warm-started **ADAPTIVE activation continuation**
|
||
(`SaturatedController::activation` λ walked 0→1 by `run.rs`: primary-only
|
||
baseline → full network). The λ-step now uses the **same predictor–corrector
|
||
control as `strategies::homotopy`** — start 0.5, **halve on any failed solve**
|
||
(retry from the last good λ), grow on success, floor `MIN_LAMBDA_STEP=5e-3` —
|
||
so the walk auto-refines through the hard switching region and takes big steps
|
||
elsewhere; each step is seeded from the previous solution. CLI also wires
|
||
`solver.max_iterations`/`tolerance` into every solver stage (was capped at 100).
|
||
Measured effect: markedly wider convergence range vs the old fixed `[0,0.5,1]`
|
||
schedule (aggressive EXV overrides now converge through many more intermediate
|
||
λ). Known **physical** limit (not a solver defect): with a `superheat_regulated`
|
||
evaporator and the EXV opening as the *only* actuator, forcing capacity well
|
||
below the natural duty drives `∂capacity/∂opening → 0` → the plant Jacobian goes
|
||
singular (loss of controllability). The robust demonstrated path uses a
|
||
well-conditioned actuator (compressor `f_m`), covered by the passing test
|
||
`test_override_capacity_limit_takes_authority_via_continuation`.
|
||
NEXT (optional): a second actuator (e.g. compressor speed) to restore
|
||
controllability for deep EXV duty cuts; optional setpoint **scheduling**
|
||
(`Table1D/2D`/`Poly`) per the PPTX/CombiTable patterns.
|
||
- **`p0b-exv-opening`** *(DONE 2026-07-07)* — controllable EXV opening regulates
|
||
evaporator **superheat**. Evaporator gains an opt-in `superheat_regulated` mode
|
||
(drops the emergent outlet-closure `r2` → superheat emerges from the ε-NTU energy
|
||
balance); a `controls[]` saturated loop with `actuator.factor:"opening"` drives the
|
||
opening (wired to `CalibIndices.actuator`), the EXV orifice residual closes it, DoF
|
||
stays square (orifice +1, drop r2 −1, saturated +2/+2). Real `measure_output(Superheat)`
|
||
added. Example `chiller_r134a_superheat_control.json`, integration + unit tests, +
|
||
fail-fast config guards. Spec: `_bmad-output/implementation-artifacts/spec-p0b-exv-opening.md`.
|
||
- **`p0c-json-schema`** *(LARGELY DONE — audit before extending)* — the CLI `schema`
|
||
command already emits the canonical Model IR JSON Schema (`emit_schema` →
|
||
`ScenarioConfig::json_schema()` via `schemars`); `controls[]` (saturated loops) parse
|
||
and co-solve; bounded control variables are expressed in `actuator{initial,min,max}`;
|
||
`parse_component_output` supports capacity/superheat/subcooling/saturationTemperature/
|
||
massflow/pressure/temperature. REMAINING (optional): a dedicated top-level hard-inverse
|
||
`constraints[]` array + a distinct `design`/`control` CLI command (today `run` co-solves
|
||
everything).
|
||
- **`p0c-ui-align`** — make the control schema map cleanly to the `apps/web`
|
||
node/port model so the UI can generate/consume it. **(User note: a UI is being
|
||
developed in parallel — keep schema UI-friendly.)**
|
||
- **`p0-tests-docs`** — unit + integration tests proving control actually regulates
|
||
(varying target changes state physically); update docs.
|
||
|
||
### 5.2 Bindings (AGENTS.md protocol — currently Rust+CLI only)
|
||
- **Python (PyO3) + WASM** wrappers for the new components/actuators, notably
|
||
`ReversingValve`, flooded-level, slide-valve, liquid-injection.
|
||
- ⚠️ **Blocked in this env**: PyO3 max supported Python is 3.13 but the interpreter
|
||
is 3.14. Fix by upgrading `pyo3` in `crates/bindings/python` OR pinning the uv env
|
||
to 3.13, then verify `uv run maturin develop --release` + `uv run pytest`. The
|
||
bindings crates may be absent from the current snapshot — confirm before starting.
|
||
|
||
### 5.3 Water-cooled machines (workspace `61XW_VFD_EMEA`, `30XF`, `61AQ` references)
|
||
- **`wc-single-circuit-e2e`** — compressor + condenser + EXV + flooded-evap with water
|
||
loops both sides; validate convergence + secondary sensitivity. *Easiest first-class
|
||
target (no air/fan/defrost).*
|
||
- **`wc-multicircuit`** — parallel dual-circuit (A/B) compressors/HX with a shared
|
||
secondary manifold (`System_2C`).
|
||
- **`wc-pass-count`** — 1P/2P/3P evaporator & condenser pass configuration.
|
||
- **`wc-slide-valve`** — second actuator alongside speed (`CompressorControl_double`).
|
||
*(A screw slide-valve actuator already exists — this is the water-cooled twin-actuator
|
||
variant.)*
|
||
- **`exv-sst-actuator`** — make EXV opening physically move suction saturated temp /
|
||
mass flow so a SaturatedController can regulate SST.
|
||
|
||
### 5.4 Real-machine feature blocks (30XF / 61AQ parity)
|
||
- **`rm-staging`** — 1–4 module staging state machine (61AQ `StateMachine`). *(Circuit
|
||
on/off staging at config level is done; this is the multi-module controller.)*
|
||
- **`rm-fan-headp`** — air-cooled condenser SDT limit → fan speed via SaturatedController.
|
||
*(A fan head-pressure actuator exists — this is the closed-loop controller variant.)*
|
||
- **`rm-exv-orifice`** — `ṁ=Cd·A(θ)·√(2ρΔP)` opening sets emergent P_evap=SST (matches
|
||
61AQ `EXVControl_cooling`). *(Orifice actuator exists — this is the SST loop.)*
|
||
- **`rm-freecool`** — free-cooling exchanger + glycol routing + OAT changeover (30XF).
|
||
- **`rm-defrost`** — defrost seasonal correction block (`Auxiliary.Defrost.Defrost_factor`).
|
||
- **`rm-en14511`** — EN 14511 net-from-gross corrections (pump/fan penalties on net
|
||
capacity/power).
|
||
- **`rm-moistair`** — moist-air (RH / wet-bulb) psychrometric properties for air-side HX.
|
||
- **`rm-surrogate`** — MCHX/compressor surrogate-map (performance-map) backend for HX
|
||
and compressor (speed/accuracy trade-off).
|
||
|
||
### 5.5 Web UI
|
||
- Circuit **`enabled` toggle** in `apps/web` configBuilder (emit `"enabled": false`).
|
||
- Keep the control JSON schema aligned with the UI node/port model (see `p0c-ui-align`).
|
||
|
||
### 5.6 Bigger / architectural (research-backed)
|
||
- Consider a **modular Modelica-style** model/controller composition system (user's
|
||
explicit interest) — arch-1…6 laid the groundwork (typed ports, subsystems, unified
|
||
IR, controls[]); next is a first-class reusable controller/model library and
|
||
possibly acausal connectors.
|
||
- Performance: exploit `research-improve` findings (surrogate maps, warm-starting,
|
||
Anderson acceleration already present, parallel rating points already via rayon).
|
||
|
||
---
|
||
|
||
## 6. Known environment limitations
|
||
- **Python bindings do not build here**: PyO3 max 3.13 vs interpreter 3.14.
|
||
- **`cargo test --workspace` fails** for the same reason — test crates individually.
|
||
- CoolProp is enabled via Cargo features; CLI/solver runs need **no** `--features`
|
||
flag. CLI integration tests self-skip without CoolProp.
|
||
|
||
---
|
||
|
||
## 7. Key files map
|
||
| Area | Path |
|
||
| --- | --- |
|
||
| Project instructions | `AGENTS.md` |
|
||
| Coupled HX | `crates/components/src/heat_exchanger/{condenser,evaporator,flooded_evaporator}.rs` |
|
||
| Reversing valve | `crates/components/src/reversing_valve.rs` |
|
||
| Inline-component template | `crates/components/src/isenthalpic_expansion_valve.rs` |
|
||
| Compressor + actuators | `crates/components/src/isentropic_compressor.rs` |
|
||
| System / DoF / performance | `crates/solver/src/system.rs` |
|
||
| Controls / saturated PI | `crates/solver/src/inverse/saturated_control.rs` |
|
||
| Smoothing primitives | `crates/core/src/smoothing.rs` |
|
||
| CLI wiring hub | `crates/cli/src/run.rs` |
|
||
| CLI config schema | `crates/cli/src/config.rs` |
|
||
| Rating / seasonal | `crates/cli/src/{rate,seasonal,qualify}.rs` |
|
||
| CLI integration tests | `crates/cli/tests/single_run.rs` |
|
||
| Examples | `crates/cli/examples/*.json` |
|
||
| Web UI | `apps/web/src/lib/{componentMeta,configBuilder}.ts` |
|
||
| Session artifacts | `_bmad-output/implementation-artifacts/sprint-status.yaml` |
|
||
|
||
---
|
||
|
||
## 8. Test status snapshot (at handoff)
|
||
- **PASS**: entropyk-core, entropyk-components (792), entropyk-solver (+integration),
|
||
entropyk, entropyk-cli, web vitest (61). **0 warnings** on core crates.
|
||
- **Fixed**: `entropyk-fluids` tabular-accuracy test (regenerated r134a.json).
|
||
- **Not buildable in this env**: `bindings/python` (PyO3 vs Python 3.14).
|