chore: sync project state and current artifacts

This commit is contained in:
Sepehr
2026-02-22 23:27:31 +01:00
parent 1b6415776e
commit dd77089b22
232 changed files with 37056 additions and 4296 deletions

View File

@@ -0,0 +1,221 @@
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)

View File

@@ -0,0 +1,87 @@
"""
Cycle frigorifique simple R134a - 4 composants
Compresseur → Condenseur → Détendeur → Évaporateur → (retour)
Équations des composants mock (python_components.rs) :
Compresseur : r[0] = p_disc - (p_suc + 1 MPa) r[1] = h_disc - (h_suc + power/m_dot)
Condenseur : r[0] = p_out - p_in r[1] = h_out - (h_in - 225 kJ/kg)
Détendeur : r[0] = p_out - (p_in - 1 MPa) r[1] = h_out - h_in
Évaporateur : r[0] = p_out - p_in r[1] = h_out - (h_in + 150 kJ/kg)
État initial cohérent : P_HP - P_LP = 1 MPa → tous les résidus de pression valent 0 au départ.
"""
import entropyk
import time
def main():
system = entropyk.System()
print("Construction du système simple (R134a)...")
fluid = "R134a"
comp = 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=fluid
))
cond = system.add_component(entropyk.Condenser(
ua=5000.0, fluid=fluid, water_temp=30.0, water_flow=2.0
))
valve = system.add_component(entropyk.ExpansionValve(
fluid=fluid, opening=0.5 # target_dp = 2e6*(1-0.5) = 1 MPa
))
evap = system.add_component(entropyk.Evaporator(
ua=3000.0, fluid=fluid, water_temp=10.0, water_flow=2.0
))
system.add_edge(comp, cond) # edge 0 : comp → cond
system.add_edge(cond, valve) # edge 1 : cond → valve
system.add_edge(valve, evap) # edge 2 : valve → evap
system.add_edge(evap, comp) # edge 3 : evap → comp
system.finalize()
print(f"Propriétés: {system.node_count} composants, {system.edge_count} connexions, "
f"{system.state_vector_len} variables d'état.")
# ─── État initial cohérent avec les équations mock ───────────────────────
# Valve et Comp utilisent tous les deux target_dp = 1 MPa
# → P_HP - P_LP = 1 MPa ⇒ résidus de pression = 0 dès le départ
# Enthalpies choisies proches de l'équilibre attendu :
# Cond : h_in - 225 kJ/kg = h_out_cond (225 000 J/kg)
# Evap : h_in + 150 kJ/kg = h_out_evap (150 000 J/kg)
# Comp : h_in + w_sp ≈ h_in + 75 kJ/kg (AHRI 540)
P_LP = 350_000.0 # Pa — basse pression (R134a ~1.5°C sat)
P_HP = 1_350_000.0 # Pa — haute pression = P_LP + 1 MPa ✓
initial_state = [
P_HP, 485_000.0, # edge0 comp→cond : vapeur surchauffée HP (≈h_suc + 75 kJ/kg)
P_HP, 260_000.0, # edge1 cond→valve : liquide HP (≈485-225)
P_LP, 260_000.0, # edge2 valve→evap : biphasique BP (isenthalpique)
P_LP, 410_000.0, # edge3 evap→comp : vapeur surchauffée BP (≈260+150)
]
config = entropyk.NewtonConfig(
max_iterations=150,
tolerance=1e-4,
line_search=True,
use_numerical_jacobian=True,
initial_state=initial_state
)
print("Lancement du Newton Solver...")
t0 = time.time()
try:
res = config.solve(system)
elapsed = time.time() - t0
print(f"\n✅ Convergé en {res.iterations} itérations ({elapsed*1000:.1f} ms)")
sv = res.state_vector
print(f"\nÉtat final du cycle R134a :")
print(f" comp → cond : P={sv[0]/1e5:.2f} bar, h={sv[1]/1e3:.1f} kJ/kg")
print(f" cond → valve : P={sv[2]/1e5:.2f} bar, h={sv[3]/1e3:.1f} kJ/kg")
print(f" valve → evap : P={sv[4]/1e5:.2f} bar, h={sv[5]/1e3:.1f} kJ/kg")
print(f" evap → comp : P={sv[6]/1e5:.2f} bar, h={sv[7]/1e3:.1f} kJ/kg")
except Exception as e:
elapsed = time.time() - t0
print(f"\n❌ Échec après {elapsed*1000:.1f} ms : {e}")
if __name__ == "__main__":
main()