# Entropyk — Manuel technique 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). --- ## Table des matières 1. [Fondations physiques](#1-fondations-physiques) 2. [Fluides (`entropyk-fluids`)](#2-fluides-entropyk-fluids) 3. [Composants (`entropyk-components`)](#3-composants-entropyk-components) 4. [Solveur (`entropyk-solver`)](#4-solveur-entropyk-solver) 5. [Degrés de liberté (DoF)](#5-degrés-de-liberté-dof) 6. [Frontières Fixed / Free](#6-frontières-fixed--free) 7. [Fonctionnalités avancées](#7-fonctionnalités-avancées) 8. [API multi-plateformes](#8-api-multi-plateformes) 9. [Démarrage et références](#9-démarrage-et-références) --- ## 1. Fondations physiques ### 1.1 Typage dimensionnel Chaque grandeur est un *newtype* SI — pas de `f64` nu aux frontières publiques. | Grandeur | Unité interne SI | Symbole | |----------|------------------|---------| | Pression | Pascal (Pa) | \(P\) | | 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}\) | Les configs JSON acceptent souvent °C / bar pour l’ergonomie ; la conversion vers SI se fait à la construction des composants. ### 1.2 Lois de conservation Sur chaque nœud / branche, le solveur impose localement : - **Masse** : \(\sum \dot{m}_{\mathrm{in}} - \sum \dot{m}_{\mathrm{out}} = 0\) (souvent trivialisée sur branche série via ṁ partagé) - **É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] \] *(Note : dans une version antérieure, chaque arête ne portait que \([P, h]\) ; le débit ṁ est désormais une inconnue d’arête à part entière.)* Sur une chaîne série (un composant à une entrée et une sortie), les arêtes partagent généralement le même index de débit ṁ : le solveur fusionne alors ces inconnues pour réduire la taille du système. --- ## 2. Fluides (`entropyk-fluids`) 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). ### 2.1 Implémentations | Backend | Rôle | |---------|------| | **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 | Feature Cargo typique : `coolprop` via `coolprop-sys` (bibliothèque précompilée sous `vendor/coolprop`). ### 2.2 Phases 1. **Sous-refroidi** : \(h < h_{\mathrm{sat},l}(P)\) 2. **Diphasique** : \(h_{\mathrm{sat},l}(P) \le h \le h_{\mathrm{sat},v}(P)\) 3. **Surchauffé** : \(h > h_{\mathrm{sat},v}(P)\) 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}} \] --- ## 3. Composants (`entropyk-components`) Tous implémentent le trait `Component` : - `n_equations()` — nombre de résidus - `compute_residuals(state, r)` — \(\mathbf{F}(\mathbf{x})\) - `jacobian_entries(state, J)` — \(\partial\mathbf{F}/\partial\mathbf{x}\) (**analytique** de préférence) - ports / `set_system_context` / `set_port_context` — indices d’arêtes live ### 3.1 Compresseurs #### `IsentropicCompressor` (cycles émergents courants) - Loi de débit (si non métré) : \(\dot{m} \approx \rho_{\mathrm{suc}}\,V\,N\,\eta_{\mathrm{vol}}\) - É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`. --- ## 4. Solveur (`entropyk-solver`) On résout \(\mathbf{F}(\mathbf{x})=\mathbf{0}\) sur le vecteur d’état global (arêtes + actionneurs + couplages). ### 4.1 Newton–Raphson (défaut CLI) \[ \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 : pressions haute et basse initialisées séparément par étages (`build_staged_emergent_seed`) - Actionneurs libres : valeurs initiales nominales --- ## 5. Degrés de liberté (DoF) Un système est **carré** ssi : \[ n_{\mathrm{équations}} = n_{\mathrm{inconnues}} \] - Sur-contraint → `TopologyError::DofImbalance` à `finalize()` (porte DoF, défaut ON) - Sous-contraint → refusé en production CLI (`validate_system_dof`) 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`. --- ## 6. Frontières Fixed / Free Alignement Modelica `MassFlowSource_T` / `Boundary_pT` — détails et sources : [`docs/modelica-boundary-proof.md`](./docs/modelica-boundary-proof.md). | 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 - Pas de `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