{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Entropyk — Fluid Properties & Refrigerants Guide\n", "\n", "Ce notebook présente les **66+ fluides disponibles** dans Entropyk via CoolProp, incluant:\n", "\n", "- **HFC** : R134a, R410A, R407C, R32, R125, R143a, R152A, R22, etc.\n", "- **HFO (Low-GWP)** : R1234yf, R1234ze(E), R1233zd(E), R1243zf, R1336mzz(E)\n", "- **Alternatives** : R513A, R454B, R452B\n", "- **Naturels** : R744 (CO2), R290 (Propane), R600a (Isobutane), R717 (Ammonia), R1270 (Propylene)\n", "- **Autres** : Water, Air, Nitrogen, Oxygen, Helium, Hydrogen, etc." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import entropyk\n", "import numpy as np\n", "import pandas as pd\n", "\n", "pd.set_option('display.max_rows', 80)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Types Physiques de Base\n", "\n", "Entropyk fournit des types forts pour les unités physiques avec conversion automatique." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Pression - plusieurs unités supportées\n", "p1 = entropyk.Pressure(bar=12.0)\n", "p2 = entropyk.Pressure(kpa=350.0)\n", "p3 = entropyk.Pressure(psi=150.0)\n", "\n", "print(\"Pression:\")\n", "print(f\" {p1} → {p1.to_bar():.2f} bar, {p1.to_kpa():.1f} kPa, {p1.to_psi():.1f} psi\")\n", "print(f\" {p2} → {p2.to_bar():.2f} bar\")\n", "print(f\" {p3} → {p3.to_bar():.2f} bar\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Température\n", "t1 = entropyk.Temperature(celsius=45.0)\n", "t2 = entropyk.Temperature(kelvin=273.15)\n", "t3 = entropyk.Temperature(fahrenheit=100.0)\n", "\n", "print(\"Température:\")\n", "print(f\" {t1} → {t1.to_celsius():.2f}°C, {t1.to_fahrenheit():.2f}°F\")\n", "print(f\" {t2} → {t2.to_celsius():.2f}°C (point de congélation)\")\n", "print(f\" {t3} → {t3.to_celsius():.2f}°C, {t3.to_kelvin():.2f} K\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Enthalpie\n", "h1 = entropyk.Enthalpy(kj_per_kg=420.0)\n", "h2 = entropyk.Enthalpy(j_per_kg=250000.0)\n", "\n", "print(\"Enthalpie:\")\n", "print(f\" {h1} → {h1.to_kj_per_kg():.1f} kJ/kg\")\n", "print(f\" {h2} → {h2.to_kj_per_kg():.1f} kJ/kg\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Débit massique\n", "m1 = entropyk.MassFlow(kg_per_s=0.05)\n", "m2 = entropyk.MassFlow(g_per_s=50.0)\n", "\n", "print(\"Débit massique:\")\n", "print(f\" {m1} → {m1.to_g_per_s():.1f} g/s\")\n", "print(f\" {m2} → {m2.to_kg_per_s():.4f} kg/s\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Cycle Simple avec Différents Fluides\n", "\n", "Construisons un cycle de réfrigération standard et comparons différents fluides." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def build_simple_cycle(fluid: str):\n", " \"\"\"Construit un cycle de réfrigération simple avec le fluide spécifié.\"\"\"\n", " system = entropyk.System()\n", " \n", " # Composants\n", " comp = entropyk.Compressor(\n", " speed_rpm=2900.0,\n", " displacement=0.0001,\n", " efficiency=0.85,\n", " fluid=fluid\n", " )\n", " cond = entropyk.Condenser(ua=5000.0)\n", " exv = entropyk.ExpansionValve(fluid=fluid, opening=0.8)\n", " evap = entropyk.Evaporator(ua=3000.0)\n", " \n", " # Ajouter au système\n", " comp_idx = system.add_component(comp)\n", " cond_idx = system.add_component(cond)\n", " exv_idx = system.add_component(exv)\n", " evap_idx = system.add_component(evap)\n", " \n", " # Connecter en cycle\n", " system.add_edge(comp_idx, cond_idx)\n", " system.add_edge(cond_idx, exv_idx)\n", " system.add_edge(exv_idx, evap_idx)\n", " system.add_edge(evap_idx, comp_idx)\n", " \n", " system.finalize()\n", " return system" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Test avec différents fluides HFC classiques\n", "hfc_fluids = [\"R134a\", \"R410A\", \"R407C\", \"R32\"]\n", "\n", "print(\"Cycles HFC classiques:\")\n", "print(\"-\" * 50)\n", "for fluid in hfc_fluids:\n", " system = build_simple_cycle(fluid)\n", " print(f\" {fluid:8s} → {system.state_vector_len} variables d'état\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Fluides HFO / Low-GWP\n", "\n", "Les HFO sont les alternatives à faible GWP (<150) pour remplacer les HFC." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# HFO et alternatives Low-GWP\n", "low_gwp_fluids = [\n", " (\"R1234yf\", \"HFO\", \"<1\", \"Remplacement R134a (automobile)\"),\n", " (\"R1234ze(E)\", \"HFO\", \"<1\", \"Remplacement R134a (stationnaire)\"),\n", " (\"R1233zd(E)\", \"HCFO\", \"1\", \"Remplacement R123 (basse pression)\"),\n", " (\"R1243zf\", \"HFO\", \"<1\", \"Nouveau fluide recherche\"),\n", " (\"R1336mzz(E)\", \"HFO\", \"<1\", \"ORC, haute température\"),\n", " (\"R513A\", \"Mélange\", \"631\", \"R134a + R1234yf (56/44)\"),\n", " (\"R454B\", \"Mélange\", \"146\", \"R32 + R1234yf (50/50) - Opteon XL41\"),\n", " (\"R452B\", \"Mélange\", \"676\", \"R32 + R125 + R1234yf - Opteon XL55\"),\n", "]\n", "\n", "df_low_gwp = pd.DataFrame(low_gwp_fluids, columns=[\"Fluide\", \"Type\", \"GWP\", \"Usage\"])\n", "df_low_gwp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Test cycles HFO\n", "print(\"Cycles HFO / Low-GWP:\")\n", "print(\"-\" * 50)\n", "for fluid, _, _, _ in low_gwp_fluids:\n", " try:\n", " system = build_simple_cycle(fluid)\n", " print(f\" {fluid:12s} → ✅ Supporté ({system.state_vector_len} vars)\")\n", " except Exception as e:\n", " print(f\" {fluid:12s} → ❌ Erreur: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Fluides Naturels\n", "\n", "Les fluides naturels ont un GWP de ~0 et sont l'avenir de la réfrigération." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Fluides naturels\n", "natural_fluids = [\n", " (\"R744\", \"CO2\", \"1\", \"Transcritique, commercial\"),\n", " (\"R290\", \"Propane\", \"3\", \"Climatisation, commercial\"),\n", " (\"R600a\", \"Isobutane\", \"3\", \"Domestique, commerc. faible charge\"),\n", " (\"R600\", \"Butane\", \"3\", \"Réfrigération basse température\"),\n", " (\"R1270\", \"Propylène\", \"3\", \"Climatisation industrielle\"),\n", " (\"R717\", \"Ammonia\", \"0\", \"Industriel, forte puissance\"),\n", "]\n", "\n", "df_natural = pd.DataFrame(natural_fluids, columns=[\"Code ASHRAE\", \"Nom\", \"GWP\", \"Application\"])\n", "df_natural" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Test cycles fluides naturels\n", "print(\"Cycles fluides naturels:\")\n", "print(\"-\" * 50)\n", "for code, name, _, app in natural_fluids:\n", " try:\n", " system = build_simple_cycle(code)\n", " print(f\" {code:6s} ({name:10s}) → ✅ Supporté\")\n", " except Exception as e:\n", " print(f\" {code:6s} ({name:10s}) → ❌ Erreur: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Autres Réfrigérants (Classiques)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Autres réfrigérants disponibles\n", "other_refrigerants = [\n", " # CFC (obsolètes)\n", " \"R11\", \"R12\", \"R13\", \"R14\",\n", " # HCFC (phase-out)\n", " \"R22\", \"R123\", \"R141b\", \"R142b\",\n", " # HFC supplémentaires\n", " \"R23\", \"R41\", \"R113\", \"R114\", \"R115\", \"R116\",\n", " \"R124\", \"R143a\", \"R152A\", \"R218\", \"R227EA\",\n", " \"R236EA\", \"R236FA\", \"R245fa\", \"R245ca\", \"R365MFC\",\n", " \"RC318\", \"R507A\",\n", "]\n", "\n", "print(f\"Total réfrigérants classiques: {len(other_refrigerants)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. Fluides Non-Réfrigérants" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Fluides non-réfrigérants disponibles\n", "other_fluids = [\n", " (\"Water\", \"H2O\", \"Fluide de travail, calibration\"),\n", " (\"Air\", \"N2+O2\", \"Climatisation, psychrométrie\"),\n", " (\"Nitrogen\", \"N2\", \"Cryogénie, inertage\"),\n", " (\"Oxygen\", \"O2\", \"Applications spéciales\"),\n", " (\"Argon\", \"Ar\", \"Cryogénie\"),\n", " (\"Helium\", \"He\", \"Cryogénie très basse T\"),\n", " (\"Hydrogen\", \"H2\", \"Énergie, cryogénie\"),\n", " (\"Methane\", \"CH4\", \"GNL, pétrole\"),\n", " (\"Ethane\", \"C2H6\", \"Pétrochimie\"),\n", " (\"Ethylene\", \"C2H4\", \"Pétrochimie\"),\n", " (\"Propane\", \"C3H8\", \"= R290\"),\n", " (\"Butane\", \"C4H10\", \"= R600\"),\n", " (\"Ethanol\", \"C2H5OH\",\"Solvant\"),\n", " (\"Methanol\", \"CH3OH\", \"Solvant\"),\n", " (\"Acetone\", \"C3H6O\", \"Solvant\"),\n", " (\"Benzene\", \"C6H6\", \"Chimie\"),\n", " (\"Toluene\", \"C7H8\", \"ORC\"),\n", "]\n", "\n", "df_other = pd.DataFrame(other_fluids, columns=[\"Nom CoolProp\", \"Formule\", \"Usage\"])\n", "df_other" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7. Résumé Complet des Fluides Disponibles" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Catégorisation complète\n", "fluid_summary = {\n", " \"Catégorie\": [\n", " \"HFC Classiques\",\n", " \"HFO / Low-GWP\",\n", " \"Alternatives (Mélanges)\",\n", " \"Fluides Naturels\",\n", " \"CFC/HCFC (Obsolètes)\",\n", " \"Autres HFC\",\n", " \"Non-Réfrigérants\",\n", " ],\n", " \"Exemples\": [\n", " \"R134a, R410A, R407C, R32, R125\",\n", " \"R1234yf, R1234ze(E), R1233zd(E)\",\n", " \"R513A, R454B, R452B, R507A\",\n", " \"R744 (CO2), R290, R600a, R717\",\n", " \"R11, R12, R22, R123, R141b\",\n", " \"R143a, R152A, R227EA, R245fa\",\n", " \"Water, Air, Nitrogen, Helium\",\n", " ],\n", " \"Nombre\": [5, 6, 4, 6, 8, 15, 17],\n", "}\n", "\n", "df_summary = pd.DataFrame(fluid_summary)\n", "print(\"\\n=== RÉSUMÉ DES FLUIDES DISPONIBLES ===\")\n", "print(f\"Total: {sum(fluid_summary['Nombre'])}+ fluides\\n\")\n", "df_summary" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8. Exemple: Cycle CO2 Transcritique\n", "\n", "Le CO2 (R744) nécessite un traitement spécial car le point critique est à 31°C seulement." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Cycle CO2 transcritique\n", "print(\"=== Cycle CO2 Transcritique (R744) ===\")\n", "print(\"\\nPropriétés du CO2:\")\n", "print(\" Point critique: 31.0°C, 73.8 bar\")\n", "print(\" GWP: 1\")\n", "print(\" Applications: Supermarchés, transports, chaleur industrielle\")\n", "\n", "co2_system = build_simple_cycle(\"R744\")\n", "print(f\"\\nSystème créé: {co2_system.state_vector_len} variables d'état\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9. Exemple: Cycle Ammoniac (R717)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Cycle Ammoniac\n", "print(\"=== Cycle Ammoniac (R717) ===\")\n", "print(\"\\nPropriétés de l'Ammoniac:\")\n", "print(\" Point critique: 132.4°C, 113.3 bar\")\n", "print(\" GWP: 0 (naturel)\")\n", "print(\" haute efficacité, toxique mais détectable\")\n", "print(\" Applications: Industrie agroalimentaire, patinoires, entrepôts\")\n", "\n", "nh3_system = build_simple_cycle(\"R717\")\n", "print(f\"\\nSystème créé: {nh3_system.state_vector_len} variables d'état\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 10. Exemple: Cycle Propane (R290)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Cycle Propane\n", "print(\"=== Cycle Propane (R290) ===\")\n", "print(\"\\nPropriétés du Propane:\")\n", "print(\" Point critique: 96.7°C, 42.5 bar\")\n", "print(\" GWP: 3 (très bas)\")\n", "print(\" Excellentes propriétés thermodynamiques\")\n", "print(\" Inflammable (A3)\")\n", "print(\" Applications: Climatisation, pompes à chaleur, commercial\")\n", "\n", "r290_system = build_simple_cycle(\"R290\")\n", "print(f\"\\nSystème créé: {r290_system.state_vector_len} variables d'état\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 11. Configuration du Solveur" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Exemple de configuration du solveur pour résolution\n", "system = build_simple_cycle(\"R134a\")\n", "\n", "# Newton-Raphson avec recherche linéaire\n", "newton = entropyk.NewtonConfig(\n", " max_iterations=200,\n", " tolerance=1e-6,\n", " line_search=True,\n", " timeout_ms=10000\n", ")\n", "\n", "# Picard pour problèmes difficiles\n", "picard = entropyk.PicardConfig(\n", " max_iterations=500,\n", " tolerance=1e-4,\n", " relaxation=0.5\n", ")\n", "\n", "# Fallback: Newton puis Picard\n", "fallback = entropyk.FallbackConfig(newton=newton, picard=picard)\n", "\n", "print(f\"Solver configuré: {fallback}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 12. Conclusion\n", "\n", "### Fluides disponibles par application:\n", "\n", "| Application | Fluide recommandé | Alternatives |\n", "|-------------|-------------------|-------------|\n", "| Climatisation résidentielle | R32, R290 | R410A, R454B |\n", "| Climatisation commerciale | R410A, R32 | R454B, R290 |\n", "| Réfrigération commerciale | R404A, R744 | R455A, R290 |\n", "| Froid industriel | R717, R744 | R290 |\n", "| Domestique | R600a, R290 | R134a |\n", "| Automobile | R1234yf | R134a, R744 |\n", "| ORC haute température | R1336mzz(E), Toluene | R245fa |" ] } ], "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 }