Files
Entropyk/docs/simulation-capabilities.md
sepehr 5bd180b5b8
Some checks failed
CI / check (push) Has been cancelled
Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
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>
2026-07-19 16:35:31 +02:00

132 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Entropyk — Simulation Capabilities & Modelica Comparison / Capacités de simulation & comparaison Modelica
> Bilingual document (English first, French below) / Document bilingue (anglais d'abord, français ensuite).
>
> This analysis is **code-grounded**: every claim is traceable to the Rust sources in `crates/`.
> Cette analyse est **fondée sur le code** : chaque affirmation est traçable dans les sources Rust de `crates/`.
---
## EN — What Entropyk can simulate
### 1. Nature of the tool
Entropyk is a **steady-state, equation-based** thermodynamic-cycle simulator for refrigeration, heat-pump and HVAC systems. It is *not* a general-purpose DAE engine (like OpenModelica); it is a **domain-specific algebraic solver** built around a component graph.
- **Solving paradigm**: each component contributes residual equations `r(x) = 0` and an **analytic Jacobian**. The global system `F(x) = 0` is solved with NewtonRaphson, Picard (sequential substitution), a Newton-homotopy continuation, and a `FallbackSolver` that chains them. (`crates/solver/src/strategies/`)
- **State vector**: per flow edge `(ṁ, P, h)`; series branches share a single mass-flow unknown after a topology presolve (`|B| + 2·|E|` layout). (`crates/solver/src/system.rs`)
- **Fluid properties**: `CoolPropBackend` (production), `TestBackend` (mock/ideal), plus `TabularBackend` and `IncompressibleBackend` in the library. (`crates/fluids/`)
### 2. System-level capabilities
| Capability | Status | Evidence |
|---|---|---|
| Coupled algebraic solving with analytic Jacobian | ✅ | `Component::jacobian_entries`, `System::assemble_jacobian` |
| Explicit degrees-of-freedom balancing | ✅ | `System::validate_inverse_control_dof`, mass-flow presolve |
| Emergent pressures (SST/SDT float from HX↔secondary balance) | ✅ | `Condenser::with_emergent_pressure`, `Evaporator` `superheat_regulated` |
| Multi-circuit networks (up to 5) | ✅ | `CircuitId 0..4`, per-circuit flow edges |
| Inter-circuit thermal coupling (`thermal_couplings`) | ✅ physical mode | Set `hot_component` (duty provider, e.g. an ε-NTU `Condenser`) + `cold_component` (a `ThermalLoad` receiver): the coupling owns one unknown Q closed against the hot component's measured duty (`Q = η·duty_hot`) and injects Q into the cold loop's energy balance — First Law closes across circuits (`chiller_r410a_coupled_water_loop.json`). Entries without both fields are inert (Q pinned to 0, CLI warns). |
| Secondary-stream heat exchange (air/water, ε-NTU) | ✅ | `Condenser`/`Evaporator` `secondary_inlet_temp_c` + `secondary_mass_flow_kg_s` + `secondary_cp_j_per_kgk`; emergent capacity/COP (e.g. `chiller_r410a_full_physics.json` → COP≈4.98, First Law closes) |
| Steady-state supervisory control, co-solved | ✅ | `SaturatedController` (offset-free PI, anti-windup) |
| Override / selector priority (min/max) | ✅ | `override_network.rs`, smoothed `softMin/softMax`, activation continuation |
| Inverse / one-shot calibration | ✅ | `inverse/calibration.rs`, Z-factors `z_flow, z_dp, z_ua, z_power, z_etav` |
| Free actuators (e.g. EXV orifice opening) | ✅ | `System` free-actuator DoF (+1 unknown / +1 component eq) |
| Reusable parameterized subsystems (flattened) | ✅ | CLI `subsystems`/`instances`/`connections``flatten_instances()` |
| Hierarchical composition in Rust | ⚠️ partial | `MacroComponent` couples P/h at ports; ṁ continuity not yet coupled |
| Normative seasonal rating (IPLV/ESEER/SCOP/SEER) | ✅ | CLI `rate`, `scop`, `seer` (re-solves the cycle per load point/bin) |
| ON/OFF/BYPASS staging | ✅ (pre-solve) | `OperationalState`, `circuits[].enabled` |
| BOLT-style inline spec/probe nodes | ✅ | `Anchor` (= BOLT `BoundaryNode.Refrigerant.Node`): probe mode (DoF-neutral) or one imposed spec — signed `superheat_k` (dTsh, <0 = subcooling), `quality`, `t_c`/`t_k`, `p_bar` (`docs/components/anchor-heat-source.md`) |
| Inline heat injection (fixed or coupling-linked) | ✅ | `HeatSource` (= BOLT `BoundaryNode.Heat.Source`): `q_w` fixed duty + optional coupling-driven Q (motor-cooling pattern), exact Jacobian, excluded from COP aggregation (`chiller_r410a_bolt_nodes.json`) |
| Boundary-imposed loop flow | ✅ | `BrineSource`/`BrineSink` `m_flow_kg_s` (= BOLT `Vd_fixed=true`) |
### 3. Can we build models as complex as Modelica?
**Yes for the targeted domain, with caveats.** Entropyk reproduces the *ideas* that make Modelica HVAC libraries powerful:
- equation-based components with a coupled solve,
- reusable parameterized subsystems,
- co-solved supervisory control (setpoint tracking + min/max override priority, exactly the "BOLT"-style chiller control referenced in the code),
- inverse calibration and normative rating.
You can assemble multi-circuit chillers/heat-pumps with emergent pressures, secondary-fluidcoupled heat exchangers, economizer screw compressors, liquid injection, head-pressure control, free-cooling, and a supervisory control tree — comparable in *structural* complexity to a Modelica chiller model.
### 4. Gaps vs Modelica (be precise)
- **Steady-state only** — no time integration, no `der(x)`, no dynamic states (thermal masses, sensor lags). Everything targets `F(x)=0`.
- **No event handling** — no zero-crossing / reinit; `ModeSwitch` (hysteresis, min-runtime) lives *outside* the Newton solve and is time-based.
- **Causal edge connectors** — state is carried on edges/branches as `(ṁ,P,h)`; continuity is enforced by component residuals referencing state indices (a TESPy-like pattern), not Modelica acausal connectors with shared variables and language-level connection equations.
- **Hierarchy is mostly compile-time / flattened** — the CLI flattens subsystems before solving; nested subsystems inside the solver require Rust `MacroComponent`, whose port ṁ-continuity is still incomplete.
- **`thermal_couplings` transfers a measured duty, not a UA·ΔT law** — the physical mode closes `Q = η·duty_hot` (the hot component's ε-NTU duty) into a `ThermalLoad` receiver; the `ua` field is not used as a coupling conductance. For a genuinely two-sided UA·LMTD interface exchanger, use a two-sided `HeatExchanger`/BPHX or a secondary stream instead. Legacy entries without `hot_component`/`cold_component` are inert (Q pinned to 0, CLI warns).
- **CLI fluids limited** to CoolProp/Test (Tabular/Incompressible exist in the lib but are not wired to the CLI).
- **No user-authored arbitrary equations** — new behaviour requires implementing the `Component` trait in Rust.
### 5. One-sentence verdict
Entropyk is closer to a **TESPy/BOLT-style steady-state cycle solver with co-solved algebraic supervisory control and inverse calibration** than to a general Modelica DAE engine: excellent structural parity for HVAC/refrigeration cycles, but without transients, events, or acausal language-level connectors.
---
## FR — Ce qu'Entropyk permet de simuler
### 1. Nature de l'outil
Entropyk est un simulateur de **cycles thermodynamiques en régime permanent (steady-state)**, basé sur les **équations**, pour la réfrigération, les pompes à chaleur et le CVC. Ce n'est *pas* un moteur DAE généraliste (comme OpenModelica) : c'est un **solveur algébrique dédié au domaine**, organisé autour d'un graphe de composants.
- **Paradigme de résolution** : chaque composant fournit des équations résiduelles `r(x) = 0` et un **Jacobien analytique**. Le système global `F(x) = 0` est résolu par NewtonRaphson, Picard (substitution séquentielle), une continuation par homotopie de Newton, et un `FallbackSolver` qui les enchaîne. (`crates/solver/src/strategies/`)
- **Vecteur d'état** : par arête de flux `(ṁ, P, h)` ; les branches en série partagent un seul inconnu de débit après un presolve topologique (layout `|B| + 2·|E|`). (`crates/solver/src/system.rs`)
- **Propriétés fluides** : `CoolPropBackend` (production), `TestBackend` (mock/gaz idéal), plus `TabularBackend` et `IncompressibleBackend` dans la bibliothèque. (`crates/fluids/`)
### 2. Capacités au niveau système
| Capacité | État | Preuve (code) |
|---|---|---|
| Résolution algébrique couplée + Jacobien analytique | ✅ | `Component::jacobian_entries`, `System::assemble_jacobian` |
| Équilibrage explicite des degrés de liberté (DoF) | ✅ | `System::validate_inverse_control_dof`, presolve débit |
| Pressions émergentes (SST/SDT flottent selon l'équilibre HX↔secondaire) | ✅ | `Condenser::with_emergent_pressure`, `Evaporator` `superheat_regulated` |
| Réseaux multi-circuits (jusqu'à 5) | ✅ | `CircuitId 0..4`, arêtes de flux par circuit |
| Couplage thermique inter-circuits (`thermal_couplings`) | ✅ mode physique | Renseigner `hot_component` (fournisseur de puissance, ex. `Condenser` ε-NTU) + `cold_component` (récepteur `ThermalLoad`) : le couplage porte un inconnu Q fermé sur la puissance mesurée du composant chaud (`Q = η·duty_hot`) et injecte Q dans le bilan d'énergie de la boucle froide — le 1er principe ferme entre circuits (`chiller_r410a_coupled_water_loop.json`). Les entrées sans ces deux champs sont inertes (Q épinglé à 0, la CLI avertit). |
| Échange par flux secondaire (air/eau, ε-NTU) | ✅ | `Condenser`/`Evaporator` `secondary_inlet_temp_c` + `secondary_mass_flow_kg_s` + `secondary_cp_j_per_kgk` ; capacité/COP émergents (ex. `chiller_r410a_full_physics.json` → COP≈4.98, 1er principe fermé) |
| Contrôle supervisoire steady-state, co-résolu | ✅ | `SaturatedController` (PI offset-free, anti-windup) |
| Priorité par override / sélecteur (min/max) | ✅ | `override_network.rs`, `softMin/softMax` lissés, continuation d'activation |
| Calibration inverse / one-shot | ✅ | `inverse/calibration.rs`, facteurs Z `z_flow, z_dp, z_ua, z_power, z_etav` |
| Actuateurs libres (ex. ouverture orifice EXV) | ✅ | DoF free-actuator (+1 inconnu / +1 éq. composant) |
| Sous-systèmes paramétrés réutilisables (aplatis) | ✅ | CLI `subsystems`/`instances`/`connections``flatten_instances()` |
| Composition hiérarchique en Rust | ⚠️ partiel | `MacroComponent` couple P/h aux ports ; continuité ṁ pas encore couplée |
| Rating saisonnier normatif (IPLV/ESEER/SCOP/SEER) | ✅ | CLI `rate`, `scop`, `seer` (re-résout le cycle par point/bin) |
| Staging ON/OFF/BYPASS | ✅ (pré-solve) | `OperationalState`, `circuits[].enabled` |
| Nœuds spec/sonde inline style BOLT | ✅ | `Anchor` (= `BoundaryNode.Refrigerant.Node` de BOLT) : mode sonde (neutre en DoF) ou une spec imposée — `superheat_k` signé (dTsh, <0 = sous-refroidissement), `quality`, `t_c`/`t_k`, `p_bar` (`docs/components/anchor-heat-source.md`) |
| Injection de chaleur inline (fixe ou liée à un couplage) | ✅ | `HeatSource` (= `BoundaryNode.Heat.Source` de BOLT) : puissance fixe `q_w` + Q optionnel piloté par couplage (pattern refroidissement moteur), Jacobien exact, exclu de l'agrégation COP (`chiller_r410a_bolt_nodes.json`) |
| Débit de boucle imposé à la frontière | ✅ | `BrineSource`/`BrineSink` `m_flow_kg_s` (= `Vd_fixed=true` de BOLT) |
### 3. Peut-on bâtir des modèles aussi complexes que Modelica ?
**Oui pour le domaine visé, avec des réserves.** Entropyk reproduit les *idées* qui font la puissance des bibliothèques HVAC Modelica :
- composants basés équations, résolus de façon couplée ;
- sous-systèmes paramétrés réutilisables ;
- contrôle supervisoire co-résolu (suivi de consigne + priorité min/max, exactement le style de contrôle chiller « BOLT » référencé dans le code) ;
- calibration inverse et rating normatif.
On peut assembler des groupes froids / PAC multi-circuits avec pressions émergentes, échangeurs couplés au fluide secondaire, compresseurs à vis avec économiseur, injection liquide, contrôle de pression de refoulement, free-cooling et un arbre de contrôle supervisoire — d'une complexité *structurelle* comparable à un modèle chiller Modelica.
### 4. Écarts vs Modelica (précis)
- **Régime permanent uniquement** — pas d'intégration temporelle, pas de `der(x)`, pas d'états dynamiques (masses thermiques, retards capteurs). Tout vise `F(x)=0`.
- **Pas de gestion d'événements** — pas de zero-crossing / reinit ; `ModeSwitch` (hystérésis, durée min) est *hors* du Newton et basé sur le temps.
- **Connecteurs causaux par arête** — l'état est porté par les arêtes/branches en `(ṁ,P,h)` ; la continuité est imposée par des résidus composants référençant des indices d'état (motif type TESPy), pas des connecteurs acausaux Modelica à variables partagées.
- **Hiérarchie surtout compile-time / aplatie** — la CLI aplatit les sous-systèmes avant résolution ; l'imbrication dans le solveur passe par `MacroComponent` (Rust), dont la continuité ṁ aux ports est incomplète.
- **`thermal_couplings` transfère une puissance mesurée, pas une loi UA·ΔT** — le mode physique ferme `Q = η·duty_hot` (la puissance ε-NTU du composant chaud) dans un récepteur `ThermalLoad` ; le champ `ua` ne sert pas de conductance de couplage. Pour un échangeur d'interface UA·LMTD réellement à deux flux, utiliser un `HeatExchanger`/BPHX à deux flux ou un flux secondaire. Les entrées legacy sans `hot_component`/`cold_component` sont inertes (Q épinglé à 0, la CLI avertit).
- **Fluides CLI limités** à CoolProp/Test (Tabular/Incompressible existent dans la lib mais ne sont pas branchés à la CLI).
- **Pas d'équations utilisateur arbitraires** — tout nouveau comportement nécessite d'implémenter le trait `Component` en Rust.
### 5. Verdict en une phrase
Entropyk se rapproche d'un **solveur de cycles steady-state type TESPy/BOLT avec contrôle supervisoire algébrique co-résolu et calibration inverse**, plutôt que d'un moteur DAE Modelica généraliste : excellente parité structurelle pour les cycles CVC/réfrigération, mais sans transitoire, sans événements, ni connecteurs acausaux au niveau langage.
---
## Component catalog / Catalogue des composants
See per-component bilingual documentation in [`docs/components/`](./components/README.md).
Voir la documentation bilingue par composant dans [`docs/components/`](./components/README.md).