Files
Entropyk/docs/simulation-capabilities.md
sepehr 5bd180b5b8
Some checks failed
CI / check (push) Has been cancelled
Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
Capture uncommitted solver robustness work (regularization, domain errors, linear solver lifecycle, tube DP/MSH), web workbench updates, and synced BMAD skills across IDE agent folders before starting BPHX pressure-drop.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:35:31 +02:00

14 KiB
Raw Blame History

Entropyk — Simulation Capabilities & Modelica Comparison / Capacités de simulation & comparaison Modelica

Bilingual document (English first, French below) / Document bilingue (anglais d'abord, français ensuite).

This analysis is code-grounded: every claim is traceable to the Rust sources in crates/. Cette analyse est fondée sur le code : chaque affirmation est traçable dans les sources Rust de crates/.


EN — What Entropyk can simulate

1. Nature of the tool

Entropyk is a steady-state, equation-based thermodynamic-cycle simulator for refrigeration, heat-pump and HVAC systems. It is not a general-purpose DAE engine (like OpenModelica); it is a domain-specific algebraic solver built around a component graph.

  • Solving paradigm: each component contributes residual equations r(x) = 0 and an analytic Jacobian. The global system F(x) = 0 is solved with NewtonRaphson, Picard (sequential substitution), a Newton-homotopy continuation, and a FallbackSolver that chains them. (crates/solver/src/strategies/)
  • State vector: per flow edge (ṁ, P, h); series branches share a single mass-flow unknown after a topology presolve (|B| + 2·|E| layout). (crates/solver/src/system.rs)
  • Fluid properties: CoolPropBackend (production), TestBackend (mock/ideal), plus TabularBackend and IncompressibleBackend in the library. (crates/fluids/)

2. System-level capabilities

Capability Status Evidence
Coupled algebraic solving with analytic Jacobian Component::jacobian_entries, System::assemble_jacobian
Explicit degrees-of-freedom balancing System::validate_inverse_control_dof, mass-flow presolve
Emergent pressures (SST/SDT float from HX↔secondary balance) Condenser::with_emergent_pressure, Evaporator superheat_regulated
Multi-circuit networks (up to 5) CircuitId 0..4, per-circuit flow edges
Inter-circuit thermal coupling (thermal_couplings) physical mode Set hot_component (duty provider, e.g. an ε-NTU Condenser) + cold_component (a ThermalLoad receiver): the coupling owns one unknown Q closed against the hot component's measured duty (Q = η·duty_hot) and injects Q into the cold loop's energy balance — First Law closes across circuits (chiller_r410a_coupled_water_loop.json). Entries without both fields are inert (Q pinned to 0, CLI warns).
Secondary-stream heat exchange (air/water, ε-NTU) Condenser/Evaporator secondary_inlet_temp_c + secondary_mass_flow_kg_s + secondary_cp_j_per_kgk; emergent capacity/COP (e.g. chiller_r410a_full_physics.json → COP≈4.98, First Law closes)
Steady-state supervisory control, co-solved SaturatedController (offset-free PI, anti-windup)
Override / selector priority (min/max) override_network.rs, smoothed softMin/softMax, activation continuation
Inverse / one-shot calibration inverse/calibration.rs, Z-factors z_flow, z_dp, z_ua, z_power, z_etav
Free actuators (e.g. EXV orifice opening) System free-actuator DoF (+1 unknown / +1 component eq)
Reusable parameterized subsystems (flattened) CLI subsystems/instances/connectionsflatten_instances()
Hierarchical composition in Rust ⚠️ partial MacroComponent couples P/h at ports; ṁ continuity not yet coupled
Normative seasonal rating (IPLV/ESEER/SCOP/SEER) CLI rate, scop, seer (re-solves the cycle per load point/bin)
ON/OFF/BYPASS staging (pre-solve) OperationalState, circuits[].enabled
BOLT-style inline spec/probe nodes Anchor (= BOLT BoundaryNode.Refrigerant.Node): probe mode (DoF-neutral) or one imposed spec — signed superheat_k (dTsh, <0 = subcooling), quality, t_c/t_k, p_bar (docs/components/anchor-heat-source.md)
Inline heat injection (fixed or coupling-linked) HeatSource (= BOLT BoundaryNode.Heat.Source): q_w fixed duty + optional coupling-driven Q (motor-cooling pattern), exact Jacobian, excluded from COP aggregation (chiller_r410a_bolt_nodes.json)
Boundary-imposed loop flow BrineSource/BrineSink m_flow_kg_s (= BOLT Vd_fixed=true)

3. Can we build models as complex as Modelica?

Yes for the targeted domain, with caveats. Entropyk reproduces the ideas that make Modelica HVAC libraries powerful:

  • equation-based components with a coupled solve,
  • reusable parameterized subsystems,
  • co-solved supervisory control (setpoint tracking + min/max override priority, exactly the "BOLT"-style chiller control referenced in the code),
  • inverse calibration and normative rating.

You can assemble multi-circuit chillers/heat-pumps with emergent pressures, secondary-fluidcoupled heat exchangers, economizer screw compressors, liquid injection, head-pressure control, free-cooling, and a supervisory control tree — comparable in structural complexity to a Modelica chiller model.

4. Gaps vs Modelica (be precise)

  • Steady-state only — no time integration, no der(x), no dynamic states (thermal masses, sensor lags). Everything targets F(x)=0.
  • No event handling — no zero-crossing / reinit; ModeSwitch (hysteresis, min-runtime) lives outside the Newton solve and is time-based.
  • Causal edge connectors — state is carried on edges/branches as (ṁ,P,h); continuity is enforced by component residuals referencing state indices (a TESPy-like pattern), not Modelica acausal connectors with shared variables and language-level connection equations.
  • Hierarchy is mostly compile-time / flattened — the CLI flattens subsystems before solving; nested subsystems inside the solver require Rust MacroComponent, whose port ṁ-continuity is still incomplete.
  • thermal_couplings transfers a measured duty, not a UA·ΔT law — the physical mode closes Q = η·duty_hot (the hot component's ε-NTU duty) into a ThermalLoad receiver; the ua field is not used as a coupling conductance. For a genuinely two-sided UA·LMTD interface exchanger, use a two-sided HeatExchanger/BPHX or a secondary stream instead. Legacy entries without hot_component/cold_component are inert (Q pinned to 0, CLI warns).
  • CLI fluids limited to CoolProp/Test (Tabular/Incompressible exist in the lib but are not wired to the CLI).
  • No user-authored arbitrary equations — new behaviour requires implementing the Component trait in Rust.

5. One-sentence verdict

Entropyk is closer to a TESPy/BOLT-style steady-state cycle solver with co-solved algebraic supervisory control and inverse calibration than to a general Modelica DAE engine: excellent structural parity for HVAC/refrigeration cycles, but without transients, events, or acausal language-level connectors.


FR — Ce qu'Entropyk permet de simuler

1. Nature de l'outil

Entropyk est un simulateur de cycles thermodynamiques en régime permanent (steady-state), basé sur les équations, pour la réfrigération, les pompes à chaleur et le CVC. Ce n'est pas un moteur DAE généraliste (comme OpenModelica) : c'est un solveur algébrique dédié au domaine, organisé autour d'un graphe de composants.

  • Paradigme de résolution : chaque composant fournit des équations résiduelles r(x) = 0 et un Jacobien analytique. Le système global F(x) = 0 est résolu par NewtonRaphson, Picard (substitution séquentielle), une continuation par homotopie de Newton, et un FallbackSolver qui les enchaîne. (crates/solver/src/strategies/)
  • Vecteur d'état : par arête de flux (ṁ, P, h) ; les branches en série partagent un seul inconnu de débit après un presolve topologique (layout |B| + 2·|E|). (crates/solver/src/system.rs)
  • Propriétés fluides : CoolPropBackend (production), TestBackend (mock/gaz idéal), plus TabularBackend et IncompressibleBackend dans la bibliothèque. (crates/fluids/)

2. Capacités au niveau système

Capacité État Preuve (code)
Résolution algébrique couplée + Jacobien analytique Component::jacobian_entries, System::assemble_jacobian
Équilibrage explicite des degrés de liberté (DoF) System::validate_inverse_control_dof, presolve débit
Pressions émergentes (SST/SDT flottent selon l'équilibre HX↔secondaire) Condenser::with_emergent_pressure, Evaporator superheat_regulated
Réseaux multi-circuits (jusqu'à 5) CircuitId 0..4, arêtes de flux par circuit
Couplage thermique inter-circuits (thermal_couplings) mode physique Renseigner hot_component (fournisseur de puissance, ex. Condenser ε-NTU) + cold_component (récepteur ThermalLoad) : le couplage porte un inconnu Q fermé sur la puissance mesurée du composant chaud (Q = η·duty_hot) et injecte Q dans le bilan d'énergie de la boucle froide — le 1er principe ferme entre circuits (chiller_r410a_coupled_water_loop.json). Les entrées sans ces deux champs sont inertes (Q épinglé à 0, la CLI avertit).
Échange par flux secondaire (air/eau, ε-NTU) Condenser/Evaporator secondary_inlet_temp_c + secondary_mass_flow_kg_s + secondary_cp_j_per_kgk ; capacité/COP émergents (ex. chiller_r410a_full_physics.json → COP≈4.98, 1er principe fermé)
Contrôle supervisoire steady-state, co-résolu SaturatedController (PI offset-free, anti-windup)
Priorité par override / sélecteur (min/max) override_network.rs, softMin/softMax lissés, continuation d'activation
Calibration inverse / one-shot inverse/calibration.rs, facteurs Z z_flow, z_dp, z_ua, z_power, z_etav
Actuateurs libres (ex. ouverture orifice EXV) DoF free-actuator (+1 inconnu / +1 éq. composant)
Sous-systèmes paramétrés réutilisables (aplatis) CLI subsystems/instances/connectionsflatten_instances()
Composition hiérarchique en Rust ⚠️ partiel MacroComponent couple P/h aux ports ; continuité ṁ pas encore couplée
Rating saisonnier normatif (IPLV/ESEER/SCOP/SEER) CLI rate, scop, seer (re-résout le cycle par point/bin)
Staging ON/OFF/BYPASS (pré-solve) OperationalState, circuits[].enabled
Nœuds spec/sonde inline style BOLT Anchor (= BoundaryNode.Refrigerant.Node de BOLT) : mode sonde (neutre en DoF) ou une spec imposée — superheat_k signé (dTsh, <0 = sous-refroidissement), quality, t_c/t_k, p_bar (docs/components/anchor-heat-source.md)
Injection de chaleur inline (fixe ou liée à un couplage) HeatSource (= BoundaryNode.Heat.Source de BOLT) : puissance fixe q_w + Q optionnel piloté par couplage (pattern refroidissement moteur), Jacobien exact, exclu de l'agrégation COP (chiller_r410a_bolt_nodes.json)
Débit de boucle imposé à la frontière BrineSource/BrineSink m_flow_kg_s (= Vd_fixed=true de BOLT)

3. Peut-on bâtir des modèles aussi complexes que Modelica ?

Oui pour le domaine visé, avec des réserves. Entropyk reproduit les idées qui font la puissance des bibliothèques HVAC Modelica :

  • composants basés équations, résolus de façon couplée ;
  • sous-systèmes paramétrés réutilisables ;
  • contrôle supervisoire co-résolu (suivi de consigne + priorité min/max, exactement le style de contrôle chiller « BOLT » référencé dans le code) ;
  • calibration inverse et rating normatif.

On peut assembler des groupes froids / PAC multi-circuits avec pressions émergentes, échangeurs couplés au fluide secondaire, compresseurs à vis avec économiseur, injection liquide, contrôle de pression de refoulement, free-cooling et un arbre de contrôle supervisoire — d'une complexité structurelle comparable à un modèle chiller Modelica.

4. Écarts vs Modelica (précis)

  • Régime permanent uniquement — pas d'intégration temporelle, pas de der(x), pas d'états dynamiques (masses thermiques, retards capteurs). Tout vise F(x)=0.
  • Pas de gestion d'événements — pas de zero-crossing / reinit ; ModeSwitch (hystérésis, durée min) est hors du Newton et basé sur le temps.
  • Connecteurs causaux par arête — l'état est porté par les arêtes/branches en (ṁ,P,h) ; la continuité est imposée par des résidus composants référençant des indices d'état (motif type TESPy), pas des connecteurs acausaux Modelica à variables partagées.
  • Hiérarchie surtout compile-time / aplatie — la CLI aplatit les sous-systèmes avant résolution ; l'imbrication dans le solveur passe par MacroComponent (Rust), dont la continuité ṁ aux ports est incomplète.
  • thermal_couplings transfère une puissance mesurée, pas une loi UA·ΔT — le mode physique ferme Q = η·duty_hot (la puissance ε-NTU du composant chaud) dans un récepteur ThermalLoad ; le champ ua ne sert pas de conductance de couplage. Pour un échangeur d'interface UA·LMTD réellement à deux flux, utiliser un HeatExchanger/BPHX à deux flux ou un flux secondaire. Les entrées legacy sans hot_component/cold_component sont inertes (Q épinglé à 0, la CLI avertit).
  • Fluides CLI limités à CoolProp/Test (Tabular/Incompressible existent dans la lib mais ne sont pas branchés à la CLI).
  • Pas d'équations utilisateur arbitraires — tout nouveau comportement nécessite d'implémenter le trait Component en Rust.

5. Verdict en une phrase

Entropyk se rapproche d'un solveur de cycles steady-state type TESPy/BOLT avec contrôle supervisoire algébrique co-résolu et calibration inverse, plutôt que d'un moteur DAE Modelica généraliste : excellente parité structurelle pour les cycles CVC/réfrigération, mais sans transitoire, sans événements, ni connecteurs acausaux au niveau langage.


Component catalog / Catalogue des composants

See per-component bilingual documentation in docs/components/. Voir la documentation bilingue par composant dans docs/components/.