docs: full French rewrite of README, plain language, no unexplained acronyms, only real CLI components

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-18 00:17:37 +02:00
parent 246f42c25a
commit f4c104b255

714
README.md
View File

@@ -1,280 +1,396 @@
# Entropyk
Moteur de simulation thermodynamique pour cycles frigorifiques, pompes à chaleur et systèmes CVC (HVAC/R).
Entropyk est un moteur de simulation thermodynamique pour cycles frigorifiques, pompes à chaleur et groupes d'eau glacée (chillers). Écrit en Rust, il assemble une machine sous forme de graphe de composants, résout le système d'équations non linéaires en régime permanent, et expose le même modèle via une **ligne de commande JSON**, une **API Rust**, des **bindings Python / C / WebAssembly** et une **interface web**.
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**.
> 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)
> Documentation détaillée : [`DOCUMENTATION.md`](./DOCUMENTATION.md) · Tutoriel CLI : [`docs/CLI_TUTORIAL.md`](./docs/CLI_TUTORIAL.md) · Frontières Fixed/Free : [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md)
---
## Table des matières
## Sommaire
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 qu'est Entropyk](#1-ce-quest-entropyk)
2. [Installation](#2-installation)
3. [Premier lancement](#3-premier-lancement)
4. [Architecture du dépôt](#4-architecture-du-dépôt)
5. [Le modèle : composants et câblage](#5-le-modèle--composants-et-câblage)
6. [Degrés de liberté (DoF)](#6-degrés-de-liberté-dof)
7. [Le solveur](#7-le-solveur)
8. [Catalogue des composants](#8-catalogue-des-composants)
9. [Frontières Fixed / Free (style Modelica)](#9-frontières-fixed--free-style-modelica)
10. [Le détendeur EXV et ses trois modes](#10-le-détendeur-exv-et-ses-trois-modes)
11. [Fluides et backends](#11-fluides-et-backends)
12. [La ligne de commande](#12-la-ligne-de-commande)
13. [Interface web](#13-interface-web)
14. [Bindings Python, C, WebAssembly](#14-bindings-python-c-webassembly)
15. [Exemples fournis](#15-exemples-fournis)
16. [Conventions de développement](#16-conventions-de-développement)
---
## 1. Ce que fait Entropyk
## 1. Ce qu'est Entropyk
Entropyk simule un **cycle frigorifique / PAC / chiller** en régime permanent :
Entropyk simule un **cycle frigorifique, une pompe à chaleur ou un chiller** en régime permanent :
1. Vous déclarez des **composants** (compresseur, condenseur, EXV, évaporateur, sources dair/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.
1. Vous déclarez des **composants** : un compresseur, un condenseur, un détendeur, un évaporateur, et les sources d'air ou d'eau qui les alimentent.
2. Vous les **câblez** entre eux par des liaisons, par exemple la sortie du compresseur vers l'entrée du condenseur.
3. Le moteur assemble automatiquement le système d'équations, calcule ses dérivées (la matrice jacobienne), et le résout par la méthode de Newton — avec repli vers des méthodes plus robustes si besoin.
4. Vous récupérez les **pressions, enthalpies, débits, puissances et COP**, ainsi qu'un diagnostic indiquant si le système est bien équilibré (autant d'équations que d'inconnues).
Cas dusage typiques :
Le COP (coefficient de performance) est le rapport entre la puissance utile (froid ou chaud) et la puissance électrique consommée par le compresseur.
| Cas | Comment |
|-----|---------|
| Point de design dun 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` |
Cas d'usage typiques :
- **Dimensionner un chiller à un point de fonctionnement** : écrire un fichier JSON décrivant la machine, puis lancer `entropyk-cli run`.
- **Laisser les pressions d'aspiration et de refoulement flotter** au lieu de les imposer : activer `emergent_pressure` sur les échangeurs et le détendeur ; les pressions résultent alors des bilans thermiques.
- **Calibrer la machine sur une cible** (surchauffe, capacité, température de sortie) : ajouter une boucle de régulation qui ajuste un actionneur (ouverture du détendeur, coefficient d'échange) pour atteindre la cible.
- **Évaluer l'efficacité saisonnière** selon les normes en vigueur (IPLV, SCOP, SEER) : les sous-commandes `rate`, `scop`, `seer` rejouent le cycle à plusieurs points de charge.
- **Qualifier un échangeur isolé** : la sous-commande `qualify` balaye la température et le débit du fluide secondaire pour produire une fiche de performance.
- **Construire un schéma à la souris** : l'interface web (`apps/web`) permet de dessiner le circuit et de lancer la simulation via le serveur `ui-server`.
---
## 2. Architecture du dépôt
## 2. Installation
### Prérequis
- **Rust** (toolchain stable, édition 2021).
- **CoolProp**, la bibliothèque de propriétés thermodynamiques, livrée précompilée sous `vendor/coolprop` et liée via `coolprop-sys`.
- Pour l'interface web : **Node.js** et **npm**.
- Pour les bindings Python : **[uv](https://github.com/astral-sh/uv)** (gestionnaire de paquets Python obligatoire, pas de `pip` direct).
### Build
```bash
cargo build --release
```
Le binaire CLI est `entropyk-cli` (package `entropyk-cli`).
---
## 3. Premier lancement
```bash
cargo run -p entropyk-cli -- run \
--config crates/cli/examples/chiller_aircooled_r134a.json \
--output result.json
```
Sortie console : statut (converged / non-converged / timeout), résidu final, nombre d'itérations, temps de calcul, équilibre DoF, états des arêtes (pression en bar, enthalpie en kJ/kg) et performances (puissance frigorifique, puissance absorbée, COP).
---
## 4. Architecture du dépôt
```
Entropyk/
├── crates/
│ ├── core/ # Newtypes physiques : Pressure, Temperature, Enthalpy, MassFlow
│ ├── fluids/ # FluidBackend + CoolProp / Tabular / Incompressible
│ ├── core/ # Types physiques de base : Pression, Température, Enthalpie, Débit
│ ├── fluids/ # Backends de propriétés : CoolProp, tabulaire, incompressible
│ ├── components/ # Tous les composants (trait Component)
│ ├── solver/ # Graphe, DoF, Newton / Picard / Fallback / Homotopy
│ ├── entropyk/ # Façade : SystemBuilder, SimulationResult, rating
│ ├── solver/ # Graphe, DoF, Newton, Picard, fallback
│ ├── entropyk/ # Façade : SystemBuilder, SimulationResult
│ ├── cli/ # Binaire entropyk-cli + exemples JSON
│ └── vendors/ # Parsers données constructeurs (Copeland, Danfoss, SWEP, Bitzer)
│ └── vendors/ # Parsers de données constructeurs (Copeland, Danfoss, SWEP, Bitzer)
├── bindings/
│ ├── python/ # PyO3 (chemin réel — pas crates/bindings/)
│ ├── c/ # FFI C + cbindgen
│ ├── python/ # PyO3
│ ├── c/ # FFI C (cbindgen)
│ └── wasm/ # WebAssembly
├── apps/web/ # Workbench diagramme (Next.js)
├── demo/ # ui-server Axum (:3030)
├── docs/ # Manuels, Modelica, tutoriels
└── plans/ # Plans daudit / remediation
├── demo/ # ui-server Axum (port 3030)
├── docs/ # Manuels, Modelica, fiches composants
└── tests/fluids/ # Tests d'intégration cross-backend
```
Flux de données :
```text
JSON config / SystemBuilder / UI
create_component System (graphe)
finalize() + DoF gate → vecteur détat [ṁ, P, h]…
Newton / Picard / Fallback
Config JSON / SystemBuilder / UI web
|
v
create_component -> System (graphe)
|
v
finalize() + porte DoF -> vecteur d'état [débit, pression, enthalpie] par arête
|
v
Newton / Picard / fallback
|
v
SimulationResult (états, énergies, COP, diagnostics)
```
---
## 3. Principes physiques et DoF
## 5. Le modèle : composants et câblage
### Vecteur détat
### Vecteur d'état
Chaque **arête** du graphe porte trois inconnues :
Chaque **arête** du graphe (une liaison entre deux ports) porte trois inconnues :
| Slot | Symbole | Unité SI |
|------|---------|----------|
| 0 | ṁ | kg/s |
| 1 | P | Pa |
| 2 | h | J/kg |
| Rang | Grandeur | Unité SI |
|------|----------|----------|
| 0 | débit massique ṁ | kg/s |
| 1 | pression P | Pa |
| 2 | enthalpie massique h | J/kg |
Sur une branche série (un composant à une entrée et une sortie), les arêtes partagent généralement le **même débit** ṁ : le solveur fusionne alors ces inconnues et réduit dautant la taille du système.
Sur une branche série (un composant à une entrée et une sortie), les arêtes partagent généralement le **même débit** ṁ : le solveur fusionne alors ces inconnues et réduit la taille du système.
### Degrés de liberté (DoF)
### Câblage
Un système est **carré** si :
Les liaisons s'écrivent `nom:port`. Par exemple :
```text
n_équations = n_inconnues
```json
{ "from": "comp:outlet", "to": "cond:inlet" }
```
- 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 dor (alignée Modelica) : **aucun composant ne doit fixer à la fois ṁ et P** sur le même flux.
Le moteur construit le graphe, attribue un index à chaque inconnue d'arête, puis assemble résidus et jacobienne.
---
## 4. Le solveur
## 6. Degrés de liberté (DoF)
Le DoF (degrees of freedom, degrés de liberté) est le cœur du diagnostic. Un système est **carré** quand :
```text
nombre d'équations = nombre d'inconnues
```
- Trop d'équations : système **sur-contraint** (contradictoire).
- Pas assez : système **sous-contraint** (indéterminé).
Dans les deux cas, `finalize()` refuse de lancer la résolution et renvoie un diagnostic détaillé (par composant : équations déclarées, inconnues consommées, rôle de chaque équation). Chaque composant déclare son nombre d'équations et le **rôle** de chacune : bilan d'énergie, chute de pression, condition de frontière, fermeture de sortie (surchauffe, sous-refroidissement, titre), actionneur…
**Règle d'or** : aucun composant ne doit fixer à la fois le débit **et** la pression sur le même flux. C'est l'équivalent de la règle Modelica qui interdit de fermer deux fois le même degré de liberté.
---
## 7. Le solveur
Implémentation : `crates/solver`.
### Stratégies disponibles
### Stratégies
| Stratégie JSON | Comportement |
|----------------|--------------|
| `"newton"` (**défaut**) | NewtonRaphson : `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 dabord ; en cas de divergence → Picard ; retour à Newton si le résidu redescend sous un seuil. |
|-----------------|--------------|
| `"newton"` (défaut) | NewtonRaphson : `x ← x α·J⁻¹·r`. Jacobien analytique fourni par les composants. Recherche linéaire de type Armijo activée automatiquement quand le système est sensible (contrôles, orifice, pression libre côté eau). |
| `"picard"` | Substitution successive amortie : `x ← (1ω)·x + ω·G(x)`, avec ω ≈ 0,5. Plus robuste, convergence plus lente. |
| `"fallback"` | Newton d'abord ; bascule vers Picard en cas de divergence, puis retour à Newton quand le résidu redescend. |
Tolérance typique : `1e-6`. Nombre ditérations CLI : souvent `300` (augmenter pour des Jacobiens partiellement numériques, ex. certains HX).
Tolérance typique : `1e-6`. Itérations : `300` par défaut ; à augmenter pour les échangeurs dont le jacobien est partiellement numérique.
### Boucle Newton (schéma)
### Boucle de résolution
```text
1. Estimation initiale (frontières + pressions haute/basse initialisées par étages 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
1. Estimation initiale (frontières + pressions haute/basse initialisées par étages si emergent_pressure)
2. Calcul des résidus r(x) de tous les composants
3. Assemblage de la matrice jacobienne J(x) = ∂r/∂x
4. Résolution du système linéaire J·Δx = r
5. Mise à jour x ← clamp(x + α·Δx) (pression bornée à un minimum, actionneurs bornés)
6. Répétition jusqu'à ce que ‖r‖ passe sous la tolérance
```
### Ce qui nest **pas** le solveur
### Limites assumées
- 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 proviennent toujours du **backend** (CoolProp…), jamais de valeurs codées en dur : un composant sérieux ne fabrique pas de propriété de secours.
- Régime **permanent** uniquement (pas de dynamique temporelle).
- Pas de CFD : les échangeurs sont des modèles 0D/1D (LMTD, ε-NTU, corrélations d'échange).
- Les propriétés fluides viennent toujours du **backend** (CoolProp…), jamais de valeurs codées en dur.
---
## 5. Catalogue des composants
## 8. 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`).
Tous les composants implémentent le trait `Component` : `n_equations`, `compute_residuals`, `jacobian_entries`, ports. La chaîne `"type"` du JSON correspond exactement aux bras de `create_component` dans `crates/cli/src/run.rs`.
### 5.1 Compresseurs
### 8.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 / SSTSDT (ṁ, 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 |
| Type JSON | Rôle | Paramètres clés |
|-----------|------|-----------------|
| `IsentropicCompressor` | Compresseur à rendement isentropique + déplacement volumétrique ; mode émergent courant | `displacement_m3`, `speed_hz`, `volumetric_efficiency`, `isentropic_efficiency`, `emergent_pressure` |
| `Compressor` | Cartographie constructeur AHRI 540 (débit et puissance selon températures d'aspiration/ refoulement) | coefficients `m1``m10` ou carte polynomiale |
| `ScrewEconomizerCompressor` / `ScrewCompressor` | Compresseur à vis avec port économiseur, variation de fréquence, slide valve optionnel | courbes selon températures de saturation, `speed_hz` |
| `CentrifugalCompressor` | Carte polytropique (facteur de débit, nombre de 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.
En mode **émergent**, le compresseur impose la **loi de débit** (déplacement × masse volumique × rendement volumétrique) et l'énergie de refoulement ; les pressions haute/basse résultent des échangeurs. Si un détendeur à orifice fixe métre le débit, le CLI bascule le compresseur en mode « débit externe » (énergie seule) pour garder le système carré.
Si un EXV à **orifice Fixed** métre le débit, le CLI bascule le compresseur en **ṁ externe** (énergie seule) pour rester carré.
### 8.2 Détente et vannes
### 5.2 Détente / vannes
| Type CLI | Rôle | Notes critiques |
|----------|------|-----------------|
| `IsenthalpicExpansionValve` / `EXV` | Laminants isenthalpiques (`h_out = h_in`) | **Sans `orifice_kv`**, `opening` na **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`… |
| Type JSON | Rôle | Notes |
|-----------|------|-------|
| `IsenthalpicExpansionValve` / `EXV` | Détendeur isenthalpique (`h_out = h_in`) | Sans `orifice_kv`, l'`opening` n'a **aucun effet** — voir [§10](#10-le-détendeur-exv-et-ses-trois-modes) |
| `ExpansionValve` | Détendeur à orifice, modèle Cd·A ou 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` |
| `ReversingValve` / `FourWayValve` | Vanne 4 voies pour pompe à chaleur (inversion froid/chaud) | `mode`, `pressure_drop_pa` |
| `BypassValve` | Bypass hydronique proportionnel | `opening`, `cv` |
### 5.3 Échangeurs frigorifiques
### 8.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 eauair | ε-NTU + BPF |
| `FreeCoolingExchanger` | Free-cooling côté eau | |
| Type JSON | Rôle | Notes |
|-----------|------|-------|
| `Condenser` / `CondenserCoil` | Condenseur + côté secondaire (eau ou air) | `ua`, `emergent_pressure`, `subcooling_k`, `secondary_fluid`, chute de pression secondaire optionnelle |
| `Evaporator` / `EvaporatorCoil` | Évaporateur à détente directe + côté secondaire | `ua`, `superheat_k` ou emergent, `secondary_fluid` |
| `FloodedEvaporator` | Évaporateur noyé / à recirculation | fermeture vapeur saturée ou `quality_control` |
| `HeatExchanger` | Échangeur générique 4 ports (LMTD / ε-NTU) | `hot_fluid_id`, `cold_fluid_id`, `ua` |
| `BphxEvaporator` / `BphxCondenser` | Échangeur à plaques brasées + corrélations d'échange | géométrie des plaques, corrélations Longo/Shah |
| `AirCooledCondenser` | Condenseur refroidi par air (T_cond ≈ air + approach) | `oat_k`, `approach_k` |
| `FinCoilCondenser` | Batterie ailettée air | géométrie tubes/ailettes |
| `MchxCondenserCoil` / `MchxCoil` | Batterie à microcanaux | géométrie des microcanaux |
| `FreeCoolingExchanger` / `FreeCooling` | 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.
**Pressions émergentes** (`emergent_pressure: true`) : l'échangeur ne pince plus la pression de saturation sur une température de design ; la pression flotte et est fermée par le sous-refroidissement, la surchauffe, le titre ou les 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).
**Côté secondaire 4 ports** : brancher `BrineSource`/`AirSource` port `secondary_inlet``secondary_outlet``BrineSink`/`AirSink`. L'échangeur propage la pression (fermeture isobare ou chute de pression quadratique issue du rating).
### 5.4 Tuyauterie, pompes, air
### 8.4 Tuyauterie, pompes, air
| Type CLI | Rôle | Notes |
|----------|------|-------|
| `Pipe` / `RefrigerantPipe` / `WaterPipe` / `AirDuct` | Conduits DarcyWeisbach | `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) | |
| Type JSON | Rôle | Notes |
|-----------|------|-------|
| `Pipe` / `RefrigerantPipe` / `WaterPipe` / `AirDuct` / `PipeWater` / `PipeAir` | Conduits (DarcyWeisbach) | `length_m`, `diameter_m` ; `pressure_drop_pa = 0`chute de pression calculée par Darcy depuis la géométrie et le débit ; `> 0` → chute de pression imposée |
| `Pump` | Courbes hauteur-débit + rendement, lois de similitude | — |
| `Fan` | Courbes pression-débit + rendement, lois de similitude | souvent sur boucle air |
| `FlowSplitter` / `FlowMerger` | Jonctions de débit | — |
| `Drum` | Séparateur liquide/vapeur (flooded) | |
### 5.5 Frontières (sources / sinks)
### 8.5 Frontières (sources et 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 |
| Type JSON | Fluide | Impose typiquement |
|-----------|--------|--------------------|
| `RefrigerantSource` / `RefrigerantSink` | Frigorigène | pression (+ titre ou enthalpie), débit optionnel |
| `BrineSource` / `BrineSink` | Eau / glycol | température, débit, pression (Fixed/Free) |
| `AirSource` / `AirSink` | Air humide | température sèche, humidité relative, débit, pression |
Voir [§8](#8-frontières-fixed--free-style-modelica).
Voir [§9](#9-frontières-fixed--free-style-modelica).
### 5.6 Divers
### 8.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) |
| Type JSON | Rôle |
|-----------|------|
| `ThermalLoad` | Charge thermique Q couplée |
| `HeatSource` | Injection de chaleur en ligne |
| `Anchor` / `RefrigerantNode` | Nœud / ancre de surchauffe optionnelle |
| `Placeholder` | Composant stub (tests, topologie) |
### 5.7 Intégration obligatoire dun nouveau composant
### 8.7 Intégration d'un nouveau composant
Lorsquon ajoute un composant, il doit être câblé **partout** :
Tout nouveau composant 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
1. Struct + trait `Component` + jacobien exact dans `crates/components`.
2. Tests unitaires (résidus, vérification du jacobien par différences finies).
3. Export dans `crates/components/src/lib.rs` et ré-export dans `crates/entropyk/src/lib.rs`.
4. Bras dans `create_component` (`crates/cli/src/run.rs`).
5. Wrapper Python (PyO3) et WASM si exposé.
6. Métadonnées UI (`apps/web/src/lib/componentMeta.ts`) si visible dans le workbench.
---
## 6. Mode CLI
## 9. Frontières Fixed / Free (style Modelica)
Binaire : `entropyk-cli` (`crates/cli`).
Entropyk reprend la sémantique des conditions aux limites Modelica. Les sources et sinks exposent trois booléens : `fix_pressure`, `fix_temperature`, `fix_mass_flow`.
| Pattern Modelica | Source | Sink | Conséquence |
|------------------|--------|------|-------------|
| **MassFlowSource_T** (défaut Entropyk quand ṁ est imposé) | T fixée, ṁ fixé, **P libre** | P fixée, T_out libre | La chute de pression de l'échangeur ferme le degré de liberté de pression |
| **Boundary_pT** | P fixée, T fixée, ṁ libre | P fixée | Il faut une résistance hydraulique (conduit ou chute de pression d'échangeur) entre les deux pressions fixées |
| Rating T_out | ṁ libre | P fixée + T_out fixée | Le débit devient inconnu (calibration) |
**Interdit** : fixer à la fois le débit **et** la pression sur la même source sans degré de liberté ailleurs.
Chute de pression secondaire de rating (eau ou air) :
```json
"secondary_rated_pressure_drop_pa": 40000,
"secondary_rated_m_flow_kg_s": 0.5
```
---
## 10. Le détendeur EXV et ses trois modes
Le composant `IsenthalpicExpansionValve` (alias `EXV`) a trois modes selon qu'on lui donne un orifice (`orifice_kv`) ou non.
### Mode A — Isenthalpique seul (chillers classiques)
```json
{ "type": "IsenthalpicExpansionValve", "name": "exv", "emergent_pressure": true }
```
- Équation : `h_out h_in = 0` (détente adiabatique sans travail).
- Le débit est **imposé par le compresseur** (loi de déplacement).
- L'`opening` est **ignoré**, même si l'UI affiche une valeur par défaut.
### Mode B — Orifice fixe (ouverture = paramètre)
```json
{
"type": "IsenthalpicExpansionValve",
"name": "exv",
"emergent_pressure": true,
"orifice_kv": 2.0e-6,
"opening": 0.6,
"fix_opening": true
}
```
Loi de débit :
```text
ṁ = Kv · opening · √(2 · ρ_in · max(ΔP, 0))
```
Le CLI met alors le compresseur en mode « débit métré » (il abandonne sa loi de déplacement) pour garder le système carré.
### Mode C — Orifice libre (ouverture = inconnue)
```json
"orifice_kv": 2.0e-6,
"fix_opening": false
```
L'`opening` devient une inconnue ; il faut une boucle de régulation (par exemple surchauffe → contrôleur saturé) pour la fermer.
> **Piège UI** : le catalogue affiche « Opening » même sans `orifice_kv`. Sans orifice explicite, changer l'ouverture ne change **rien**. Exemple dédié : `crates/cli/examples/chiller_r134a_exv_orifice.json`.
---
## 11. Fluides et backends
| Backend | Usage |
|---------|-------|
| **CoolProp** (`fluid_backend: "CoolProp"`) | Frigorigènes (R134a, R410A…), eau — défaut pour la physique sérieuse |
| **Tabular** | Tables interpolées (WASM, environnements sans CoolProp) |
| **Incompressible** | Glycols et liquides (masse volumique, viscosité de design) |
| **Cached / Damped** | Wrappers de performance et de stabilité |
Les types physiques de `entropyk-core` sont toujours en unités SI (Pa, K, J/kg, kg/s). Les JSON d'entrée acceptent souvent les °C et bar pour l'ergonomie ; la conversion est faite à la construction.
---
## 12. La ligne de commande
Binaire : `entropyk-cli` (package `entropyk-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 |
| `run` | Une simulation depuis un fichier JSON |
| `batch` | Dossier de configs, exécution parallèle |
| `validate` | Vérifie le JSON et l'équilibre DoF (build + solve de contrôle) |
| `qualify` | Qualification d'un échangeur (régime frigorigène fixe, balayage secondaire) |
| `rate` | Rating saisonnier : IPLV (AHRI 550/590) ou ESEER |
| `scop` | SCOP chauffage par bins EN 14825 |
| `seer` | SEER froid par bins EN 14825 |
| `schema` | Émet le JSON Schema du modèle (source unique pour CLI, UI, outils externes) |
Flags globaux : `-v` / `--verbose`, `-q` / `--quiet`.
### Exemples dinvocation
### Exemples
```bash
# Build
cargo build --release -p entropyk-cli
# Chiller air R134a
# Simulation unique
cargo run -p entropyk-cli -- run \
--config crates/cli/examples/chiller_aircooled_r134a.json \
--output result.json
@@ -288,7 +404,7 @@ 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
# Schéma JSON
cargo run -p entropyk-cli -- schema -o model-ir.schema.json
```
@@ -304,10 +420,10 @@ cargo run -p entropyk-cli -- schema -o model-ir.schema.json
"id": 0,
"name": "Circuit principal",
"components": [
{ "type": "IsentropicCompressor", "name": "comp", "...": "..." },
{ "type": "Condenser", "name": "cond", "...": "..." },
{ "type": "IsenthalpicExpansionValve", "name": "exv", "...": "..." },
{ "type": "Evaporator", "name": "evap", "...": "..." }
{ "type": "IsentropicCompressor", "name": "comp" },
{ "type": "Condenser", "name": "cond" },
{ "type": "IsenthalpicExpansionValve", "name": "exv" },
{ "type": "Evaporator", "name": "evap" }
],
"edges": [
{ "from": "comp:outlet", "to": "cond:inlet" },
@@ -328,139 +444,21 @@ cargo run -p entropyk-cli -- schema -o model-ir.schema.json
### Pipeline interne de `run`
1. Parse `ScenarioConfig`
2. Pour chaque composant : `create_component(...)` (CoolProp, params, modes orifice / emergent)
3. Ajout des arêtes nommées `nom:port`
4. `finalize()` + contrôle DoF
5. Estimation initiale (frontières + pressions haute/basse par étages)
6. Solve selon `solver.strategy`
7. Sérialisation JSON : états darêtes, performances, `dof`, `failure_diagnostics` si échec
1. Lecture de `ScenarioConfig`.
2. Pour chaque composant : `create_component(...)` (CoolProp, params, modes orifice / emergent).
3. Ajout des arêtes nommées `nom:port`.
4. `finalize()` + contrôle DoF (système carré obligatoire).
5. Estimation initiale (frontières + pressions par étages).
6. Résolution selon `solver.strategy`.
7. Sérialisation JSON : états d'arêtes, performances, `dof`, `failure_diagnostics` en cas d'é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 dinconnues dactionneurs + résidus de tracking.
Bloc optionnel `controls` : boucles qui lient une **mesure** (capacité, surchauffe…) à un **actionneur** (`opening`, `z_ua`, `f_m`…). Le solveur ajoute alors les inconnues d'actionneur et les résidus de suivi au système.
---
## 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 dentré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 sil apparaît dans lUI 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 louverture 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 dentrée acceptent souvent °C / bar pour lergonomie ; la conversion est faite à la construction.
---
## 11. Interface web
## 13. Interface web
| Élément | Chemin |
|---------|--------|
@@ -469,11 +467,10 @@ Types physiques dans `entropyk-core` : toujours SI (Pa, K, J/kg, kg/s). Les JSON
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`
- Palette de composants avec glyphes ISO, câblage React Flow.
- Ledger DoF en temps réel (`dofLedger.ts`).
- Coach Fixed/Free Modelica (`boundaryFix.ts`, `dofCoach.ts`).
- Simulation via `POST /api/simulate`.
```bash
# Terminal 1
@@ -485,11 +482,11 @@ cd apps/web && npm run dev
---
## 12. Bindings Python / C / WASM
## 14. Bindings Python, C, WebAssembly
Chemins réels : `bindings/python`, `bindings/c`, `bindings/wasm` (pas sous `crates/`).
### Python (`uv` obligatoire)
### Python (uv obligatoire)
```bash
uv pip install -e ./bindings/python
@@ -505,52 +502,15 @@ cargo build --release -p entropyk-c
# header généré sous target/ (voir bindings/c/README.md)
```
### WASM
### WebAssembly
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.
> Certaines classes Python historiques sont encore des stubs (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 lUI : 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
## 15. Exemples fournis
Répertoire : `crates/cli/examples/`.
@@ -558,15 +518,21 @@ Répertoire : `crates/cli/examples/`.
|---------|---------|
| `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_flooded_4port_watercooled.json` | FloodedEvaporator, DoF carré |
| `chiller_flooded_delta_t_rating.json` | Rating par ΔT |
| `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 |
| `chiller_r134a_exv_orifice.json` | EXV avec orifice (ouverture physique) |
| `chiller_r134a_superheat_control.json` | Boucle de surchauffe |
| `chiller_r134a_slide_valve.json` | Slide valve compresseur à vis |
| `chiller_r134a_dual_circuit_staging.json` | Double circuit en cascade |
| `chiller_r134a_liquid_injection.json` | Injection liquide |
| `chiller_r134a_flooded_headpressure.json` | Flooded à pression de tête |
| `chiller_r410a_bolt_nodes.json` | Nœuds boulonnés |
| `chiller_r410a_coupled_water_loop.json` | Boucle d'eau couplée |
| `heatpump_airsource_r410a.json` | Pompe à chaleur air |
| `heatpump_r410a_reversing_valve.json` | Vanne 4 voies |
| `hx_air_water_4port.json` | HX isolé aireau |
| `heatpump_r134a_fan_headpressure.json` | Pression de tête pilotée par ventilateur |
| `hx_air_water_4port.json` | Échangeur isolé aireau |
| `bphx_evaporator_condenser.json` | Plaques brasées |
| `capillary_tube_r134a.json` | Capillaire |
| `rate_chiller_iplv_ahri.json` | Rating IPLV |
@@ -574,23 +540,23 @@ Répertoire : `crates/cli/examples/`.
---
## 15. Conventions de développement
## 16. Conventions de développement
- **Langage** : Rust, `Result<T, E>` partout — pas de `panic!` en production.
- **Jacobiens** : analytiques exacts ; pas de différences finies sauf chemin explicitement documenté / temporaire.
- **Jacobiens** : analytiques et exacts ; pas de différences finies sauf chemin explicitement documenté ou 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.
- **Documentation technique / commits** : anglais ; communication projet en français.
- **Git** : branche `main`, messages à l'impératif en 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
1. Struct + trait `Component` dans `crates/components`.
2. Tests unitaires (résidus, jacobien vérifié par différences finies).
3. Export `lib.rs` + façade `entropyk`.
4. Bras CLI `create_component`.
5. Exemple JSON sous `crates/cli/examples/`.
6. Métadonnées UI + bindings si besoin.
---
@@ -605,8 +571,12 @@ Répertoire : `crates/cli/examples/`.
| [`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 |
| [`apps/web/README.md`](./apps/web/README.md) | Interface web |
---
**Projet** : Entropyk · **Langage** : Rust · **Licence / version** : voir `Cargo.toml` (v0.1.x)