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:
2026-07-18 00:06:39 +02:00
parent 3358b74342
commit a4f0e26263
3 changed files with 1187 additions and 247 deletions

View File

@@ -1,169 +1,317 @@
# 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 larchitecture globale, les composants et le solveur. Ce document se concentre sur **lusage CLI**.
---
## Installation
```bash
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
# Single simulation
./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
cargo run -p entropyk-cli -- <sous-commande> ...
```
## 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
{
"name": "Chiller eau glacée R410A",
"fluid": "R410A",
"circuits": [
{
"id": 0,
"components": [
{
"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
}
],
"name": "Mon chiller",
"description": "optionnel",
"fluid": "R134a",
"fluid_backend": "CoolProp",
"circuits": [ { "id": 0, "components": [], "edges": [] } ],
"controls": [],
"thermal_couplings": [],
"solver": {
"strategy": "fallback",
"max_iterations": 100,
"strategy": "newton",
"max_iterations": 300,
"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 |
|------|---------------------|---------------------|
| `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` |
### Exemple moderne (chiller air, 4 ports)
## 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
{
"hot_circuit": 0,
"cold_circuit": 1,
"ua": 5000,
"efficiency": 0.95
"type": "IsenthalpicExpansionValve",
"name": "exv",
"emergent_pressure": true,
"orifice_kv": 2.0e-6,
"opening": 0.6,
"fix_opening": true
}
```
- `hot_circuit`: Circuit ID providing heat
- `cold_circuit`: Circuit ID receiving heat
- `ua`: Thermal conductance (W/K)
- `efficiency`: Heat exchanger efficiency (0.0-1.0)
Loi : `ṁ = Kv · opening · √(2 · ρ · max(ΔP, 0))`.
Avec orifice Fixed, le CLI met le compresseur en ṁ métré. Voir `examples/chiller_r134a_exv_orifice.json`.
## Solver Strategies
### Échangeurs
| Strategy | Description |
|----------|-------------|
| `newton` | Newton-Raphson solver |
| `picard` | Sequential substitution (Picard iteration) |
| `fallback` | Picard → Newton fallback (recommended) |
| Type | Paramètres utiles |
|------|-------------------|
| `Condenser` / `Evaporator` | `ua`, `emergent_pressure`, `subcooling_k` / SH, `secondary_fluid`, ΔP secondaire |
| `FloodedEvaporator` | `ua`, `quality_control` |
| `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 |
|------|---------|
| 0 | Success |
| 1 | Simulation error |
| 2 | Configuration error |
| 3 | I/O error |
```text
BrineSource/AirSource → HX:secondary_inlet → HX:secondary_outlet → BrineSink/AirSink
```
## 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
- `heat_pump_r410a.json` - Air-to-water heat pump
- `simple_cycle.json` - Simple heat exchanger cycle
### Tuyauterie / machines tournantes
| 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 dactionneur + résidus de tracking. Le système doit rester DoF-carré (mesure FIX ↔ actionneur FREE).
---
## Stratégies solveur
| Valeur | Comportement |
|--------|--------------|
| `newton` | NewtonRaphson (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 lancien défaut mental « ΔP=0 = rien » : aujourdhui `pressure_drop_pa = 0` déclenche **Darcy** depuis L/D.
5. **Exemples obsolètes** cités dans danciennes 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