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>
Entropyk
Moteur de simulation thermodynamique pour cycles frigorifiques, pompes à chaleur et systèmes CVC (HVAC/R).
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· Exemples avancés :EXAMPLES_FULL.md· Frontières Modelica :docs/modelica-boundary-proof.md
Table des matières
- Ce que fait Entropyk
- Architecture du dépôt
- Principes physiques et DoF
- Le solveur
- Catalogue des composants
- Mode CLI
- API Rust (SystemBuilder)
- Frontières Fixed / Free (style Modelica)
- EXV, orifice et débit
- Fluides et backends
- Interface web
- Bindings Python / C / WASM
- Installation et commandes
- Exemples fournis
- Conventions de développement
1. Ce que fait Entropyk
Entropyk simule un cycle frigorifique / PAC / chiller en régime permanent :
- Vous déclarez des composants (compresseur, condenseur, EXV, évaporateur, sources d’air/eau…).
- Vous les câblez par des arêtes (
comp:outlet → cond:inlet). - Le moteur construit un vecteur d’état, assemble résidus + Jacobien, et Newton (ou Picard / fallback) converge.
- 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
Flux de données :
JSON config / SystemBuilder / UI
│
▼
create_component → System (graphe)
│
▼
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 :
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)
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 |
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.
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 :
- Trait
Component+ Jacobien exact danscrates/components - Export façade
crates/entropyk - Bras
create_componentdanscrates/cli/src/run.rs - Wrapper Python (PyO3) et WASM si exposé
- 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
# 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
{
"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
}
}
Pipeline interne de run
- Parse
ScenarioConfig - Pour chaque composant :
create_component(...)(CoolProp, params, modes orifice / emergent…) - Ajout des arêtes nommées
nom:port finalize()+ contrôle DoF- Seed (frontières + staging HP/BP)
- Solve selon
solver.strategy - Sérialisation JSON : états d’arêtes, performances,
dof,failure_diagnosticssi é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.
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_dofNewtonConfig/PicardConfig/FallbackConfig— stratégiesSimulationResult— sortie structurée
8. Frontières Fixed / Free (style Modelica)
Alignement documenté dans 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) :
"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)
{ "type": "IsenthalpicExpansionValve", "name": "exv", "emergent_pressure": true }
- Équation :
h_out − h_in = 0 - ṁ imposé par le compresseur (déplacement)
openingignoré (même s’il apparaît dans l’UI avec une valeur par défaut)
Mode B — Orifice Fixed (opening = paramètre)
{
"type": "IsenthalpicExpansionValve",
"name": "exv",
"emergent_pressure": true,
"orifice_kv": 2.0e-6,
"opening": 0.6,
"fix_opening": true
}
Loi :
ṁ = 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)
"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_kvexplicite, 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
# 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)
uv pip install -e ./bindings/python
uv pip install maturin
cd bindings/python && uv run maturin develop --release
uv run pytest tests/
C
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 viacoolprop-sys) - Pour l’UI : Node.js + npm
- Pour Python :
uv
Commandes courantes
# 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 :
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,
Resultpartout (politique zero-panic en production). - Jacobiens : analytiques exacts ; pas de différences finies sauf chemin explicitement documenté / temporaire.
- Types : newtypes SI (
Pressure,Enthalpy…) — pas def64nus 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)
- Struct +
Componentdanscrates/components - Tests unitaires (résidus, Jacobien FD-check)
- Export
lib.rs+ façadeentropyk - Bras CLI
create_component - Exemple JSON sous
crates/cli/examples/ - Meta UI + bindings si besoin
Liens utiles
| Document | Contenu |
|---|---|
DOCUMENTATION.md |
Modèles physiques, solveur, API |
EXAMPLES_FULL.md |
Scénarios avancés |
docs/CLI_TUTORIAL.md |
Tutoriel CLI |
docs/modelica-boundary-proof.md |
Preuve Fixed/Free |
docs/components/ |
Fiches composants |
AGENTS.md |
Instructions agents / structure |
crates/cli/README.md |
Détails CLI |
apps/web/README.md |
UI |
Projet : Entropyk · Langage : Rust · Licence / version : voir Cargo.toml (v0.1.x)