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:
@@ -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 l’architecture globale, les composants et le solveur. Ce document se concentre sur **l’usage 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 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