Rewrite French project docs for architecture, solver, and CLI.
Bring the root README, technical manual, and CLI guide in sync with post-CM1.x state (m,P,h), Modelica Fixed/Free, and current component catalog. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
403
DOCUMENTATION.md
403
DOCUMENTATION.md
@@ -1,138 +1,355 @@
|
|||||||
# Entropyk: Technical Manual & Reference Guide
|
# Entropyk — Manuel technique
|
||||||
|
|
||||||
Entropyk is a high-performance thermodynamic simulation framework designed for precision modeling of HVAC/R systems. This manual provides exhaustive documentation of the physical models, solver mechanics, and multi-platform APIs.
|
Entropyk est un cadre de simulation thermodynamique en régime permanent pour systèmes HVAC/R (chillers, pompes à chaleur, cycles frigorifiques). Ce manuel détaille les fondations physiques, les modèles de composants, le solveur, les DoF, et les API multi-plateformes.
|
||||||
|
|
||||||
|
Pour un tour d’horizon orienté utilisateur : [`README.md`](./README.md).
|
||||||
|
Pour le CLI JSON : [`crates/cli/README.md`](./crates/cli/README.md).
|
||||||
|
Pour Fixed/Free Modelica : [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Physical Foundations
|
## Table des matières
|
||||||
|
|
||||||
### 1.1 Dimensional Analysis & Type Safety
|
1. [Fondations physiques](#1-fondations-physiques)
|
||||||
Entropyk utilizes a "Type-Safe Dimension" pattern to eliminate unit errors. Every physical quantity is wrapped in a NewType that enforces SI base units internally.
|
2. [Fluides (`entropyk-fluids`)](#2-fluides-entropyk-fluids)
|
||||||
|
3. [Composants (`entropyk-components`)](#3-composants-entropyk-components)
|
||||||
| Quantity | Internal Unit (SI) | Documentation Symbol |
|
4. [Solveur (`entropyk-solver`)](#4-solveur-entropyk-solver)
|
||||||
| :--- | :--- | :--- |
|
5. [Degrés de liberté (DoF)](#5-degrés-de-liberté-dof)
|
||||||
| Pressure | Pascal ($Pa$) | $P$ |
|
6. [Frontières Fixed / Free](#6-frontières-fixed--free)
|
||||||
| Temperature | Kelvin ($K$) | $T$ |
|
7. [Fonctionnalités avancées](#7-fonctionnalités-avancées)
|
||||||
| Enthalpy | Joule per kilogram ($J/kg$) | $h$ |
|
8. [API multi-plateformes](#8-api-multi-plateformes)
|
||||||
| Mass Flow | Kilogram per second ($kg/s$) | $\dot{m}$ |
|
9. [Démarrage et références](#9-démarrage-et-références)
|
||||||
| Density | Kilogram per cubic meter ($kg/m^3$) | $\rho$ |
|
|
||||||
|
|
||||||
### 1.2 Conservation Laws
|
|
||||||
The solver operates on the principle of local conservation at every node $i$:
|
|
||||||
- **Mass Conservation**: $\sum \dot{m}_{in} - \sum \dot{m}_{out} = 0$
|
|
||||||
- **Energy Conservation**: $\sum (\dot{m} \cdot h)_{in} - \sum (\dot{m} \cdot h)_{out} + \dot{Q} - \dot{W} = 0$
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Fluid Physics (`entropyk-fluids`)
|
## 1. Fondations physiques
|
||||||
|
|
||||||
The `FluidBackend` trait provides thermodynamic properties $(T, \rho, c_p, s)$ as functions of state variables $(P, h)$.
|
### 1.1 Typage dimensionnel
|
||||||
|
|
||||||
### 2.1 Backend Implementations
|
Chaque grandeur est un *newtype* SI — pas de `f64` nu aux frontières publiques.
|
||||||
|
|
||||||
#### A. CoolProp Backend
|
| Grandeur | Unité interne SI | Symbole |
|
||||||
Utilizes full Helmholtz energy equations of state (EOS).
|
|----------|------------------|---------|
|
||||||
- **Domain**: Precise research and steady-state validation.
|
| Pression | Pascal (Pa) | \(P\) |
|
||||||
- **Complexity**: $O(N)$ high overhead due to iterative property calls.
|
| Température | Kelvin (K) | \(T\) |
|
||||||
|
| Enthalpie massique | J/kg | \(h\) |
|
||||||
|
| Débit massique | kg/s | \(\dot{m}\) |
|
||||||
|
| Densité | kg/m³ | \(\rho\) |
|
||||||
|
| Puissance | W | \(\dot{Q}\), \(\dot{W}\) |
|
||||||
|
|
||||||
#### B. Tabular Backend (Bicubic)
|
Les configs JSON acceptent souvent °C / bar pour l’ergonomie ; la conversion vers SI se fait à la construction des composants.
|
||||||
Uses high-fidelity lookup tables with bicubic Hermite spline interpolation.
|
|
||||||
- **Equation**: $Z(P, h) = \sum_{i=0}^3 \sum_{j=0}^3 a_{ij} \cdot P^i \cdot h^j$
|
|
||||||
- **Performance**: $O(1)$ constant time with SIMD acceleration. Recommended for HIL.
|
|
||||||
|
|
||||||
#### C. Incompressible Backend (Linearized)
|
### 1.2 Lois de conservation
|
||||||
For water, glycols, and brines where $\rho$ is nearly constant.
|
|
||||||
- **Density**: $\rho(T) = \rho_0 \cdot [1 - \beta(T - T_0)]$
|
|
||||||
- **Enthalpy**: $h = c_p \cdot (T - T_0)$
|
|
||||||
|
|
||||||
### 2.2 Phase Change Logic
|
Sur chaque nœud / branche, le solveur impose localement :
|
||||||
Fluid backends automatically identify the fluid phase:
|
|
||||||
1. **Subcooled**: $h < h_{sat,l}(P)$
|
|
||||||
2. **Two-Phase**: $h_{sat,l}(P) \le h \le h_{sat,v}(P)$
|
|
||||||
3. **Superheated**: $h > h_{sat,v}(P)$
|
|
||||||
|
|
||||||
For two-phase flow, quality $x$ is defined as:
|
- **Masse** : \(\sum \dot{m}_{\mathrm{in}} - \sum \dot{m}_{\mathrm{out}} = 0\) (souvent trivialisée sur branche série via ṁ partagé)
|
||||||
$$x = \frac{h - h_{sat,l}}{h_{sat,v} - h_{sat,l}}$$
|
- **Énergie** : \(\sum (\dot{m}\,h)_{\mathrm{in}} - \sum (\dot{m}\,h)_{\mathrm{out}} + \dot{Q} - \dot{W} = 0\)
|
||||||
|
|
||||||
|
### 1.3 Vecteur d’état
|
||||||
|
|
||||||
|
Chaque **arête** du graphe porte **trois** inconnues :
|
||||||
|
|
||||||
|
\[
|
||||||
|
\mathbf{x}_{\mathrm{edge}} = [\dot{m},\; P,\; h]
|
||||||
|
\]
|
||||||
|
|
||||||
|
*(Ancienne doc obsolète : \([P,h]\) seul — post-CM1.x le débit est une inconnue d’arête / de branche.)*
|
||||||
|
|
||||||
|
Sur une chaîne série 1-entrée / 1-sortie, les arêtes partagent souvent le même index ṁ (topologie CM1.4).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Component Technical Reference (`entropyk-components`)
|
## 2. Fluides (`entropyk-fluids`)
|
||||||
|
|
||||||
### 3.1 Compressor (`Compressor`)
|
Trait unifié `FluidBackend` : propriétés \((T,\rho,c_p,s,\ldots)\) en fonction de l’état \((P,h)\) (ou autres paires selon l’appel).
|
||||||
|
|
||||||
#### A. AHRI 540 (10-Coefficient)
|
### 2.1 Implémentations
|
||||||
Standard model for positive displacement compressors. Mass flow $\dot{m}$ and power $W$ are calculated using the 3rd-order polynomial:
|
|
||||||
$$X = C_1 + C_2 T_s + C_3 T_d + C_4 T_s^2 + C_5 T_s T_d + C_6 T_d^2 + C_7 T_s^3 + C_8 T_d T_s^2 + C_9 T_s T_d^2 + C_{10} T_d^3$$
|
|
||||||
*Note: $T_s$ is suction temperature and $T_d$ is discharge temperature in Fahrenheit or Celsius depending on coefficients.*
|
|
||||||
|
|
||||||
#### B. SST/SDT Polynomials
|
| Backend | Rôle |
|
||||||
Used for variable speed compressors where coefficients are adjusted for RPM:
|
|---------|------|
|
||||||
$$\dot{m} = \sum_{i=0}^3 \sum_{j=0}^3 A_{ij} \cdot SST^i \cdot SDT^j$$
|
| **CoolProp** | Équations d’état Helmholtz — précision recherche / validation |
|
||||||
|
| **Tabular** | Tables + splines bicubiques Hermite — \(O(1)\), adapté HIL / WASM |
|
||||||
|
| **Incompressible** | Eau, glycols, saumures — \(\rho(T)\), \(h \approx c_p\,\Delta T\) |
|
||||||
|
| **Cached / Damped** | Wrappers perf / stabilité numérique |
|
||||||
|
| **TestBackend** | Mocks pour tests sans CoolProp |
|
||||||
|
|
||||||
### 3.2 Pipe (`Pipe`)
|
Feature Cargo typique : `coolprop` via `coolprop-sys` (bibliothèque précompilée sous `vendor/coolprop`).
|
||||||
- **Pressure Drop**: $\Delta P = f \cdot \frac{L}{D} \cdot \frac{\rho v^2}{2}$
|
|
||||||
- **Haaland Approximation** (Friction Factor $f$):
|
|
||||||
$$\frac{1}{\sqrt{f}} \approx -1.8 \log_{10} \left[ \left(\frac{\epsilon/D}{3.7}\right)^{1.11} + \frac{6.9}{Re} \right]$$
|
|
||||||
*Where $Re = \frac{\rho v D}{\mu}$ is the Reynolds number.*
|
|
||||||
|
|
||||||
### 3.3 Heat Exchanger (`HeatExchanger`)
|
### 2.2 Phases
|
||||||
Single-phase and phase-change modeling via the $\varepsilon$-NTU method.
|
|
||||||
|
|
||||||
- **Heat Transfer**: $\dot{Q} = \varepsilon \cdot C_{min} \cdot (T_{h,in} - T_{c,in})$
|
1. **Sous-refroidi** : \(h < h_{\mathrm{sat},l}(P)\)
|
||||||
- **Effectiveness ($\varepsilon$)**:
|
2. **Diphasique** : \(h_{\mathrm{sat},l}(P) \le h \le h_{\mathrm{sat},v}(P)\)
|
||||||
- **Counter-Flow**: $\varepsilon = \frac{1 - \exp(-NTU(1 - C^*))}{1 - C^* \exp(-NTU(1 - C^*))}$
|
3. **Surchauffé** : \(h > h_{\mathrm{sat},v}(P)\)
|
||||||
- **Evaporator/Condenser**: $\varepsilon = 1 - \exp(-NTU)$ (since $C^* \to 0$ during phase change)
|
4. **Supercritique** : au-delà du point critique (selon backend)
|
||||||
|
|
||||||
|
Titre vapeur en diphasique :
|
||||||
|
|
||||||
|
\[
|
||||||
|
x = \frac{h - h_{\mathrm{sat},l}}{h_{\mathrm{sat},v} - h_{\mathrm{sat},l}}
|
||||||
|
\]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Solver Engine (`entropyk-solver`)
|
## 3. Composants (`entropyk-components`)
|
||||||
|
|
||||||
The engine solves $\mathbf{F}(\mathbf{x}) = \mathbf{0}$ where $\mathbf{x}$ is the state vector $[P, h]$ for all edges.
|
Tous implémentent le trait `Component` :
|
||||||
|
|
||||||
### 4.1 Newton-Raphson Solver
|
- `n_equations()` — nombre de résidus
|
||||||
Primary strategy for fast, quadratic convergence.
|
- `compute_residuals(state, r)` — \(\mathbf{F}(\mathbf{x})\)
|
||||||
$$\mathbf{J}(\mathbf{x}_k) \Delta \mathbf{x} = -\mathbf{F}(\mathbf{x}_k)$$
|
- `jacobian_entries(state, J)` — \(\partial\mathbf{F}/\partial\mathbf{x}\) (**analytique** de préférence)
|
||||||
$$\mathbf{x}_{k+1} = \mathbf{x}_k + \alpha \Delta \mathbf{x}$$
|
- ports / `set_system_context` / `set_port_context` — indices d’arêtes live
|
||||||
|
|
||||||
- **Armijo Line Search**: Dynamically adjusts $\alpha$ to ensure steady residual reduction.
|
### 3.1 Compresseurs
|
||||||
- **Step Clipping**: Hard bounds on $\Delta P$ and $\Delta h$ to maintain physical sanity (e.g., $P > 0$).
|
|
||||||
- **Jacobian Freezing**: Reuses $\mathbf{J}$ for $N$ steps if convergence is stable, improving speed by ~40%.
|
|
||||||
|
|
||||||
### 4.2 Sequential Substitution (Picard)
|
#### `IsentropicCompressor` (cycles émergents courants)
|
||||||
Fixed-point iteration for robust initialization:
|
|
||||||
$$\mathbf{x}_{k+1} = \mathbf{x}_k - \omega \cdot \mathbf{F}(\mathbf{x}_k)$$
|
- Loi de débit (si non métré) : \(\dot{m} \approx \rho_{\mathrm{suc}}\,V\,N\,\eta_{\mathrm{vol}}\)
|
||||||
*Where $\omega \in (0, 1]$ is the relaxation factor (default 0.5).*
|
- Énergie de refoulement via \(\eta_{\mathrm{is}}\)
|
||||||
|
- `emergent_pressure` : ne pince pas les pressions de design
|
||||||
|
- Mode **ṁ externe** : quand un EXV orifice Fixed métre le débit (CLI)
|
||||||
|
|
||||||
|
#### `Compressor` — AHRI 540 (10 coefficients)
|
||||||
|
|
||||||
|
\[\begin{aligned}
|
||||||
|
X &= C_1 + C_2 T_s + C_3 T_d + C_4 T_s^2 + C_5 T_s T_d + C_6 T_d^2 \\
|
||||||
|
&\quad + C_7 T_s^3 + C_8 T_d T_s^2 + C_9 T_s T_d^2 + C_{10} T_d^3
|
||||||
|
\end{aligned}\]
|
||||||
|
|
||||||
|
où \(X\) est \(\dot{m}\) ou \(\dot{W}\) selon le jeu de coeffs. Unités \(T_s,T_d\) selon la convention du jeu (souvent °F pour AHRI).
|
||||||
|
|
||||||
|
#### Cartes SST/SDT
|
||||||
|
|
||||||
|
\[\dot{m} = \sum_{i,j} A_{ij}\,\mathrm{SST}^i\,\mathrm{SDT}^j\]
|
||||||
|
|
||||||
|
Utilisé aussi pour `ScrewEconomizerCompressor` (vis + port écono, VFD, slide valve).
|
||||||
|
|
||||||
|
#### `CentrifugalCompressor`
|
||||||
|
|
||||||
|
Carte polytropique (facteur de débit, nombre de Mach périphérique).
|
||||||
|
|
||||||
|
### 3.2 Détente
|
||||||
|
|
||||||
|
#### `IsenthalpicExpansionValve` / EXV
|
||||||
|
|
||||||
|
Trois modes :
|
||||||
|
|
||||||
|
| Mode | Équations | Effet de `opening` |
|
||||||
|
|------|-----------|--------------------|
|
||||||
|
| Isenthalpique seul (`emergent_pressure`, **sans** `orifice_kv`) | \(h_{\mathrm{out}}-h_{\mathrm{in}}=0\) | **Aucun** — ṁ = compresseur |
|
||||||
|
| Orifice Fixed (`orifice_kv` + `fix_opening: true`) | + \(\dot{m}=K_v\cdot o\cdot\sqrt{2\rho\Delta P}\) | Paramètre physique |
|
||||||
|
| Orifice Free (`fix_opening: false`) | idem, \(o\) inconnu | Régulation / contrôleur |
|
||||||
|
|
||||||
|
#### `ExpansionValve`, `CapillaryTube`, `ReversingValve`, `BypassValve`
|
||||||
|
|
||||||
|
Voir fiches sous [`docs/components/`](./docs/components/) et meta UI `apps/web/src/lib/componentMeta.ts`.
|
||||||
|
|
||||||
|
### 3.3 Conduits (`Pipe`)
|
||||||
|
|
||||||
|
Chute de pression Darcy–Weisbach :
|
||||||
|
|
||||||
|
\[
|
||||||
|
\Delta P = f\,\frac{L}{D}\,\frac{\rho v^2}{2},\quad
|
||||||
|
\frac{1}{\sqrt{f}} \approx -1{,}8\log_{10}\!\left[\left(\frac{\varepsilon/D}{3{,}7}\right)^{1{,}11}+\frac{6{,}9}{Re}\right]
|
||||||
|
\]
|
||||||
|
|
||||||
|
(Haaland). Mode edge-coupled CLI :
|
||||||
|
|
||||||
|
- `pressure_drop_pa > 0` → ΔP **imposé** constant
|
||||||
|
- `pressure_drop_pa = 0` → ΔP **Darcy** depuis géométrie + ṁ live
|
||||||
|
|
||||||
|
### 3.4 Échangeurs
|
||||||
|
|
||||||
|
#### `HeatExchanger` générique (ε-NTU / LMTD)
|
||||||
|
|
||||||
|
\[
|
||||||
|
\dot{Q} = \varepsilon\, C_{\min}\,(T_{h,\mathrm{in}}-T_{c,\mathrm{in}})
|
||||||
|
\]
|
||||||
|
|
||||||
|
- Contre-courant : \(\varepsilon = \dfrac{1-e^{-NTU(1-C^*)}}{1-C^* e^{-NTU(1-C^*)}}\)
|
||||||
|
- Évap / cond (changement de phase, \(C^*\to 0\)) : \(\varepsilon = 1-e^{-NTU}\)
|
||||||
|
|
||||||
|
En mode 4 ports live : + fermetures isobares \(P_{\mathrm{out}}-P_{\mathrm{in}}=0\) par flux (pattern Modelica Free-P).
|
||||||
|
|
||||||
|
#### `Condenser` / `Evaporator` / `FloodedEvaporator`
|
||||||
|
|
||||||
|
- Côté frigorigène : bilans + fermetures SC / SH / vapeur saturée / qualité
|
||||||
|
- `emergent_pressure` : P flotte, fermée par l’énergie + closures
|
||||||
|
- Secondaire 4 ports : énergie + momentum (isobare ou ΔP quadratique de rating)
|
||||||
|
|
||||||
|
ΔP secondaire type rating :
|
||||||
|
|
||||||
|
\[
|
||||||
|
\Delta P_{\mathrm{sec}} = \Delta P_{\mathrm{rated}}\left(\frac{\dot{m}}{\dot{m}_{\mathrm{rated}}}\right)^2
|
||||||
|
\]
|
||||||
|
|
||||||
|
via `secondary_rated_pressure_drop_pa` + `secondary_rated_m_flow_kg_s`.
|
||||||
|
|
||||||
|
#### Autres HX
|
||||||
|
|
||||||
|
`Bphx*`, `AirCooledCondenser`, `FinCoilCondenser`, `MchxCondenserCoil`, `Economizer`, `GasCooler`, `ShellAndTubeHx`, `FanCoilUnit`, `FreeCoolingExchanger` — corrélations / géométries dédiées (voir modules `heat_exchanger/`).
|
||||||
|
|
||||||
|
### 3.5 Frontières
|
||||||
|
|
||||||
|
| Famille | Rôle |
|
||||||
|
|---------|------|
|
||||||
|
| `RefrigerantSource` / `Sink` | BC frigorigène (P, qualité / h, ṁ) |
|
||||||
|
| `BrineSource` / `Sink` | Eau / glycol (P, T, ṁ, concentration) |
|
||||||
|
| `AirSource` / `Sink` | Air humide (psychrométrie) |
|
||||||
|
|
||||||
|
### 3.6 Hydraulique / air / jonctions
|
||||||
|
|
||||||
|
`Pump`, `Fan` (courbes + affinity laws), `FlowSplitter` / `FlowMerger`, `Drum` (séparateur L/V flooded), `ThermalLoad`, `HeatSource`, `Anchor`, `Node`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Advanced Features
|
## 4. Solveur (`entropyk-solver`)
|
||||||
|
|
||||||
### 5.1 Inverse Control
|
On résout \(\mathbf{F}(\mathbf{x})=\mathbf{0}\) sur le vecteur d’état global (arêtes + actionneurs + couplages).
|
||||||
Swaps independent variables for targets.
|
|
||||||
- **Constraints**: Force specific outputs (e.g., Exit Superheat $= 5K$).
|
|
||||||
- **Bounded Variables**: Physical limits on inputs (e.g., Valve Opening $0 \le x \le 1$).
|
|
||||||
|
|
||||||
### 5.2 Multi-Circuit Coupling
|
### 4.1 Newton–Raphson (défaut CLI)
|
||||||
Modeled via bridge components (typically `HeatExchanger`). The solver constructs a unified Jacobian for both circuits to handle thermal feedback loops in a single pass.
|
|
||||||
|
\[
|
||||||
|
\mathbf{J}(\mathbf{x}_k)\,\Delta\mathbf{x} = -\mathbf{F}(\mathbf{x}_k),\quad
|
||||||
|
\mathbf{x}_{k+1} = \mathrm{clamp}\bigl(\mathbf{x}_k + \alpha\,\Delta\mathbf{x}\bigr)
|
||||||
|
\]
|
||||||
|
|
||||||
|
- **Jacobien** : assemblé depuis les `jacobian_entries` des composants (analytique)
|
||||||
|
- **Armijo** : réduit \(\alpha\) si le résidu ne diminue pas (activé CLI si contrôles / orifice / Free-P eau)
|
||||||
|
- **Gel de Jacobien** : réutilisation de \(\mathbf{J}\) pendant \(N\) itérations stables
|
||||||
|
- **Bornes** : ex. \(P \ge 10\,\mathrm{kPa}\) (`MIN_SOLVER_PRESSURE_PA`) sur les slots pression
|
||||||
|
|
||||||
|
### 4.2 Picard (substitution successive)
|
||||||
|
|
||||||
|
\[
|
||||||
|
\mathbf{x}_{k+1} = (1-\omega)\,\mathbf{x}_k + \omega\,G(\mathbf{x}_k)
|
||||||
|
\]
|
||||||
|
|
||||||
|
avec \(\omega \approx 0{,}5\). Plus robuste, convergence linéaire. Anderson optionnel.
|
||||||
|
|
||||||
|
### 4.3 Fallback
|
||||||
|
|
||||||
|
1. Newton d’abord
|
||||||
|
2. Si divergence → Picard
|
||||||
|
3. Si résidu redescend sous un seuil → retour Newton
|
||||||
|
Nombre max de bascules limité (anti-oscillation).
|
||||||
|
|
||||||
|
### 4.4 Homotopy
|
||||||
|
|
||||||
|
Continuation \(\lambda\) pour chemins difficiles (API solver avancée).
|
||||||
|
|
||||||
|
### 4.5 Seed
|
||||||
|
|
||||||
|
- Frontières : `seed_from_boundary_conditions`
|
||||||
|
- Cycles émergents : staging HP/BP distinct (`build_staged_emergent_seed`)
|
||||||
|
- Actionneurs libres : valeurs initiales nominales
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Multi-Platform API Reference
|
## 5. Degrés de liberté (DoF)
|
||||||
|
|
||||||
Entropyk provides high-fidelity bindings with near-perfect parity.
|
Un système est **carré** ssi :
|
||||||
|
|
||||||
| Feature | Rust (`-core`) | Python (`entropyk`) | C / FFI | WASM |
|
\[
|
||||||
| :--- | :--- | :--- | :--- | :--- |
|
n_{\mathrm{équations}} = n_{\mathrm{inconnues}}
|
||||||
| **Component Creation** | `Compressor::new()` | `ek.Compressor()` | `ek_compressor_create()` | `new Compressor()` |
|
\]
|
||||||
| **System Finalization** | `system.finalize()` | `system.finalize()` | `ek_system_finalize()` | `system.finalize()` |
|
|
||||||
| **Solving** | `config.solve(&sys)` | `config.solve(sys)` | `ek_solve(sys, cfg)` | `await config.solve(sys)` |
|
- Sur-contraint → `TopologyError::DofImbalance` à `finalize()` (porte DoF, défaut ON)
|
||||||
| **Inverse Control** | `sys.add_constraint()` | `sys.add_constraint()` | `ek_sys_add_constraint()` | `sys.addConstraint()` |
|
- Sous-contraint → refusé en production CLI (`validate_system_dof`)
|
||||||
| **Memory Management** | RAII (Automatic) | Ref-Counted (PyO3) | Manual Free (`_free`) | JS Garbage Collected |
|
|
||||||
|
Chaque résidu porte un `EquationRole` (Dirichlet, bilan énergie, fermeture outlet SH/SC, actionneur…).
|
||||||
|
|
||||||
|
**Règle d’or** : ne jamais fixer **à la fois** \(\dot{m}\) et \(P\) sur le même flux sans libérer un autre DoF.
|
||||||
|
|
||||||
|
Ledger UI (aide design, non bit-exact) : `apps/web/src/lib/dofLedger.ts`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Getting Started
|
## 6. Frontières Fixed / Free
|
||||||
- **Step-by-Step Instructions**: Refer to [EXAMPLES_FULL.md](./EXAMPLES_FULL.md).
|
|
||||||
- **Performance**: Use `TabularBackend` for real-time HIL applications.
|
Alignement Modelica `MassFlowSource_T` / `Boundary_pT` — détails et sources : [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md).
|
||||||
- **Custom Physics**: Implement the `Component` trait in Rust for specialized modeling.
|
|
||||||
|
| Pattern | Source | Sink | Remarque |
|
||||||
|
|---------|--------|------|----------|
|
||||||
|
| MassFlowSource_T (**défaut** si ṁ imposé) | Fixed T, Fixed ṁ, **Free P** | Fixed P, Free T_out | HX propage P (isobare / ΔP) |
|
||||||
|
| Boundary_pT + friction | Fixed P, Fixed T, Free ṁ | Fixed P | Pipe / ΔP HX obligatoire |
|
||||||
|
| Rating T_out | Free ṁ | Fixed P + Fixed T_out | ṁ devient inconnu |
|
||||||
|
|
||||||
|
Flags JSON : `fix_pressure`, `fix_temperature`, `fix_mass_flow`.
|
||||||
|
|
||||||
|
Double Fixed-P aux deux extrémités **uniquement** s’il existe une résistance hydraulique entre elles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Fonctionnalités avancées
|
||||||
|
|
||||||
|
### 7.1 Contrôle inverse / calibration
|
||||||
|
|
||||||
|
- **Contraintes** : imposer une sortie (SH = 5 K, capacité = …)
|
||||||
|
- **Variables bornées** : actionneurs (`opening`, `z_ua`, `f_m`…) avec min/max
|
||||||
|
- CLI : bloc `controls` (`SaturatedController`, etc.)
|
||||||
|
|
||||||
|
### 7.2 Multi-circuits et couplages thermiques
|
||||||
|
|
||||||
|
Plusieurs circuits dans `circuits[]` ; `thermal_couplings` pour un pont thermique (UA, efficacité) entre circuits. Jacobien unifié.
|
||||||
|
|
||||||
|
### 7.3 Ratings saisonniers / part-load
|
||||||
|
|
||||||
|
| Métrique | CLI | Norme |
|
||||||
|
|----------|-----|-------|
|
||||||
|
| IPLV / NPLV / ESEER | `rate` | AHRI 550/590, Eurovent |
|
||||||
|
| SCOP | `scop` | EN 14825 |
|
||||||
|
| SEER | `seer` | EN 14825 |
|
||||||
|
|
||||||
|
Chaque point de charge est une **vraie** re-simulation du cycle, pas une interpolation de points imposés.
|
||||||
|
Référence : [`docs/rating-and-seasonal-metrics.md`](./docs/rating-and-seasonal-metrics.md).
|
||||||
|
|
||||||
|
### 7.4 Qualification HX
|
||||||
|
|
||||||
|
Sous-commande `qualify` : régime frigorigène fixé, balayage des conditions secondaires.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. API multi-plateformes
|
||||||
|
|
||||||
|
| Capacité | Rust | Python | C / FFI | WASM |
|
||||||
|
|----------|------|--------|---------|------|
|
||||||
|
| Création composants | `IsentropicCompressor::new()`… | wrappers PyO3 | `ek_*_create` | `wasm_bindgen` |
|
||||||
|
| Finalisation | `system.finalize()` | idem | `ek_system_finalize` | idem |
|
||||||
|
| Solve | `NewtonConfig::solve` | idem | `ek_solve` | async JS |
|
||||||
|
| Mémoire | RAII | PyO3 refcount | `*_free` manuel | GC JS |
|
||||||
|
|
||||||
|
Chemins réels des bindings : `bindings/python`, `bindings/c`, `bindings/wasm` (pas sous `crates/`).
|
||||||
|
|
||||||
|
> Audit 2026-07 : certaines classes Python/C historiques restent des stubs — vérifier les warnings ; préférer CLI / Rust pour la physique complète.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Démarrage et références
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build & test
|
||||||
|
cargo build
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# CLI
|
||||||
|
cargo run -p entropyk-cli -- run -c crates/cli/examples/chiller_aircooled_r134a.json
|
||||||
|
|
||||||
|
# UI API
|
||||||
|
cargo run -q -p entropyk-demo --bin ui-server # :3030
|
||||||
|
```
|
||||||
|
|
||||||
|
| Document | Contenu |
|
||||||
|
|----------|---------|
|
||||||
|
| [`README.md`](./README.md) | Vue d’ensemble FR, catalogue composants, CLI, UI |
|
||||||
|
| [`crates/cli/README.md`](./crates/cli/README.md) | Référence CLI JSON |
|
||||||
|
| [`EXAMPLES_FULL.md`](./EXAMPLES_FULL.md) | Scénarios avancés |
|
||||||
|
| [`docs/CLI_TUTORIAL.md`](./docs/CLI_TUTORIAL.md) | Tutoriel pas à pas |
|
||||||
|
| [`docs/components/`](./docs/components/) | Fiches composants |
|
||||||
|
| [`AGENTS.md`](./AGENTS.md) | Conventions agents / structure dépôt |
|
||||||
|
|
||||||
|
### Politique d’implémentation
|
||||||
|
|
||||||
|
- Zero-panic en production (`Result` partout)
|
||||||
|
- Jacobiens exacts (FD seulement si chemin documenté / temporaire)
|
||||||
|
- Nouveau composant : Rust + CLI + (Python/WASM) + meta UI — voir checklist dans le README racine
|
||||||
|
|||||||
623
README.md
623
README.md
@@ -1,37 +1,612 @@
|
|||||||
# Entropyk
|
# Entropyk
|
||||||
|
|
||||||
High-performance thermodynamic simulation engine for HVAC/R and industrial systems.
|
Moteur de simulation thermodynamique pour cycles frigorifiques, pompes à chaleur et systèmes CVC (HVAC/R).
|
||||||
|
|
||||||
## 📚 Documentation & Theory
|
Entropyk assemble une **machine** (compresseur, échangeurs, détendeur, boucles secondaires…) sous forme de graphe de composants, résout le système d’équations non linéaires, et expose le même modèle via **Rust**, **CLI JSON**, **Python**, **C** et **WebAssembly**.
|
||||||
|
|
||||||
Entropyk is built on rigorous physical principles.
|
> Documentation approfondie : [`DOCUMENTATION.md`](./DOCUMENTATION.md) · Exemples avancés : [`EXAMPLES_FULL.md`](./EXAMPLES_FULL.md) · Frontières Modelica : [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md)
|
||||||
- **[Technical Manual](./DOCUMENTATION.md)**: Exhaustive documentation of physical models (AHRI 540, ε-NTU), solver algorithms (Newton-Raphson, Picard), and multi-platform API parity.
|
|
||||||
- **[Comprehensive Examples](./EXAMPLES_FULL.md)**: Advanced scenarios including multi-circuit chillers, inverse control optimization, and HIL integration guide.
|
|
||||||
|
|
||||||
## Quick Start (Rust)
|
---
|
||||||
|
|
||||||
```toml
|
## Table des matières
|
||||||
[dependencies]
|
|
||||||
entropyk = "0.1"
|
1. [Ce que fait Entropyk](#1-ce-que-fait-entropyk)
|
||||||
|
2. [Architecture du dépôt](#2-architecture-du-dépôt)
|
||||||
|
3. [Principes physiques et DoF](#3-principes-physiques-et-dof)
|
||||||
|
4. [Le solveur](#4-le-solveur)
|
||||||
|
5. [Catalogue des composants](#5-catalogue-des-composants)
|
||||||
|
6. [Mode CLI](#6-mode-cli)
|
||||||
|
7. [API Rust (SystemBuilder)](#7-api-rust-systembuilder)
|
||||||
|
8. [Frontières Fixed / Free (style Modelica)](#8-frontières-fixed--free-style-modelica)
|
||||||
|
9. [EXV, orifice et débit](#9-exv-orifice-et-débit)
|
||||||
|
10. [Fluides et backends](#10-fluides-et-backends)
|
||||||
|
11. [Interface web](#11-interface-web)
|
||||||
|
12. [Bindings Python / C / WASM](#12-bindings-python--c--wasm)
|
||||||
|
13. [Installation et commandes](#13-installation-et-commandes)
|
||||||
|
14. [Exemples fournis](#14-exemples-fournis)
|
||||||
|
15. [Conventions de développement](#15-conventions-de-développement)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Ce que fait Entropyk
|
||||||
|
|
||||||
|
Entropyk simule un **cycle frigorifique / PAC / chiller** en régime permanent :
|
||||||
|
|
||||||
|
1. Vous déclarez des **composants** (compresseur, condenseur, EXV, évaporateur, sources d’air/eau…).
|
||||||
|
2. Vous les **câblez** par des arêtes (`comp:outlet → cond:inlet`).
|
||||||
|
3. Le moteur construit un vecteur d’état, assemble résidus + Jacobien, et **Newton** (ou Picard / fallback) converge.
|
||||||
|
4. Vous obtenez pressions, enthalpies, débits, puissances, COP, et diagnostics DoF.
|
||||||
|
|
||||||
|
Cas d’usage typiques :
|
||||||
|
|
||||||
|
| Cas | Comment |
|
||||||
|
|-----|---------|
|
||||||
|
| Point de design d’un chiller | Config JSON + `entropyk-cli run` |
|
||||||
|
| Pressions émergentes (SST/SDT libres) | `emergent_pressure: true` sur HX + EXV |
|
||||||
|
| Calibration inverse (cible SH / capacité) | Contrôles `SaturatedController` / facteurs `z_ua` |
|
||||||
|
| Rating IPLV / SCOP / SEER | Sous-commandes `rate`, `scop`, `seer` |
|
||||||
|
| Qualif. échangeur isolé | `qualify` |
|
||||||
|
| Schéma interactif | UI `apps/web` → API `ui-server` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Architecture du dépôt
|
||||||
|
|
||||||
|
```
|
||||||
|
Entropyk/
|
||||||
|
├── crates/
|
||||||
|
│ ├── core/ # Newtypes physiques : Pressure, Temperature, Enthalpy, MassFlow…
|
||||||
|
│ ├── fluids/ # FluidBackend + CoolProp / Tabular / Incompressible
|
||||||
|
│ ├── components/ # Tous les composants (trait Component)
|
||||||
|
│ ├── solver/ # Graphe, DoF, Newton / Picard / Fallback / Homotopy
|
||||||
|
│ ├── entropyk/ # Façade : SystemBuilder, SimulationResult, rating
|
||||||
|
│ ├── cli/ # Binaire entropyk-cli + exemples JSON
|
||||||
|
│ └── vendors/ # Parsers données constructeurs (Copeland, Danfoss, SWEP, Bitzer)
|
||||||
|
├── bindings/
|
||||||
|
│ ├── python/ # PyO3 (chemin réel — pas crates/bindings/)
|
||||||
|
│ ├── c/ # FFI C + cbindgen
|
||||||
|
│ └── wasm/ # WebAssembly
|
||||||
|
├── apps/web/ # Workbench diagramme (Next.js)
|
||||||
|
├── demo/ # ui-server Axum (:3030)
|
||||||
|
├── docs/ # Manuels, Modelica, tutoriels
|
||||||
|
└── plans/ # Plans d’audit / remediation
|
||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
Flux de données :
|
||||||
use entropyk_solver::{System, FallbackConfig};
|
|
||||||
|
|
||||||
fn main() {
|
```text
|
||||||
let mut system = System::new();
|
JSON config / SystemBuilder / UI
|
||||||
// ... define components and edges ...
|
│
|
||||||
system.finalize().unwrap();
|
▼
|
||||||
|
create_component → System (graphe)
|
||||||
let result = FallbackConfig::default().solve(&system).unwrap();
|
│
|
||||||
println!("System Converged!");
|
▼
|
||||||
|
finalize() + DoF gate → vecteur d’état [ṁ, P, h]…
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Newton / Picard / Fallback
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
SimulationResult (états, énergies, COP, diagnostics)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Principes physiques et DoF
|
||||||
|
|
||||||
|
### Vecteur d’état
|
||||||
|
|
||||||
|
Chaque **arête** du graphe porte trois inconnues :
|
||||||
|
|
||||||
|
| Slot | Symbole | Unité SI |
|
||||||
|
|------|---------|----------|
|
||||||
|
| 0 | ṁ | kg/s |
|
||||||
|
| 1 | P | Pa |
|
||||||
|
| 2 | h | J/kg |
|
||||||
|
|
||||||
|
Sur une branche série (1 entrée / 1 sortie), les arêtes partagent souvent le **même ṁ** (topologie CM1.4) : le solveur réduit alors le nombre d’inconnues de débit.
|
||||||
|
|
||||||
|
### Degrés de liberté (DoF)
|
||||||
|
|
||||||
|
Un système est **carré** si :
|
||||||
|
|
||||||
|
```text
|
||||||
|
n_équations = n_inconnues
|
||||||
|
```
|
||||||
|
|
||||||
|
- Trop d’équations → **sur-contraint** → `finalize()` refuse (DoF gate).
|
||||||
|
- Pas assez → **sous-contraint** → refuse aussi en production (CLI).
|
||||||
|
|
||||||
|
Chaque composant déclare un nombre d’équations et des **rôles** (`EquationRole`) : bilan d’énergie, chute de pression, Dirichlet de frontière, fermeture de sortie (SH/SC/qualité), actionneur…
|
||||||
|
|
||||||
|
Règle d’or (alignée Modelica) : **aucun composant ne doit fixer à la fois ṁ et P** sur le même flux.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Le solveur
|
||||||
|
|
||||||
|
Implémentation : `crates/solver`.
|
||||||
|
|
||||||
|
### Stratégies disponibles
|
||||||
|
|
||||||
|
| Stratégie JSON | Comportement |
|
||||||
|
|----------------|--------------|
|
||||||
|
| `"newton"` (**défaut**) | Newton–Raphson : `x ← x − α J⁻¹ r`. Jacobien analytique des composants. Recherche linéaire Armijo optionnelle (activée si contrôles / orifice / Free-P eau). |
|
||||||
|
| `"picard"` | Substitution successive amortie : `x ← (1−ω)x + ω G(x)`, ω ≈ 0,5. Plus robuste, plus lente. |
|
||||||
|
| `"fallback"` | Newton d’abord ; en cas de divergence → Picard ; retour à Newton si le résidu redescend sous un seuil. |
|
||||||
|
|
||||||
|
Tolérance typique : `1e-6`. Nombre d’itérations CLI : souvent `300` (augmenter pour des Jacobiens partiellement numériques, ex. certains HX).
|
||||||
|
|
||||||
|
### Boucle Newton (schéma)
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. Seed initial (frontières + staging HP/BP si emergent_pressure)
|
||||||
|
2. Calculer r(x) = résidus de tous les composants
|
||||||
|
3. Assembler J(x) = ∂r/∂x
|
||||||
|
4. Résoudre J·Δx = −r
|
||||||
|
5. Appliquer x ← clamp(x + α·Δx) (bornes P ≥ 10 kPa, actionneurs…)
|
||||||
|
6. Répéter jusqu’à ‖r‖ < tolérance
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ce qui n’est **pas** le solveur
|
||||||
|
|
||||||
|
- Pas de dynamique temporelle (régime permanent).
|
||||||
|
- Pas de CFD : les HX sont des modèles 0D/1D (LMTD, ε-NTU, corrélations).
|
||||||
|
- Les propriétés fluides viennent du **backend** (CoolProp…), pas d’hypothèses hardcodées (politique « zero fallback » côté composants sérieux).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Catalogue des composants
|
||||||
|
|
||||||
|
Tous implémentent le trait `Component` (`n_equations`, `compute_residuals`, `jacobian_entries`, ports…).
|
||||||
|
Types CLI = chaînes `"type"` dans le JSON (voir `crates/cli/src/run.rs`).
|
||||||
|
|
||||||
|
### 5.1 Compresseurs
|
||||||
|
|
||||||
|
| Type CLI | Rôle | Paramètres clés |
|
||||||
|
|----------|------|-----------------|
|
||||||
|
| `IsentropicCompressor` | Compresseur η_is + déplacement volumétrique ; mode **emergent** courant | `displacement_m3`, `speed_hz`, `volumetric_efficiency`, `isentropic_efficiency`, `emergent_pressure` |
|
||||||
|
| `Compressor` | Cartographie AHRI 540 / SST–SDT (ṁ, puissance) | coeffs `m1`…`m10` ou carte polynomiale |
|
||||||
|
| `ScrewEconomizerCompressor` / `ScrewCompressor` | Vis + port écono, VFD, slide valve optionnel | courbes SST/SDT, `speed_hz` |
|
||||||
|
| `CentrifugalCompressor` | Carte polytropique (facteur de débit, Mach) | `diameter_m`, `speed_rpm`, γ, R |
|
||||||
|
|
||||||
|
En mode **emergent**, le compresseur impose typiquement la **loi de ṁ** (déplacement × ρ × η_vol) et l’énergie de refoulement ; les pressions HP/BP émergent des HX.
|
||||||
|
|
||||||
|
Si un EXV à **orifice Fixed** métre le débit, le CLI bascule le compresseur en **ṁ externe** (énergie seule) pour rester carré.
|
||||||
|
|
||||||
|
### 5.2 Détente / vannes
|
||||||
|
|
||||||
|
| Type CLI | Rôle | Notes critiques |
|
||||||
|
|----------|------|-----------------|
|
||||||
|
| `IsenthalpicExpansionValve` / `EXV` | Laminants isenthalpiques (`h_out = h_in`) | **Sans `orifice_kv`**, `opening` n’a **aucun effet** — voir [§9](#9-exv-orifice-et-débit) |
|
||||||
|
| `ExpansionValve` | Modèles débit orifice / Cd·A / TXV Eames | `flow_model`, `opening`, `beta_m2`… |
|
||||||
|
| `CapillaryTube` | Capillaire adiabatique segmenté | `diameter_m`, `length_m`, `n_segments` |
|
||||||
|
| `ReversingValve` / `FourWayValve` | 4 voies PAC (froid/chaud) | `mode`, `pressure_drop_pa` |
|
||||||
|
| `BypassValve` | Bypass hydronique proportionnel | `opening`, `cv` |
|
||||||
|
|
||||||
|
### 5.3 Échangeurs frigorifiques
|
||||||
|
|
||||||
|
| Type CLI | Rôle | Notes |
|
||||||
|
|----------|------|-------|
|
||||||
|
| `Condenser` | Condensation + côté secondaire (eau/air) | `ua`, `emergent_pressure`, `subcooling_k`, `secondary_fluid`, ΔP secondaire optionnelle |
|
||||||
|
| `Evaporator` | Évaporation DX + secondaire | `ua`, `superheat_k` / emergent, `secondary_fluid` |
|
||||||
|
| `FloodedEvaporator` | Flooded / recirculation | fermeture vapeur saturée ou `quality_control` |
|
||||||
|
| `FloodedCondenser` | Condenseur flooded | sortie sous-refroidie |
|
||||||
|
| `HeatExchanger` | HX générique 4 ports (LMTD / ε-NTU) | `hot_fluid_id`, `cold_fluid_id`, `ua` |
|
||||||
|
| `BphxEvaporator` / `BphxCondenser` | Plaques brasées + corrélations HTC | géométrie plaques, corrélations Longo/Shah… |
|
||||||
|
| `AirCooledCondenser` | T_cond ≈ OAT + approach | `oat_k`, `approach_k` |
|
||||||
|
| `FinCoilCondenser` | Bobine ailettée air | géométrie tubes/ailettes |
|
||||||
|
| `MchxCondenserCoil` | Microcanaux | géométrie MCHX |
|
||||||
|
| `CondenserCoil` / `EvaporatorCoil` | Bobines dédiées | variantes rating |
|
||||||
|
| `Economizer` | IHX ON/OFF/BYPASS | machine à états |
|
||||||
|
| `GasCooler` | Refroidisseur de gaz CO₂ | HTC Pettersen |
|
||||||
|
| `ShellAndTubeHx` | Rating Bell-Delaware | |
|
||||||
|
| `FanCoilUnit` | FCU eau–air | ε-NTU + BPF |
|
||||||
|
| `FreeCoolingExchanger` | Free-cooling côté eau | |
|
||||||
|
|
||||||
|
**Pressions émergentes** (`emergent_pressure: true`) : le HX ne pince plus P_sat sur une T de design ; la pression flotte et est fermée par SC/SH/qualité + bilans d’énergie.
|
||||||
|
|
||||||
|
**Secondaire 4 ports** : brancher `BrineSource`/`AirSource` → `secondary_inlet` → `secondary_outlet` → `BrineSink`/`AirSink`. Le HX propage la pression (fermeture isobare ou ΔP quadratique de rating).
|
||||||
|
|
||||||
|
### 5.4 Tuyauterie, pompes, air
|
||||||
|
|
||||||
|
| Type CLI | Rôle | Notes |
|
||||||
|
|----------|------|-------|
|
||||||
|
| `Pipe` / `RefrigerantPipe` / `WaterPipe` / `AirDuct` | Conduits Darcy–Weisbach | `length_m`, `diameter_m` ; `pressure_drop_pa = 0` → **ΔP Darcy** depuis L/D + ṁ ; `> 0` → ΔP imposé |
|
||||||
|
| `Pump` | Courbes H/η + affinity laws | |
|
||||||
|
| `Fan` | Courbes pression/η + affinity | souvent sur boucle air |
|
||||||
|
| `FlowSplitter` / `FlowMerger` | Jonctions | |
|
||||||
|
| `Drum` | Séparateur L/V (flooded) | |
|
||||||
|
|
||||||
|
### 5.5 Frontières (sources / sinks)
|
||||||
|
|
||||||
|
| Type CLI | Fluide | Impose typiquement |
|
||||||
|
|----------|--------|--------------------|
|
||||||
|
| `RefrigerantSource` / `RefrigerantSink` | Frigorigène | P (+ qualité ou h), ṁ optionnel |
|
||||||
|
| `BrineSource` / `BrineSink` | Eau / glycol | T, ṁ, P (Fixed/Free) |
|
||||||
|
| `AirSource` / `AirSink` | Air humide | T_dry, RH, ṁ, P |
|
||||||
|
|
||||||
|
Voir [§8](#8-frontières-fixed--free-style-modelica).
|
||||||
|
|
||||||
|
### 5.6 Divers
|
||||||
|
|
||||||
|
| Type CLI | Rôle |
|
||||||
|
|----------|------|
|
||||||
|
| `ThermalLoad` | Charge thermique Q (couplage) |
|
||||||
|
| `HeatSource` | Injection Q inline |
|
||||||
|
| `Anchor` / `RefrigerantNode` | Nœud / ancre SH optionnelle |
|
||||||
|
| `Placeholder` | Composant stub (tests / topology) |
|
||||||
|
|
||||||
|
### 5.7 Intégration obligatoire d’un nouveau composant
|
||||||
|
|
||||||
|
Lorsqu’on ajoute un composant, il doit être câblé **partout** :
|
||||||
|
|
||||||
|
1. Trait `Component` + Jacobien exact dans `crates/components`
|
||||||
|
2. Export façade `crates/entropyk`
|
||||||
|
3. Bras `create_component` dans `crates/cli/src/run.rs`
|
||||||
|
4. Wrapper Python (PyO3) et WASM si exposé
|
||||||
|
5. Meta UI (`apps/web/src/lib/componentMeta.ts`) si visible dans le workbench
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Mode CLI
|
||||||
|
|
||||||
|
Binaire : `entropyk-cli` (`crates/cli`).
|
||||||
|
|
||||||
|
### Sous-commandes
|
||||||
|
|
||||||
|
| Commande | Rôle |
|
||||||
|
|----------|------|
|
||||||
|
| `run` | Une simulation depuis un JSON |
|
||||||
|
| `batch` | Dossier de configs, parallèle |
|
||||||
|
| `validate` | Vérifie le JSON / topologie sans résoudre (ou validation légère) |
|
||||||
|
| `qualify` | Qualification HX (régime frigorigène fixe, balayage secondaire) |
|
||||||
|
| `rate` | IPLV (AHRI 550/590) / ESEER |
|
||||||
|
| `scop` | SCOP EN 14825 (bins chauffage) |
|
||||||
|
| `seer` | SEER EN 14825 (bins froid) |
|
||||||
|
| `schema` | Émet le JSON Schema du Model IR |
|
||||||
|
|
||||||
|
Flags globaux : `-v` / `--verbose`, `-q` / `--quiet`.
|
||||||
|
|
||||||
|
### Exemples d’invocation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
cargo build --release -p entropyk-cli
|
||||||
|
|
||||||
|
# Chiller air R134a
|
||||||
|
cargo run -p entropyk-cli -- run \
|
||||||
|
--config crates/cli/examples/chiller_aircooled_r134a.json \
|
||||||
|
--output result.json
|
||||||
|
|
||||||
|
# Validation
|
||||||
|
cargo run -p entropyk-cli -- validate --config mon_cycle.json
|
||||||
|
|
||||||
|
# Batch
|
||||||
|
cargo run -p entropyk-cli -- batch -d ./scenarios/ -p 4 -O results.json
|
||||||
|
|
||||||
|
# Rating IPLV
|
||||||
|
cargo run -p entropyk-cli -- rate -c crates/cli/examples/rate_chiller_iplv_ahri.json
|
||||||
|
|
||||||
|
# Schema
|
||||||
|
cargo run -p entropyk-cli -- schema -o model-ir.schema.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schéma JSON minimal
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Mon chiller",
|
||||||
|
"fluid": "R134a",
|
||||||
|
"fluid_backend": "CoolProp",
|
||||||
|
"circuits": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "Circuit principal",
|
||||||
|
"components": [
|
||||||
|
{ "type": "IsentropicCompressor", "name": "comp", "...": "..." },
|
||||||
|
{ "type": "Condenser", "name": "cond", "...": "..." },
|
||||||
|
{ "type": "IsenthalpicExpansionValve", "name": "exv", "...": "..." },
|
||||||
|
{ "type": "Evaporator", "name": "evap", "...": "..." }
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
{ "from": "comp:outlet", "to": "cond:inlet" },
|
||||||
|
{ "from": "cond:outlet", "to": "exv:inlet" },
|
||||||
|
{ "from": "exv:outlet", "to": "evap:inlet" },
|
||||||
|
{ "from": "evap:outlet", "to": "comp:inlet" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controls": [],
|
||||||
|
"solver": {
|
||||||
|
"strategy": "newton",
|
||||||
|
"max_iterations": 300,
|
||||||
|
"tolerance": 1e-6
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
### Pipeline interne de `run`
|
||||||
|
|
||||||
- **Physics-First**: Strong typing for Pressure, Temperature, and Enthalpy.
|
1. Parse `ScenarioConfig`
|
||||||
- **Fluid Backends**: CoolProp (RefProp compatible) and high-speed Tabular interpolators.
|
2. Pour chaque composant : `create_component(...)` (CoolProp, params, modes orifice / emergent…)
|
||||||
- **Advanced Solvers**: Newton-Raphson with Armijo line search and Picard robust fallback.
|
3. Ajout des arêtes nommées `nom:port`
|
||||||
- **Inverse Control**: Built-in support for parameter estimation and design-to-target.
|
4. `finalize()` + contrôle DoF
|
||||||
- **Multi-Platform**: First-class support for Python, C/FFI, and WebAssembly.
|
5. Seed (frontières + staging HP/BP)
|
||||||
|
6. Solve selon `solver.strategy`
|
||||||
|
7. Sérialisation JSON : états d’arêtes, performances, `dof`, `failure_diagnostics` si échec
|
||||||
|
|
||||||
|
### Contrôles (régulation / calibration)
|
||||||
|
|
||||||
|
Bloc optionnel `controls` : boucles type `SaturatedController` qui lient une **mesure** (capacité, SH…) à un **actionneur** (`opening`, `z_ua`, `f_m`…).
|
||||||
|
Le solveur augmente alors le vecteur d’état d’inconnues d’actionneurs + résidus de tracking.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. API Rust (SystemBuilder)
|
||||||
|
|
||||||
|
Façade : crate `entropyk`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use entropyk::SystemBuilder;
|
||||||
|
// + types composants depuis entropyk / entropyk_components
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let system = SystemBuilder::new()
|
||||||
|
.with_fluid("R134a")?
|
||||||
|
// .component("comp", Box::new(...))?
|
||||||
|
// .edge_with_ports("comp", "outlet", "cond", "inlet")?
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
// Ou bas niveau :
|
||||||
|
// let mut newton = entropyk_solver::NewtonConfig::default();
|
||||||
|
// let result = newton.solve(&mut system)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Points d’entrée utiles :
|
||||||
|
|
||||||
|
- `SystemBuilder` — construction ergonomique + JSON round-trip (`to_config_json` / `from_config_json`)
|
||||||
|
- `System` — graphe, `finalize`, `dof_report`, `validate_system_dof`
|
||||||
|
- `NewtonConfig` / `PicardConfig` / `FallbackConfig` — stratégies
|
||||||
|
- `SimulationResult` — sortie structurée
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Frontières Fixed / Free (style Modelica)
|
||||||
|
|
||||||
|
Alignement documenté dans [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md).
|
||||||
|
|
||||||
|
| Pattern Modelica | Source | Sink | Conséquence |
|
||||||
|
|------------------|--------|------|-------------|
|
||||||
|
| **MassFlowSource_T** (défaut Entropyk si ṁ imposé) | Fixed T, Fixed ṁ, **Free P** | Fixed P, Free T_out | Le HX/propager ΔP ferme le DoF pression |
|
||||||
|
| **Boundary_pT** | Fixed P, Fixed T, Free ṁ | Fixed P | Il faut une résistance hydraulique (pipe / ΔP HX) entre les deux P |
|
||||||
|
| Rating T_out | Free ṁ | Fixed P + Fixed T_out | ṁ devient inconnu (calibration) |
|
||||||
|
|
||||||
|
Flags JSON : `fix_pressure`, `fix_temperature`, `fix_mass_flow` (booléens).
|
||||||
|
|
||||||
|
**Interdit** : Fixed ṁ **et** Fixed P sur la même source sans degré de liberté ailleurs.
|
||||||
|
|
||||||
|
ΔP secondaire de rating (eau/air) :
|
||||||
|
|
||||||
|
```json
|
||||||
|
"secondary_rated_pressure_drop_pa": 40000,
|
||||||
|
"secondary_rated_m_flow_kg_s": 0.5
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. EXV, orifice et débit
|
||||||
|
|
||||||
|
Trois modes pour `IsenthalpicExpansionValve` :
|
||||||
|
|
||||||
|
### Mode A — Isenthalpique seul (exemples chillers classiques)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "type": "IsenthalpicExpansionValve", "name": "exv", "emergent_pressure": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Équation : `h_out − h_in = 0`
|
||||||
|
- **ṁ imposé par le compresseur** (déplacement)
|
||||||
|
- `opening` **ignoré** (même s’il apparaît dans l’UI avec une valeur par défaut)
|
||||||
|
|
||||||
|
### Mode B — Orifice Fixed (opening = paramètre)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "IsenthalpicExpansionValve",
|
||||||
|
"name": "exv",
|
||||||
|
"emergent_pressure": true,
|
||||||
|
"orifice_kv": 2.0e-6,
|
||||||
|
"opening": 0.6,
|
||||||
|
"fix_opening": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Loi :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ṁ = Kv · opening · √(2 · ρ_in · max(ΔP, 0))
|
||||||
|
```
|
||||||
|
|
||||||
|
Le CLI met le compresseur en **ṁ métré** (lâche la loi de déplacement) pour rester carré.
|
||||||
|
|
||||||
|
### Mode C — Orifice Free (opening = inconnue)
|
||||||
|
|
||||||
|
```json
|
||||||
|
"orifice_kv": 2.0e-6,
|
||||||
|
"fix_opening": false
|
||||||
|
```
|
||||||
|
|
||||||
|
`opening` est une inconnue ; il faut une boucle de régulation (ex. SH → SaturatedController).
|
||||||
|
|
||||||
|
> **Piège UI** : le catalogue montre « Opening » même sans Kv. Sans `orifice_kv` explicite, changer l’ouverture ne change **rien**.
|
||||||
|
|
||||||
|
Exemple dédié : `crates/cli/examples/chiller_r134a_exv_orifice.json`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Fluides et backends
|
||||||
|
|
||||||
|
| Backend | Usage |
|
||||||
|
|---------|--------|
|
||||||
|
| **CoolProp** (`fluid_backend: "CoolProp"`) | Frigorigènes (R134a, R410A…), eau — défaut sérieux |
|
||||||
|
| **Tabular** | Tables interpolées (WASM / hors CoolProp) |
|
||||||
|
| **Incompressible** | Glycols / liquides (ρ, μ de design) |
|
||||||
|
| **Cached / Damped** | Wrappers perf / stabilité |
|
||||||
|
|
||||||
|
Types physiques dans `entropyk-core` : toujours SI (Pa, K, J/kg, kg/s). Les JSON d’entrée acceptent souvent °C / bar pour l’ergonomie ; la conversion est faite à la construction.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Interface web
|
||||||
|
|
||||||
|
| Élément | Chemin |
|
||||||
|
|---------|--------|
|
||||||
|
| Front Next.js | `apps/web` |
|
||||||
|
| API Axum | `cargo run -p entropyk-demo --bin ui-server` → `http://localhost:3030` |
|
||||||
|
|
||||||
|
Fonctionnalités :
|
||||||
|
|
||||||
|
- Palette de composants + glyph ISO
|
||||||
|
- Câblage React Flow
|
||||||
|
- Ledger DoF temps réel (`dofLedger.ts`)
|
||||||
|
- Coach Fixed/Free Modelica (`boundaryFix.ts`, `dofCoach.ts`)
|
||||||
|
- Solve via `POST /api/simulate`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1
|
||||||
|
cargo run -q -p entropyk-demo --bin ui-server
|
||||||
|
|
||||||
|
# Terminal 2
|
||||||
|
cd apps/web && npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Bindings Python / C / WASM
|
||||||
|
|
||||||
|
Chemins réels : `bindings/python`, `bindings/c`, `bindings/wasm` (pas sous `crates/`).
|
||||||
|
|
||||||
|
### Python (`uv` obligatoire)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv pip install -e ./bindings/python
|
||||||
|
uv pip install maturin
|
||||||
|
cd bindings/python && uv run maturin develop --release
|
||||||
|
uv run pytest tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
### C
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release -p entropyk-c
|
||||||
|
# header généré sous target/ (voir bindings/c/README.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
### WASM
|
||||||
|
|
||||||
|
Voir `bindings/wasm/README.md` — adapté aux backends tabulaires côté client.
|
||||||
|
|
||||||
|
> Certaines classes Python historiques sont encore des **stubs / mocks** (audit 2026-07) : vérifier les warnings à la construction et préférer le chemin CLI / Rust pour la physique complète.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Installation et commandes
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
|
||||||
|
- Rust (édition workspace 2021+)
|
||||||
|
- CoolProp précompilé sous `vendor/coolprop` (lien via `coolprop-sys`)
|
||||||
|
- Pour l’UI : Node.js + npm
|
||||||
|
- Pour Python : [`uv`](https://github.com/astral-sh/uv)
|
||||||
|
|
||||||
|
### Commandes courantes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build / tests
|
||||||
|
cargo build
|
||||||
|
cargo test
|
||||||
|
cargo test -p entropyk-components
|
||||||
|
cargo test -p entropyk-cli --test hx_standalone
|
||||||
|
|
||||||
|
# CLI
|
||||||
|
cargo run -p entropyk-cli -- run -c crates/cli/examples/chiller_aircooled_r134a.json
|
||||||
|
|
||||||
|
# Clippy / format
|
||||||
|
cargo fmt
|
||||||
|
cargo clippy
|
||||||
|
|
||||||
|
# UI API (port 3030)
|
||||||
|
cargo run -q -p entropyk-demo --bin ui-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Sous Windows, si `ui-server.exe` est verrouillé pendant `cargo test --workspace`, exclure le package démo :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test --workspace --exclude entropyk-demo --no-fail-fast
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Exemples fournis
|
||||||
|
|
||||||
|
Répertoire : `crates/cli/examples/`.
|
||||||
|
|
||||||
|
| Fichier | Intérêt |
|
||||||
|
|---------|---------|
|
||||||
|
| `chiller_aircooled_r134a.json` | Chiller air 4 ports, emergent, air + eau glacée |
|
||||||
|
| `chiller_watercooled_r410a.json` | Chiller eau R410A |
|
||||||
|
| `chiller_flooded_4port_watercooled.json` | FloodedEvaporator + DoF carré |
|
||||||
|
| `chiller_r134a_emergent_pressure.json` | Pressions émergentes |
|
||||||
|
| `chiller_r134a_exv_orifice.json` | EXV avec orifice (opening physique) |
|
||||||
|
| `chiller_r134a_superheat_control.json` | Boucle SH |
|
||||||
|
| `chiller_r134a_slide_valve.json` | Slide valve vis |
|
||||||
|
| `chiller_r134a_dual_circuit_staging.json` | Dual circuit |
|
||||||
|
| `heatpump_airsource_r410a.json` | PAC air |
|
||||||
|
| `heatpump_r410a_reversing_valve.json` | Vanne 4 voies |
|
||||||
|
| `hx_air_water_4port.json` | HX isolé air–eau |
|
||||||
|
| `bphx_evaporator_condenser.json` | Plaques brasées |
|
||||||
|
| `capillary_tube_r134a.json` | Capillaire |
|
||||||
|
| `rate_chiller_iplv_ahri.json` | Rating IPLV |
|
||||||
|
| `scop_heatpump_r134a.json` | SCOP |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 15. Conventions de développement
|
||||||
|
|
||||||
|
- **Langage code** : Rust, `Result` partout (politique zero-panic en production).
|
||||||
|
- **Jacobiens** : analytiques exacts ; pas de différences finies sauf chemin explicitement documenté / temporaire.
|
||||||
|
- **Types** : newtypes SI (`Pressure`, `Enthalpy`…) — pas de `f64` nus aux frontières publiques.
|
||||||
|
- **Docs techniques / commits** : anglais ; communication projet possible en français.
|
||||||
|
- **Git** : branche `main`, messages impératifs anglais.
|
||||||
|
- **BMAD** : workflows sous `_bmad/` — suivre les fichiers YAML/XML à la lettre si activés.
|
||||||
|
|
||||||
|
### Ajouter un composant (checklist)
|
||||||
|
|
||||||
|
1. Struct + `Component` dans `crates/components`
|
||||||
|
2. Tests unitaires (résidus, Jacobien FD-check)
|
||||||
|
3. Export `lib.rs` + façade `entropyk`
|
||||||
|
4. Bras CLI `create_component`
|
||||||
|
5. Exemple JSON sous `crates/cli/examples/`
|
||||||
|
6. Meta UI + bindings si besoin
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Liens utiles
|
||||||
|
|
||||||
|
| Document | Contenu |
|
||||||
|
|----------|---------|
|
||||||
|
| [`DOCUMENTATION.md`](./DOCUMENTATION.md) | Modèles physiques, solveur, API |
|
||||||
|
| [`EXAMPLES_FULL.md`](./EXAMPLES_FULL.md) | Scénarios avancés |
|
||||||
|
| [`docs/CLI_TUTORIAL.md`](./docs/CLI_TUTORIAL.md) | Tutoriel CLI |
|
||||||
|
| [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md) | Preuve Fixed/Free |
|
||||||
|
| [`docs/components/`](./docs/components/) | Fiches composants |
|
||||||
|
| [`AGENTS.md`](./AGENTS.md) | Instructions agents / structure |
|
||||||
|
| [`crates/cli/README.md`](./crates/cli/README.md) | Détails CLI |
|
||||||
|
| [`apps/web/README.md`](./apps/web/README.md) | UI |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Projet** : Entropyk · **Langage** : Rust · **Licence / version** : voir `Cargo.toml` (v0.1.x)
|
||||||
|
|||||||
@@ -1,169 +1,317 @@
|
|||||||
# Entropyk CLI
|
# Entropyk CLI
|
||||||
|
|
||||||
Command-line interface for batch thermodynamic simulations.
|
Interface en ligne de commande pour lancer, valider et noter des simulations thermodynamiques à partir de fichiers JSON.
|
||||||
|
|
||||||
|
Binaire : `entropyk-cli` · Crate : `crates/cli` · Exemples : `crates/cli/examples/`
|
||||||
|
|
||||||
|
Le README racine ([`../../README.md`](../../README.md)) décrit l’architecture globale, les composants et le solveur. Ce document se concentre sur **l’usage CLI**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo build --release -p entropyk-cli
|
cargo build --release -p entropyk-cli
|
||||||
|
|
||||||
|
# Binaire
|
||||||
|
./target/release/entropyk-cli --help # Linux / macOS
|
||||||
|
.\target\release\entropyk-cli.exe --help # Windows
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
Ou sans installer :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Single simulation
|
cargo run -p entropyk-cli -- <sous-commande> ...
|
||||||
./target/release/entropyk-cli run config.json -o result.json
|
|
||||||
|
|
||||||
# Batch processing
|
|
||||||
./target/release/entropyk-cli batch ./scenarios/ --parallel 4
|
|
||||||
|
|
||||||
# Validate configuration
|
|
||||||
./target/release/entropyk-cli validate config.json
|
|
||||||
|
|
||||||
# Help
|
|
||||||
./target/release/entropyk-cli --help
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration Format
|
Flags globaux : `-v` / `--verbose`, `-q` / `--quiet`.
|
||||||
|
|
||||||
### Complete Chiller Example (R410A + Water)
|
---
|
||||||
|
|
||||||
|
## Sous-commandes
|
||||||
|
|
||||||
|
| Commande | Rôle |
|
||||||
|
|----------|------|
|
||||||
|
| `run` | Une simulation depuis un JSON |
|
||||||
|
| `batch` | Un dossier de configs, en parallèle |
|
||||||
|
| `validate` | Vérifie la config (parse / topologie) |
|
||||||
|
| `qualify` | Qualification HX (régime frigorigène fixe) |
|
||||||
|
| `rate` | IPLV (AHRI 550/590) / ESEER |
|
||||||
|
| `scop` | SCOP EN 14825 (bins chauffage) |
|
||||||
|
| `seer` | SEER EN 14825 (bins froid) |
|
||||||
|
| `schema` | Émet le JSON Schema du Model IR |
|
||||||
|
|
||||||
|
### Exemples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Simulation unique
|
||||||
|
cargo run -p entropyk-cli -- run \
|
||||||
|
--config crates/cli/examples/chiller_aircooled_r134a.json \
|
||||||
|
--output result.json
|
||||||
|
|
||||||
|
# Validation
|
||||||
|
cargo run -p entropyk-cli -- validate --config mon_cycle.json
|
||||||
|
|
||||||
|
# Batch (4 workers)
|
||||||
|
cargo run -p entropyk-cli -- batch -d ./scenarios/ -p 4 -O results.json
|
||||||
|
|
||||||
|
# Rating IPLV
|
||||||
|
cargo run -p entropyk-cli -- rate -c crates/cli/examples/rate_chiller_iplv_ahri.json
|
||||||
|
|
||||||
|
# SCOP
|
||||||
|
cargo run -p entropyk-cli -- scop -c crates/cli/examples/scop_heatpump_r134a.json
|
||||||
|
|
||||||
|
# Schema
|
||||||
|
cargo run -p entropyk-cli -- schema -o model-ir.schema.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pipeline de `run`
|
||||||
|
|
||||||
|
1. Parse `ScenarioConfig` (fluide, circuits, edges, controls, solver)
|
||||||
|
2. Pour chaque composant : `create_component` (`crates/cli/src/run.rs`)
|
||||||
|
3. Câblage des arêtes `nom:port` → `nom:port`
|
||||||
|
4. `finalize()` + **porte DoF** (système carré obligatoire)
|
||||||
|
5. Seed initial (frontières + staging HP/BP si `emergent_pressure`)
|
||||||
|
6. Solve : `newton` | `picard` | `fallback`
|
||||||
|
7. Sortie JSON : états, performances, `dof`, erreurs / `failure_diagnostics`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Format de configuration
|
||||||
|
|
||||||
|
### Structure racine
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Chiller eau glacée R410A",
|
"name": "Mon chiller",
|
||||||
"fluid": "R410A",
|
"description": "optionnel",
|
||||||
|
"fluid": "R134a",
|
||||||
"circuits": [
|
"fluid_backend": "CoolProp",
|
||||||
{
|
"circuits": [ { "id": 0, "components": [], "edges": [] } ],
|
||||||
"id": 0,
|
"controls": [],
|
||||||
"components": [
|
"thermal_couplings": [],
|
||||||
{
|
|
||||||
"type": "Compressor",
|
|
||||||
"name": "comp",
|
|
||||||
"fluid": "R410A",
|
|
||||||
"speed_rpm": 2900,
|
|
||||||
"displacement_m3": 0.000030,
|
|
||||||
"efficiency": 0.85,
|
|
||||||
"m1": 0.85, "m2": 2.5,
|
|
||||||
"m3": 500, "m4": 1500, "m5": -2.5, "m6": 1.8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "HeatExchanger",
|
|
||||||
"name": "condenser",
|
|
||||||
"ua": 5000,
|
|
||||||
"hot_fluid": "R410A",
|
|
||||||
"hot_t_inlet_c": 45,
|
|
||||||
"hot_pressure_bar": 24,
|
|
||||||
"hot_mass_flow_kg_s": 0.05,
|
|
||||||
"cold_fluid": "Water",
|
|
||||||
"cold_t_inlet_c": 30,
|
|
||||||
"cold_pressure_bar": 1,
|
|
||||||
"cold_mass_flow_kg_s": 0.4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ExpansionValve",
|
|
||||||
"name": "exv",
|
|
||||||
"fluid": "R410A",
|
|
||||||
"opening": 1.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Evaporator",
|
|
||||||
"name": "evaporator",
|
|
||||||
"ua": 6000,
|
|
||||||
"t_sat_k": 275.15,
|
|
||||||
"superheat_k": 5
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edges": [
|
|
||||||
{ "from": "comp:outlet", "to": "condenser:inlet" },
|
|
||||||
{ "from": "condenser:outlet", "to": "exv:inlet" },
|
|
||||||
{ "from": "exv:outlet", "to": "evaporator:inlet" },
|
|
||||||
{ "from": "evaporator:outlet", "to": "comp:inlet" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"components": [
|
|
||||||
{ "type": "Pump", "name": "pump" },
|
|
||||||
{ "type": "Placeholder", "name": "load", "n_equations": 0 }
|
|
||||||
],
|
|
||||||
"edges": [
|
|
||||||
{ "from": "pump:outlet", "to": "load:inlet" },
|
|
||||||
{ "from": "load:outlet", "to": "pump:inlet" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
"thermal_couplings": [
|
|
||||||
{
|
|
||||||
"hot_circuit": 0,
|
|
||||||
"cold_circuit": 1,
|
|
||||||
"ua": 6000,
|
|
||||||
"efficiency": 0.95
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
"solver": {
|
"solver": {
|
||||||
"strategy": "fallback",
|
"strategy": "newton",
|
||||||
"max_iterations": 100,
|
"max_iterations": 300,
|
||||||
"tolerance": 1e-6
|
"tolerance": 1e-6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Component Types
|
| Champ | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `fluid` | Frigorigène principal du circuit (ex. `R134a`, `R410A`) |
|
||||||
|
| `fluid_backend` | `CoolProp` (défaut sérieux), Tabular, etc. |
|
||||||
|
| `circuits[]` | Un ou plusieurs circuits (id 0…n) |
|
||||||
|
| `components[]` | Objets avec `type`, `name`, + paramètres |
|
||||||
|
| `edges[]` | `{ "from": "comp:outlet", "to": "cond:inlet" }` |
|
||||||
|
| `controls[]` | Boucles inverse / SaturatedController (optionnel) |
|
||||||
|
| `solver.strategy` | `newton` (**défaut**), `picard`, `fallback` |
|
||||||
|
|
||||||
| Type | Required Parameters | Optional Parameters |
|
### Exemple moderne (chiller air, 4 ports)
|
||||||
|------|---------------------|---------------------|
|
|
||||||
| `Compressor` | `fluid`, `speed_rpm`, `displacement_m3` | `efficiency`, `m1-m10` (AHRI 540) |
|
|
||||||
| `HeatExchanger` | `ua`, `hot_fluid`, `cold_fluid`, `hot_t_inlet_c`, `cold_t_inlet_c` | `hot_pressure_bar`, `cold_pressure_bar`, `hot_mass_flow_kg_s`, `cold_mass_flow_kg_s` |
|
|
||||||
| `Condenser` | `ua` | `t_sat_k` |
|
|
||||||
| `CondenserCoil` | `ua` | `t_sat_k` |
|
|
||||||
| `Evaporator` | `ua` | `t_sat_k`, `superheat_k` |
|
|
||||||
| `EvaporatorCoil` | `ua` | `t_sat_k`, `superheat_k` |
|
|
||||||
| `ExpansionValve` | `fluid` | `opening` |
|
|
||||||
| `Pump` | - | `name` |
|
|
||||||
| `Placeholder` | `name` | `n_equations` |
|
|
||||||
|
|
||||||
## Thermal Couplings
|
Voir `examples/chiller_aircooled_r134a.json` — pattern recommandé :
|
||||||
|
|
||||||
Thermal couplings define heat transfer between circuits:
|
- `IsentropicCompressor` + `emergent_pressure`
|
||||||
|
- `Condenser` / `Evaporator` avec secondaires `AirSource`/`BrineSource` → HX → sinks
|
||||||
|
- `IsenthalpicExpansionValve` isenthalpique (sans orifice sauf besoin)
|
||||||
|
- Sources : Fixed T + Fixed ṁ + **Free P** ; sinks : Fixed P
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run -p entropyk-cli -- run \
|
||||||
|
-c crates/cli/examples/chiller_aircooled_r134a.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Types de composants CLI
|
||||||
|
|
||||||
|
Chaînes `type` reconnues par `create_component` (liste non exhaustive — voir le match dans `src/run.rs`).
|
||||||
|
|
||||||
|
### Compresseurs
|
||||||
|
|
||||||
|
| Type | Paramètres utiles |
|
||||||
|
|------|-------------------|
|
||||||
|
| `IsentropicCompressor` | `displacement_m3`, `speed_hz`, `volumetric_efficiency`, `isentropic_efficiency`, `emergent_pressure` |
|
||||||
|
| `Compressor` | Cartes AHRI 540 (`m1`…`m10`) ou SST/SDT |
|
||||||
|
| `ScrewEconomizerCompressor` / `ScrewCompressor` | Courbes SST/SDT, VFD, slide valve |
|
||||||
|
| `CentrifugalCompressor` | `diameter_m`, `speed_rpm`, γ, R |
|
||||||
|
|
||||||
|
### Détente
|
||||||
|
|
||||||
|
| Type | Paramètres utiles | Attention |
|
||||||
|
|------|-------------------|-----------|
|
||||||
|
| `IsenthalpicExpansionValve` / `EXV` | `emergent_pressure`, `t_evap_k` | Sans `orifice_kv`, **`opening` est ignoré** |
|
||||||
|
| `ExpansionValve` | `opening`, `flow_model`, `beta_m2`… | |
|
||||||
|
| `CapillaryTube` | `diameter_m`, `length_m`, `n_segments` | |
|
||||||
|
| `ReversingValve` / `FourWayValve` | `mode`, `pressure_drop_pa` | |
|
||||||
|
| `BypassValve` | `opening`, `cv` | |
|
||||||
|
|
||||||
|
**EXV orifice** (débit physique) :
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"hot_circuit": 0,
|
"type": "IsenthalpicExpansionValve",
|
||||||
"cold_circuit": 1,
|
"name": "exv",
|
||||||
"ua": 5000,
|
"emergent_pressure": true,
|
||||||
"efficiency": 0.95
|
"orifice_kv": 2.0e-6,
|
||||||
|
"opening": 0.6,
|
||||||
|
"fix_opening": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `hot_circuit`: Circuit ID providing heat
|
Loi : `ṁ = Kv · opening · √(2 · ρ · max(ΔP, 0))`.
|
||||||
- `cold_circuit`: Circuit ID receiving heat
|
Avec orifice Fixed, le CLI met le compresseur en ṁ métré. Voir `examples/chiller_r134a_exv_orifice.json`.
|
||||||
- `ua`: Thermal conductance (W/K)
|
|
||||||
- `efficiency`: Heat exchanger efficiency (0.0-1.0)
|
|
||||||
|
|
||||||
## Solver Strategies
|
### Échangeurs
|
||||||
|
|
||||||
| Strategy | Description |
|
| Type | Paramètres utiles |
|
||||||
|----------|-------------|
|
|------|-------------------|
|
||||||
| `newton` | Newton-Raphson solver |
|
| `Condenser` / `Evaporator` | `ua`, `emergent_pressure`, `subcooling_k` / SH, `secondary_fluid`, ΔP secondaire |
|
||||||
| `picard` | Sequential substitution (Picard iteration) |
|
| `FloodedEvaporator` | `ua`, `quality_control` |
|
||||||
| `fallback` | Picard → Newton fallback (recommended) |
|
| `HeatExchanger` | `ua`, `hot_fluid_id`, `cold_fluid_id` (4 ports) |
|
||||||
|
| `BphxEvaporator` / `BphxCondenser` | Géométrie plaques + corrélations |
|
||||||
|
| `AirCooledCondenser`, `FinCoilCondenser`, `MchxCondenserCoil` | Bobines air / MCHX |
|
||||||
|
| `FreeCoolingExchanger` | Free-cooling eau |
|
||||||
|
|
||||||
## Exit Codes
|
Secondaire 4 ports :
|
||||||
|
|
||||||
| Code | Meaning |
|
```text
|
||||||
|------|---------|
|
BrineSource/AirSource → HX:secondary_inlet → HX:secondary_outlet → BrineSink/AirSink
|
||||||
| 0 | Success |
|
```
|
||||||
| 1 | Simulation error |
|
|
||||||
| 2 | Configuration error |
|
|
||||||
| 3 | I/O error |
|
|
||||||
|
|
||||||
## Examples
|
ΔP secondaire de rating (optionnel) :
|
||||||
|
|
||||||
See `crates/cli/examples/` for complete configuration examples:
|
```json
|
||||||
|
"secondary_rated_pressure_drop_pa": 40000,
|
||||||
|
"secondary_rated_m_flow_kg_s": 0.5
|
||||||
|
```
|
||||||
|
|
||||||
- `chiller_r410a_full.json` - Water chiller with R410A
|
### Tuyauterie / machines tournantes
|
||||||
- `heat_pump_r410a.json` - Air-to-water heat pump
|
|
||||||
- `simple_cycle.json` - Simple heat exchanger cycle
|
| Type | Notes |
|
||||||
|
|------|-------|
|
||||||
|
| `Pipe` / `RefrigerantPipe` / `WaterPipe` / `AirDuct` | `length_m`, `diameter_m` ; `pressure_drop_pa = 0` → **Darcy** L/D ; `> 0` → ΔP imposé |
|
||||||
|
| `Pump`, `Fan` | Courbes + affinity laws |
|
||||||
|
| `FlowSplitter`, `FlowMerger`, `Drum` | Jonctions / séparateur |
|
||||||
|
|
||||||
|
### Frontières
|
||||||
|
|
||||||
|
| Type | Flags Fixed/Free |
|
||||||
|
|------|------------------|
|
||||||
|
| `BrineSource` / `BrineSink` | `fix_pressure`, `fix_temperature`, `fix_mass_flow` |
|
||||||
|
| `AirSource` / `AirSink` | idem (+ psychrométrie `t_dry_c`, `rh`) |
|
||||||
|
| `RefrigerantSource` / `RefrigerantSink` | P, qualité / h, ṁ |
|
||||||
|
|
||||||
|
**Défaut recommandé (Modelica MassFlowSource_T)** : source Fixed T + Fixed ṁ + Free P ; sink Fixed P.
|
||||||
|
|
||||||
|
Voir [`docs/modelica-boundary-proof.md`](../../docs/modelica-boundary-proof.md).
|
||||||
|
|
||||||
|
### Divers
|
||||||
|
|
||||||
|
`ThermalLoad`, `HeatSource`, `Anchor` / `RefrigerantNode`, `Placeholder`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contrôles (régulation / calibration)
|
||||||
|
|
||||||
|
```json
|
||||||
|
"controls": [
|
||||||
|
{
|
||||||
|
"type": "SaturatedController",
|
||||||
|
"id": "sh_loop",
|
||||||
|
"measure": { "component": "evap", "output": "superheat" },
|
||||||
|
"actuator": {
|
||||||
|
"component": "exv",
|
||||||
|
"factor": "opening",
|
||||||
|
"initial": 0.5,
|
||||||
|
"min": 0.1,
|
||||||
|
"max": 1.0
|
||||||
|
},
|
||||||
|
"target": 5.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque boucle ajoute des inconnues d’actionneur + résidus de tracking. Le système doit rester DoF-carré (mesure FIX ↔ actionneur FREE).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stratégies solveur
|
||||||
|
|
||||||
|
| Valeur | Comportement |
|
||||||
|
|--------|--------------|
|
||||||
|
| `newton` | Newton–Raphson (défaut). Armijo activé si contrôles, orifice EXV, ou Free-P sur `BrineSource`. |
|
||||||
|
| `picard` | Substitution successive amortie (ω ≈ 0,5) |
|
||||||
|
| `fallback` | Newton → Picard si divergence → retour Newton si résidu bas |
|
||||||
|
|
||||||
|
```json
|
||||||
|
"solver": {
|
||||||
|
"strategy": "newton",
|
||||||
|
"max_iterations": 300,
|
||||||
|
"tolerance": 1e-6
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Si le résidu décroît lentement (Jacobien partiellement numérique sur certains HX), augmenter `max_iterations` (ex. 1000).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sortie et codes de sortie
|
||||||
|
|
||||||
|
Sortie typique JSON (`--output`) :
|
||||||
|
|
||||||
|
- `status` : `converged` / `Error` / …
|
||||||
|
- `iterations`, `state` (arêtes : ṁ, P, h…)
|
||||||
|
- `performance` (puissances, COP…)
|
||||||
|
- `dof` (équations vs inconnues)
|
||||||
|
- `error`, `failure_diagnostics` si échec après itérations
|
||||||
|
|
||||||
|
| Code | Signification |
|
||||||
|
|------|----------------|
|
||||||
|
| 0 | Succès |
|
||||||
|
| 1 | Erreur de simulation / non-convergence |
|
||||||
|
| 2 | Erreur de configuration |
|
||||||
|
| 3 | Erreur I/O |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exemples fournis (`examples/`)
|
||||||
|
|
||||||
|
| Fichier | Intérêt |
|
||||||
|
|---------|---------|
|
||||||
|
| `chiller_aircooled_r134a.json` | Chiller air 4 ports, emergent |
|
||||||
|
| `chiller_watercooled_r410a.json` | Chiller eau R410A |
|
||||||
|
| `chiller_flooded_4port_watercooled.json` | FloodedEvaporator |
|
||||||
|
| `chiller_r134a_emergent_pressure.json` | Pressions émergentes |
|
||||||
|
| `chiller_r134a_exv_orifice.json` | EXV orifice (opening physique) |
|
||||||
|
| `chiller_r134a_superheat_control.json` | Boucle SH |
|
||||||
|
| `heatpump_airsource_r410a.json` | PAC air |
|
||||||
|
| `heatpump_r410a_reversing_valve.json` | Vanne 4 voies |
|
||||||
|
| `hx_air_water_4port.json` | HX isolé |
|
||||||
|
| `bphx_evaporator_condenser.json` | Plaques brasées |
|
||||||
|
| `capillary_tube_r134a.json` | Capillaire |
|
||||||
|
| `rate_chiller_iplv_ahri.json` | Rating IPLV |
|
||||||
|
| `scop_heatpump_r134a.json` | SCOP |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pièges fréquents
|
||||||
|
|
||||||
|
1. **EXV `opening` sans effet** → il manque `orifice_kv` (sinon isenthalpique seul ; ṁ = compresseur).
|
||||||
|
2. **DoF under-constrained** → source Free P sans fermeture P sur le HX/pipe ; ou oubli de brancher le secondaire 4 ports.
|
||||||
|
3. **DoF over-constrained** → Fixed ṁ **et** Fixed P sur la même frontière ; ou double Fixed-P sans ΔP.
|
||||||
|
4. **Pipe isobare** → avec l’ancien défaut mental « ΔP=0 = rien » : aujourd’hui `pressure_drop_pa = 0` déclenche **Darcy** depuis L/D.
|
||||||
|
5. **Exemples obsolètes** cités dans d’anciennes docs (`chiller_r410a_full.json`, etc.) → utiliser la table ci-dessus.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voir aussi
|
||||||
|
|
||||||
|
- [README racine](../../README.md) — architecture, composants, solveur
|
||||||
|
- [DOCUMENTATION.md](../../DOCUMENTATION.md) — manuel technique
|
||||||
|
- [docs/CLI_TUTORIAL.md](../../docs/CLI_TUTORIAL.md) — tutoriel pas à pas
|
||||||
|
- [docs/modelica-boundary-proof.md](../../docs/modelica-boundary-proof.md) — Fixed/Free
|
||||||
|
- [docs/rating-and-seasonal-metrics.md](../../docs/rating-and-seasonal-metrics.md) — IPLV / SCOP / SEER
|
||||||
|
|||||||
Reference in New Issue
Block a user