Entropyk/bindings/python/complete_thermodynamic_system.ipynb

619 lines
24 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Entropyk — Système Thermodynamique Complet avec Vraies Équations\n",
"\n",
"Ce notebook présente un **système frigorifique réaliste** avec:\n",
"\n",
"- **Vrais composants thermodynamiques** utilisant CoolProp\n",
"- **Circuit frigorigène** complet\n",
"- **Circuits eau** côté condenseur et évaporateur\n",
"- **Contrôle inverse** pour surchauffe/sous-refroidissement"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import entropyk\n",
"import numpy as np\n",
"\n",
"print(\"=== ENTROPYK - SYSTÈME THERMODYNAMIQUE AVEC VRAIES ÉQUATIONS ===\\n\")\n",
"print(\"Composants disponibles:\")\n",
"print([x for x in dir(entropyk) if not x.startswith('_')])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 1. CRÉATION DES COMPOSANTS AVEC PARAMÈTRES RÉELS"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# === Paramètres du système ===\n",
"\n",
"FLUID = \"R134a\"\n",
"\n",
"# Condenseur: eau à 30°C, débit 0.5 kg/s\n",
"COND_WATER_TEMP = 30.0 # °C\n",
"COND_WATER_FLOW = 0.5 # kg/s\n",
"COND_UA = 8000.0 # W/K\n",
"\n",
"# Évaporateur: eau à 12°C, débit 0.4 kg/s\n",
"EVAP_WATER_TEMP = 12.0 # °C\n",
"EVAP_WATER_FLOW = 0.4 # kg/s\n",
"EVAP_UA = 6000.0 # W/K\n",
"\n",
"# Compresseur\n",
"COMP_SPEED = 3000.0 # RPM\n",
"COMP_DISP = 0.0001 # m³/rev (100 cc)\n",
"COMP_EFF = 0.85 # Rendement\n",
"\n",
"print(\"Paramètres définis:\")\n",
"print(f\" Fluide: {FLUID}\")\n",
"print(f\" Condenseur: UA={COND_UA} W/K, eau={COND_WATER_TEMP}°C @ {COND_WATER_FLOW} kg/s\")\n",
"print(f\" Évaporateur: UA={EVAP_UA} W/K, eau={EVAP_WATER_TEMP}°C @ {EVAP_WATER_FLOW} kg/s\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 2. CIRCUIT FRIGORIGÈNE\n",
"\n",
"```\n",
" ┌─────────────────────────────────────────────────────────┐\n",
" │ CIRCUIT R134a │\n",
" │ │\n",
" │ [COMP] ──→ [COND] ──→ [EXV] ──→ [EVAP] ──→ [COMP] │\n",
" │ │\n",
" └─────────────────────────────────────────────────────────┘\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CIRCUIT FRIGORIGÈNE ===\\n\")\n",
"\n",
"# Créer le système\n",
"system = entropyk.System()\n",
"\n",
"# Compresseur avec coefficients AHRI 540\n",
"comp = entropyk.Compressor(\n",
" m1=0.85, m2=2.5, # Flow coefficients\n",
" m3=500.0, m4=1500.0, m5=-2.5, m6=1.8, # Power (cooling)\n",
" m7=600.0, m8=1600.0, m9=-3.0, m10=2.0, # Power (heating)\n",
" speed_rpm=COMP_SPEED,\n",
" displacement=COMP_DISP,\n",
" efficiency=COMP_EFF,\n",
" fluid=FLUID\n",
")\n",
"comp_idx = system.add_component(comp)\n",
"print(f\"1. Compresseur: {comp}\")\n",
"\n",
"# Condenseur avec eau côté tube\n",
"cond = entropyk.Condenser(\n",
" ua=COND_UA,\n",
" fluid=FLUID,\n",
" water_temp=COND_WATER_TEMP,\n",
" water_flow=COND_WATER_FLOW\n",
")\n",
"cond_idx = system.add_component(cond)\n",
"print(f\"2. Condenseur: {cond}\")\n",
"\n",
"# Vanne d'expansion\n",
"exv = entropyk.ExpansionValve(\n",
" fluid=FLUID,\n",
" opening=0.6\n",
")\n",
"exv_idx = system.add_component(exv)\n",
"print(f\"3. EXV: {exv}\")\n",
"\n",
"# Évaporateur avec eau côté tube\n",
"evap = entropyk.Evaporator(\n",
" ua=EVAP_UA,\n",
" fluid=FLUID,\n",
" water_temp=EVAP_WATER_TEMP,\n",
" water_flow=EVAP_WATER_FLOW\n",
")\n",
"evap_idx = system.add_component(evap)\n",
"print(f\"4. Évaporateur: {evap}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CONNEXIONS CYCLE FRIGO ===\\n\")\n",
"\n",
"# Connecter le cycle frigorigène\n",
"system.add_edge(comp_idx, cond_idx) # Comp → Cond (HP)\n",
"system.add_edge(cond_idx, exv_idx) # Cond → EXV\n",
"system.add_edge(exv_idx, evap_idx) # EXV → Evap (BP)\n",
"system.add_edge(evap_idx, comp_idx) # Evap → Comp\n",
"\n",
"print(\"Cycle frigorigène connecté: Comp → Cond → EXV → Evap → Comp\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 3. CIRCUITS EAU"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CIRCUIT EAU CONDENSEUR ===\\n\")\n",
"\n",
"# Source eau condenseur (30°C, 1 bar)\n",
"cond_water_in = entropyk.FlowSource(\n",
" pressure_pa=100000.0,\n",
" temperature_k=273.15 + COND_WATER_TEMP,\n",
" fluid=\"Water\"\n",
")\n",
"cond_in_idx = system.add_component(cond_water_in)\n",
"print(f\"Source eau cond: {cond_water_in}\")\n",
"\n",
"# Sink eau condenseur\n",
"cond_water_out = entropyk.FlowSink()\n",
"cond_out_idx = system.add_component(cond_water_out)\n",
"print(f\"Sink eau cond: {cond_water_out}\")\n",
"\n",
"# Connexions\n",
"system.add_edge(cond_in_idx, cond_idx)\n",
"system.add_edge(cond_idx, cond_out_idx)\n",
"\n",
"print(f\"\\nCircuit eau cond: Source({COND_WATER_TEMP}°C) → Condenseur → Sink\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CIRCUIT EAU ÉVAPORATEUR ===\\n\")\n",
"\n",
"# Source eau évaporateur (12°C, 1 bar)\n",
"evap_water_in = entropyk.FlowSource(\n",
" pressure_pa=100000.0,\n",
" temperature_k=273.15 + EVAP_WATER_TEMP,\n",
" fluid=\"Water\"\n",
")\n",
"evap_in_idx = system.add_component(evap_water_in)\n",
"print(f\"Source eau evap: {evap_water_in}\")\n",
"\n",
"# Sink eau évaporateur\n",
"evap_water_out = entropyk.FlowSink()\n",
"evap_out_idx = system.add_component(evap_water_out)\n",
"print(f\"Sink eau evap: {evap_water_out}\")\n",
"\n",
"# Connexions\n",
"system.add_edge(evap_in_idx, evap_idx)\n",
"system.add_edge(evap_idx, evap_out_idx)\n",
"\n",
"print(f\"\\nCircuit eau evap: Source({EVAP_WATER_TEMP}°C) → Évaporateur → Sink\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 4. CONTRÔLE INVERSE"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== ENREGISTREMENT NOMS ===\\n\")\n",
"\n",
"system.register_component_name(\"compressor\", comp_idx)\n",
"system.register_component_name(\"condenser\", cond_idx)\n",
"system.register_component_name(\"evaporator\", evap_idx)\n",
"system.register_component_name(\"exv\", exv_idx)\n",
"\n",
"print(\"Noms enregistrés: compressor, condenser, evaporator, exv\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CONTRAINTES DE CONTRÔLE ===\\n\")\n",
"\n",
"# Contrainte: Superheat = 5K\n",
"sh_constraint = entropyk.Constraint.superheat(\n",
" id=\"sh_5k\",\n",
" component_id=\"evaporator\",\n",
" target_value=5.0,\n",
" tolerance=1e-4\n",
")\n",
"system.add_constraint(sh_constraint)\n",
"print(f\"1. Surchauffe: {sh_constraint}\")\n",
"\n",
"# Contrainte: Subcooling = 3K\n",
"sc_constraint = entropyk.Constraint.subcooling(\n",
" id=\"sc_3k\",\n",
" component_id=\"condenser\",\n",
" target_value=3.0,\n",
" tolerance=1e-4\n",
")\n",
"system.add_constraint(sc_constraint)\n",
"print(f\"2. Sous-refroidissement: {sc_constraint}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== VARIABLES DE CONTRÔLE ===\\n\")\n",
"\n",
"# EXV opening (10% - 100%)\n",
"exv_var = entropyk.BoundedVariable(\n",
" id=\"exv_opening\",\n",
" value=0.6,\n",
" min=0.1,\n",
" max=1.0,\n",
" component_id=\"exv\"\n",
")\n",
"system.add_bounded_variable(exv_var)\n",
"print(f\"1. EXV: {exv_var}\")\n",
"\n",
"# Compressor speed (1500 - 6000 RPM)\n",
"speed_var = entropyk.BoundedVariable(\n",
" id=\"comp_speed\",\n",
" value=3000.0,\n",
" min=1500.0,\n",
" max=6000.0,\n",
" component_id=\"compressor\"\n",
")\n",
"system.add_bounded_variable(speed_var)\n",
"print(f\"2. Vitesse: {speed_var}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== LIENS CONTRAINTES → VARIABLES ===\\n\")\n",
"\n",
"system.link_constraint_to_control(\"sh_5k\", \"exv_opening\")\n",
"print(\"1. Superheat → EXV opening\")\n",
"\n",
"system.link_constraint_to_control(\"sc_3k\", \"comp_speed\")\n",
"print(\"2. Subcooling → Compressor speed\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 5. FINALISATION ET RÉSOLUTION"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== FINALISATION ===\\n\")\n",
"\n",
"system.finalize()\n",
"\n",
"print(f\"Système finalisé:\")\n",
"print(f\" Composants: {system.node_count}\")\n",
"print(f\" Connexions: {system.edge_count}\")\n",
"print(f\" Variables d'état: {system.state_vector_len}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== CONFIGURATION SOLVEUR ===\\n\")\n",
"\n",
"# Newton avec line search\n",
"newton = entropyk.NewtonConfig(\n",
" max_iterations=500,\n",
" tolerance=1e-8,\n",
" line_search=True,\n",
" timeout_ms=60000\n",
")\n",
"print(f\"Newton: {newton}\")\n",
"\n",
"# Picard en backup\n",
"picard = entropyk.PicardConfig(\n",
" max_iterations=1000,\n",
" tolerance=1e-6,\n",
" relaxation=0.3\n",
")\n",
"print(f\"Picard: {picard}\")\n",
"\n",
"# Fallback\n",
"solver = entropyk.FallbackConfig(newton=newton, picard=picard)\n",
"print(f\"\\nSolver: {solver}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== RÉSOLUTION ===\\n\")\n",
"\n",
"try:\n",
" result = solver.solve(system)\n",
" \n",
" print(f\"✅ RÉSULTAT:\")\n",
" print(f\" Itérations: {result.iterations}\")\n",
" print(f\" Résidu: {result.final_residual:.2e}\")\n",
" print(f\" Statut: {result.status}\")\n",
" print(f\" Convergé: {result.is_converged}\")\n",
" \n",
" # State vector\n",
" state = result.to_numpy()\n",
" print(f\"\\n State vector: {state.shape}\")\n",
" print(f\" Valeurs: min={state.min():.2f}, max={state.max():.2f}\")\n",
" \n",
" if result.status == \"ControlSaturation\":\n",
" print(\"\\n ⚠️ Saturation de contrôle - variable à la borne\")\n",
" \n",
"except entropyk.SolverError as e:\n",
" print(f\"❌ SolverError: {e}\")\n",
" \n",
"except entropyk.TimeoutError as e:\n",
" print(f\"⏱️ TimeoutError: {e}\")\n",
" \n",
"except Exception as e:\n",
" print(f\"❌ Erreur: {type(e).__name__}: {e}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 6. TESTS AVEC DIFFÉRENTS FLUIDES"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== TEST MULTI-FLUIDES ===\\n\")\n",
"\n",
"fluids = [\n",
" (\"R134a\", 12.0, 30.0), # T_cond_in, T_evap_in\n",
" (\"R32\", 12.0, 30.0),\n",
" (\"R290\", 12.0, 30.0), # Propane\n",
" (\"R744\", 12.0, 30.0), # CO2\n",
" (\"R1234yf\", 12.0, 30.0), # HFO\n",
"]\n",
"\n",
"for fluid, t_evap, t_cond in fluids:\n",
" try:\n",
" s = entropyk.System()\n",
" \n",
" c = s.add_component(entropyk.Compressor(\n",
" speed_rpm=3000, displacement=0.0001, efficiency=0.85, fluid=fluid\n",
" ))\n",
" cd = s.add_component(entropyk.Condenser(ua=8000, fluid=fluid, water_temp=t_cond, water_flow=0.5))\n",
" ex = s.add_component(entropyk.ExpansionValve(fluid=fluid, opening=0.5))\n",
" ev = s.add_component(entropyk.Evaporator(ua=6000, fluid=fluid, water_temp=t_evap, water_flow=0.4))\n",
" \n",
" s.add_edge(c, cd)\n",
" s.add_edge(cd, ex)\n",
" s.add_edge(ex, ev)\n",
" s.add_edge(ev, c)\n",
" \n",
" # Eau circuits\n",
" cd_in = s.add_component(entropyk.FlowSource(pressure_pa=100000, temperature_k=273.15+t_cond, fluid=\"Water\"))\n",
" cd_out = s.add_component(entropyk.FlowSink())\n",
" ev_in = s.add_component(entropyk.FlowSource(pressure_pa=100000, temperature_k=273.15+t_evap, fluid=\"Water\"))\n",
" ev_out = s.add_component(entropyk.FlowSink())\n",
" \n",
" s.add_edge(cd_in, cd)\n",
" s.add_edge(cd, cd_out)\n",
" s.add_edge(ev_in, ev)\n",
" s.add_edge(ev, ev_out)\n",
" \n",
" s.finalize()\n",
" \n",
" print(f\" {fluid:10s} → ✅ OK ({s.state_vector_len} vars)\")\n",
" \n",
" except Exception as e:\n",
" print(f\" {fluid:10s} → ❌ {e}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 7. TYPES PHYSIQUES"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"=== TYPES PHYSIQUES ===\\n\")\n",
"\n",
"# Pressions cycle R134a typique\n",
"p_hp = entropyk.Pressure(bar=12.0) # HP condensation\n",
"p_bp = entropyk.Pressure(bar=2.0) # BP évaporation\n",
"\n",
"print(f\"Pressions:\")\n",
"print(f\" HP: {p_hp} = {p_hp.to_kpa():.0f} kPa\")\n",
"print(f\" BP: {p_bp} = {p_bp.to_kpa():.0f} kPa\")\n",
"print(f\" Ratio: {p_hp.to_bar()/p_bp.to_bar():.1f}\")\n",
"\n",
"# Températures\n",
"t_cond = entropyk.Temperature(celsius=45.0)\n",
"t_evap = entropyk.Temperature(celsius=-5.0)\n",
"\n",
"print(f\"\\nTempératures:\")\n",
"print(f\" Condensation: {t_cond.to_celsius():.0f}°C = {t_cond.to_kelvin():.2f} K\")\n",
"print(f\" Évaporation: {t_evap.to_celsius():.0f}°C = {t_evap.to_kelvin():.2f} K\")\n",
"\n",
"# Enthalpies\n",
"h_liq = entropyk.Enthalpy(kj_per_kg=250.0)\n",
"h_vap = entropyk.Enthalpy(kj_per_kg=400.0)\n",
"\n",
"print(f\"\\nEnthalpies:\")\n",
"print(f\" Liquide: {h_liq.to_kj_per_kg():.0f} kJ/kg\")\n",
"print(f\" Vapeur: {h_vap.to_kj_per_kg():.0f} kJ/kg\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 8. SCHÉMA DU SYSTÈME COMPLET\n",
"\n",
"```\n",
"╔═══════════════════════════════════════════════════════════════════════════╗\n",
"║ SYSTÈME FRIGORIFIQUE COMPLET ║\n",
"╠═══════════════════════════════════════════════════════════════════════════╣\n",
"║ ║\n",
"║ CIRCUIT EAU CONDENSEUR ║\n",
"║ ┌─────────┐ ┌─────────┐ ║\n",
"║ │ SOURCE │───────[TUBE]────────→│ SINK │ ║\n",
"║ │ 30°C │ ╱╲ │ 35°C │ ║\n",
"║ └─────────┘ ╲ └─────────┘ ║\n",
"║ COND╲ (Échange thermique) ║\n",
"║ HP, 45°C → ╲──────╱ ← Liquide, 40°C ║\n",
"║ ╲ ║\n",
"║ ╲──╱ ║\n",
"║ ║ ║\n",
"║ ┌─────────┐ ║ ┌─────────┐ ┌─────────┐ ║\n",
"║ │ COMP │──────║──────│ COND │──────│ EXV │ ║\n",
"║ │ R134a │ ║ │ │ │ │ ║\n",
"║ └─────────┘ ║ └─────────┘ └─────────┘ ║\n",
"║ ↑ ║ │ ║\n",
"║ │ ║ ↓ ║\n",
"║ │ ║ BP, 5°C ║\n",
"║ │ ║ │ ║\n",
"║ │ ║ ↓ ║\n",
"║ │ ╱╲╱╲ ┌─────────┐ ║\n",
"║ │ EVAP╲ │ │ ║\n",
"║ └────────╲──────╱←────────────────────────────────│ │ ║\n",
"║ Vapeur, 5°C ╲ Vapeur, -5°C (2-phase) └─────────┘ ║\n",
"║ ╲──╱ ║\n",
"║ ╲ (Échange thermique) ║\n",
"║ ╲ ║\n",
"║ CIRCUIT EAU ╱────────╲ ┌─────────┐ ║\n",
"║ ÉVAPORATEUR [TUBE]────→│ SINK │ ║\n",
"║ ┌─────────┐ 7°C │ │ ║\n",
"║ │ SOURCE │──────────→│ │ ║\n",
"║ │ 12°C │ └─────────┘ ║\n",
"║ └─────────┘ ║\n",
"║ ║\n",
"╚═══════════════════════════════════════════════════════════════════════════╝\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"\"\"\n",
"╔══════════════════════════════════════════════════════════════════════════════╗\n",
"║ RÉSUMÉ API ENTROPYK ║\n",
"╠══════════════════════════════════════════════════════════════════════════════╣\n",
"║ ║\n",
"║ COMPOSANTS (avec vraies équations CoolProp) ║\n",
"║ ───────────────────────────────────────────────────────────────────────── ║\n",
"║ Compressor(fluid, speed_rpm, displacement, efficiency, m1-m10) ║\n",
"║ Condenser(ua, fluid, water_temp, water_flow) ← avec circuit eau ║\n",
"║ Evaporator(ua, fluid, water_temp, water_flow) ← avec circuit eau ║\n",
"║ ExpansionValve(fluid, opening) ║\n",
"║ FlowSource(pressure_pa, temperature_k, fluid) ║\n",
"║ FlowSink() ║\n",
"║ ║\n",
"║ CIRCUITS ║\n",
"║ ───────────────────────────────────────────────────────────────────────── ║\n",
"║ system.add_edge(src_idx, tgt_idx) # Connecter composants ║\n",
"║ ║\n",
"║ FLUIDES DISPONIBLES (66+) ║\n",
"║ ───────────────────────────────────────────────────────────────────────── ║\n",
"║ HFC: R134a, R410A, R32, R407C, R125, R143a, R22, etc. ║\n",
"║ HFO: R1234yf, R1234ze(E), R1233zd(E), R1336mzz(E) ║\n",
"║ Naturels: R744 (CO2), R290 (Propane), R600a (Isobutane), R717 (Ammonia) ║\n",
"║ Mélanges: R513A, R454B, R452B, R507A ║\n",
"║ ║\n",
"╚══════════════════════════════════════════════════════════════════════════════╝\n",
"\"\"\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}