{ "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 }