Entropyk/bindings/python/examples/complete_thermodynamic_system.py

222 lines
7.3 KiB
Python

import entropyk
import math
def build_complete_system():
# ── 1. Initialisation du graphe du système ──
system = entropyk.System()
print("Construction du système Entropyk complet...")
# Paramètres fluides
refrigerant = "R410A"
water = "Water"
# =========================================================================
# BOUCLE 1 : CIRCUIT FRIGORIFIQUE (REFRIGERANT R410A)
# =========================================================================
# 1.1 Compresseur (Modèle Polynomial AHRI 540)
compressor = system.add_component(entropyk.Compressor(
m1=0.85, m2=2.5, m3=500.0, m4=1500.0, m5=-2.5, m6=1.8, m7=600.0, m8=1600.0, m9=-3.0, m10=2.0,
speed_rpm=3600.0,
displacement=0.00008,
efficiency=0.88,
fluid=refrigerant
))
# 1.2 Tuyau de refoulement (vers condenseur)
pipe_hot = system.add_component(entropyk.Pipe(
length=5.0,
diameter=0.02,
fluid=refrigerant
))
# 1.3 Condenseur (Rejet de chaleur)
condenser = system.add_component(entropyk.Condenser(
ua=4500.0,
fluid=refrigerant,
water_temp=30.0, # Température d'entrée côté eau/air
water_flow=2.0
))
# 1.4 Ligne liquide
pipe_liquid = system.add_component(entropyk.Pipe(
length=10.0,
diameter=0.015,
fluid=refrigerant
))
# 1.5 Division du débit (FlowSplitter) vers 2 évaporateurs
splitter = system.add_component(entropyk.FlowSplitter(n_outlets=2))
# 1.6 Branche A : Détendeur + Évaporateur 1
exv_a = system.add_component(entropyk.ExpansionValve(fluid=refrigerant, opening=0.5))
evap_a = system.add_component(entropyk.Evaporator(
ua=2000.0,
fluid=refrigerant,
water_temp=12.0,
water_flow=1.0
))
# 1.7 Branche B : Détendeur + Évaporateur 2
exv_b = system.add_component(entropyk.ExpansionValve(fluid=refrigerant, opening=0.5))
evap_b = system.add_component(entropyk.Evaporator(
ua=2000.0,
fluid=refrigerant,
water_temp=15.0, # Température d'eau légèrement différente
water_flow=1.0
))
# 1.8 Fusion du débit (FlowMerger)
merger = system.add_component(entropyk.FlowMerger(n_inlets=2))
# 1.9 Tuyau d'aspiration (retour compresseur)
pipe_suction = system.add_component(entropyk.Pipe(
length=5.0,
diameter=0.025,
fluid=refrigerant
))
# --- Connexions de la boucle frigo ---
system.add_edge(compressor, pipe_hot)
system.add_edge(pipe_hot, condenser)
system.add_edge(condenser, pipe_liquid)
# Splitter
system.add_edge(pipe_liquid, splitter)
system.add_edge(splitter, exv_a)
system.add_edge(splitter, exv_b)
# Branches parallèles
system.add_edge(exv_a, evap_a)
system.add_edge(exv_b, evap_b)
# Merger
system.add_edge(evap_a, merger)
system.add_edge(evap_b, merger)
system.add_edge(merger, pipe_suction)
system.add_edge(pipe_suction, compressor)
# =========================================================================
# BOUCLE 2 : CIRCUIT RÉSEAU HYDRAULIQUE (EAU - Côté Évaporateur Principal)
# (Juste de la tuyauterie et une pompe pour montrer les FlowSource/FlowSink)
# =========================================================================
water_source = system.add_component(entropyk.FlowSource(
fluid=water,
pressure_pa=101325.0, # 1 atm
temperature_k=285.15 # 12 °C
))
water_pump = system.add_component(entropyk.Pump(
pressure_rise_pa=50000.0, # 0.5 bar
efficiency=0.6
))
water_pipe = system.add_component(entropyk.Pipe(
length=20.0,
diameter=0.05,
fluid=water
))
water_sink = system.add_component(entropyk.FlowSink())
# --- Connexions Hydrauliques Principales ---
system.add_edge(water_source, water_pump)
system.add_edge(water_pump, water_pipe)
system.add_edge(water_pipe, water_sink)
# =========================================================================
# BOUCLE 3 : CIRCUIT VENTILATION (AIR - Côté Condenseur)
# =========================================================================
air_source = system.add_component(entropyk.FlowSource(
fluid="Air",
pressure_pa=101325.0,
temperature_k=308.15 # 35 °C d'air ambiant
))
condenser_fan = system.add_component(entropyk.Fan(
pressure_rise_pa=200.0, # 200 Pa de montée en pression par le ventilo
efficiency=0.5
))
air_sink = system.add_component(entropyk.FlowSink())
# --- Connexions Ventilation ---
system.add_edge(air_source, condenser_fan)
system.add_edge(condenser_fan, air_sink)
# ── 4. Finalisation du système ──
print("Finalisation du graphe (Construction de la topologie)...")
system.finalize()
print(f"Propriétés du système : {system.node_count} composants, {system.edge_count} connexions.")
print(f"Taille du vecteur d'état mathématique : {system.state_vector_len} variables.")
return system
def solve_system(system):
# ── 5. Configuration Avancée du Solveur (Story 6-6) ──
print("\nConfiguration de la stratégie de résolution...")
# (Optionnel) Critères de convergence fins
convergence = entropyk.ConvergenceCriteria(
pressure_tolerance_pa=5.0,
mass_balance_tolerance_kgs=1e-6,
energy_balance_tolerance_w=1e-3
)
# (Optionnel) Jacobian Freezing pour aller plus vite
freezing = entropyk.JacobianFreezingConfig(
max_frozen_iters=4,
threshold=0.1
)
# Configuration Newton avec tolérances avancées
newton_config = entropyk.NewtonConfig(
max_iterations=150,
tolerance=1e-5,
line_search=True,
use_numerical_jacobian=True,
jacobian_freezing=freezing,
convergence_criteria=convergence,
initial_state=[1000000.0, 450000.0] * 17
)
# Configuration Picard robuste en cas d'échec de Newton
picard_config = entropyk.PicardConfig(
max_iterations=500,
tolerance=1e-4,
relaxation=0.4,
convergence_criteria=convergence
)
# ── 6. Lancement du calcul ──
print("Lancement de la simulation (Newton uniquement)...")
try:
result = newton_config.solve(system)
status = result.status
print(f"\n✅ Simulation terminée avec succès !")
print(f"Statut : {status}")
print(f"Itérations : {result.iterations}")
print(f"Résidu final : {result.final_residual:.2e}")
# Le résultat contient le vecteur d'état complet
state_vec = result.state_vector
print(f"Aperçu des 5 premières variables d'état : {state_vec[:5]}")
except entropyk.TimeoutError:
print("\n❌ Le solveur a dépassé le temps imparti (Timeout).")
except entropyk.SolverError as e:
print(f"\n❌ Erreur du solveur : {e}")
print("Note: Ce comportement peut arriver si les paramètres (taille des tuyaux, coeffs, températures)")
print("dépassent le domaine thermodynamique du fluide ou si le graphe manque de contraintes aux limites.")
if __name__ == "__main__":
system = build_complete_system()
solve_system(system)