Mélangeur, Bouteille flash et Stockage mélangé
Trois primitives de flowsheet du paquet ThermodynamicCycles :
Mélangeur (
Mixer) : réunit \(N\) flux d’un même fluide (bilan masse + énergie) ;Bouteille flash (
FlashTank) : détente à pression imposée et séparation liquide/vapeur saturés ;Stockage mélangé (
Tank.MixedStorage) : ballon monocouche parfaitement mélangé, réponse thermique exponentielle.
Toutes échangent l’information par des FluidPort (attributs fluid, F
en kg/s, P en Pa, h en J/kg).
Mélangeur (ThermodynamicCycles.Mixer)
Rôle
Le modèle ThermodynamicCycles.Mixer.Mixer réunit plusieurs flux d’un même
fluide en un seul flux de sortie, par mélange adiabatique sans perte.
Primitive nécessaire aux réchauffeurs d’eau alimentaire à mélange (cycle de
Rankine régénératif), aux collecteurs, à la cogénération, etc.
Connecteurs
Port |
Type |
Rôle |
|---|---|---|
|
liste de |
flux entrants (2 par défaut via |
|
|
alias pratiques de |
|
|
flux sortant (mélange) |
Un port supplémentaire s’ajoute par add_inlet() (crée le port, l’ajoute à
Inlets et le renvoie). Seuls les flux actifs (F non nul et
\(F > 0\)) participent au calcul ; l’absence de flux actif lève une
ValueError.
Équations
Sur les seuls flux actifs (bilans de masse et enthalpique) :
Le fluide de sortie est celui du premier flux actif. La pression de sortie vaut
la pression imposée si Po_bar est défini, sinon la pression la plus
faible des entrées :
La température de sortie est déduite par CoolProp : \(T_{o} = T(P_{out}, h_{out}) - 273{,}15\) (°C).
Paramètres
Attribut |
Défaut |
Description |
|---|---|---|
|
2 |
nombre de ports d’entrée créés à l’instanciation |
|
|
pression de sortie imposée (bar) ; sinon min des entrées |
|
|
horodatage reporté dans |
Sorties : Outlet (mélange), To (température de sortie, °C) et df
(récapitulatif : fluide, nombre de flux, F_totale_kgs, P_sortie_bar,
T_sortie_degC).
Exemple
from ThermodynamicCycles.Mixer import Mixer
from ThermodynamicCycles.FluidPort.FluidPort import ThermoPropsSI
mix = Mixer.Object(n_inlets=2)
P = 3e5
mix.Inlet1.fluid = "water"
mix.Inlet1.P = P
mix.Inlet1.F = 1.0
mix.Inlet1.h = ThermoPropsSI("H", "P", P, "T", 20 + 273.15, "water")
mix.Inlet2.fluid = "water"
mix.Inlet2.P = P
mix.Inlet2.F = 0.5
mix.Inlet2.h = ThermoPropsSI("H", "P", P, "T", 80 + 273.15, "water")
mix.calculate()
print("Débit total :", round(mix.Outlet.F, 3), "kg/s")
print("T mélange :", round(mix.To, 2), "°C")
Bouteille flash (ThermodynamicCycles.FlashTank)
Rôle
Le modèle ThermodynamicCycles.FlashTank.FlashTank (portage du modèle Modelica
FlashTank_pressureFixed) simule une détente flash à pression imposée. Un
fluide (souvent sous-refroidi ou saturé) entre à \(P_a\), est détendu à
\(P_{flash} < P_a\), produisant un mélange diphasique. Le ballon sépare la
vapeur du liquide, tous deux saturés à \(P_{flash}\).
Connecteurs
Port |
Modelica |
Rôle |
|---|---|---|
|
|
entrée amont (haute pression, liquide en général) |
|
|
vapeur saturée à \(P_{flash}\) |
|
|
liquide saturé à \(P_{flash}\) |
Équations
Enthalpies de saturation à \(P_{flash}\) (CoolProp, \(Q=1\) rosée / \(Q=0\) bulle) :
Bilans de masse et d’énergie (\(m_a = m_b + m_c\), \(m_a h_a = m_b h_b + m_c h_c\)) donnent la fraction vapeur produite par conservation de l’enthalpie, bornée dans \([0, 1]\) :
Débits séparés et chaleur latente libérée par la vapeur produite :
Note
Cas limites gérés par bornage : entrée surchauffée (\(h_a > h_v\)) → \(x = 1\) (tout vapeur) ; entrée sous-refroidie (\(h_a < h_l\)) → \(x = 0\) (pas de flash). Si \(h_v \le h_l\) (hors domaine diphasique), \(x = 0\).
Paramètres
Attribut |
Défaut |
Description |
|---|---|---|
|
|
pression de flash (Pa) ; si |
|
|
horodatage reporté dans |
Sorties : x (fraction vapeur), h_vapor / h_liquid (J/kg),
T_flash_degC, Q_flash_W, les ports Outlet_vapor / Outlet_liquid,
et df (dont F_vapor_kgs, F_liquid_kgs, Q_flash_kW).
Exemple
from ThermodynamicCycles.FlashTank import FlashTank
from ThermodynamicCycles.FluidPort.FluidPort import ThermoPropsSI
flash = FlashTank.Object()
# Eau saturée à 10 bar détendue à 1 bar
P_in = 10e5
flash.Inlet.fluid = "water"
flash.Inlet.P = P_in
flash.Inlet.F = 1.0
flash.Inlet.h = ThermoPropsSI("H", "P", P_in, "Q", 0, "water") # liquide saturé
flash.P_flash = 1e5
flash.calculate()
print("Fraction vapeur x :", round(flash.x, 4))
print("T flash :", round(flash.T_flash_degC, 2), "°C")
print("Débit vapeur :", round(flash.Outlet_vapor.F, 4), "kg/s")
Stockage mélangé (ThermodynamicCycles.Tank.MixedStorage)
Rôle
Le modèle ThermodynamicCycles.Tank.MixedStorage simule un ballon monocouche
parfaitement mélangé (température uniforme) alimenté par un flux, avec pertes
vers l’ambiance. Sur un pas de temps, la température suit une relaxation
exponentielle vers une valeur d’équilibre, solution analytique du bilan
thermique du réservoir agité.
Connecteurs
Port |
Type |
Rôle |
|---|---|---|
|
|
flux entrant (fournit |
|
|
flux sortant, à la température \(T\) du ballon |
En sortie, le débit et la pression sont recopiés de l’entrée
(Outlet.F = Inlet.F, Outlet.P = Inlet.P) ; l’enthalpie sortante est
évaluée à la température du ballon.
Équations
Le débit et la température d’entrée sont lus sur le port : \(m = F_{in}\), \(T_i = T(P, h_{in}) - 273{,}15\). La température d’équilibre (asymptote) et la constante de temps sont :
La température du ballon après un pas \(t\) suit la relaxation exponentielle depuis l’état initial :
L’énergie stockée sur le pas, sa version horaire et le cumul :
Le \(C_p\) est réévalué à la température du ballon (CoolProp,
CPMASS) avant le calcul de l’énergie.
Note
État persistant : en fin de calculate(), Tinit_degC est réaffecté
à la température courante T_degC. Chaque appel enchaîné représente donc le
pas de temps suivant ; cumul_Qstr_kWh accumule l’énergie stockée au fil
des appels.
Paramètres
Attribut |
Défaut |
Description |
|---|---|---|
|
1 m³ |
volume du ballon |
|
1000 kg/m³ |
masse volumique du fluide stocké |
|
4181 J/kg/K |
capacité thermique massique (réévaluée au calcul) |
|
12 °C |
température initiale du ballon (mise à jour à chaque pas) |
|
3600 s |
pas de temps |
|
0 W/m²/K |
coefficient global d’échange vers l’ambiance |
|
3 m² |
surface d’échange vers l’ambiance |
|
12 °C |
température ambiante |
|
|
horodatage reporté dans |
Sorties : T_degC (température du ballon), Qstr_J / Qstr_kWh /
Qstr_kW (énergie et puissance stockées sur le pas), cumul_Qstr_kWh
(énergie cumulée), Outlet et df.
Exemple
from ThermodynamicCycles.Tank import MixedStorage
from ThermodynamicCycles.FluidPort.FluidPort import ThermoPropsSI
tank = MixedStorage.Object()
tank.V = 0.5
tank.Tinit_degC = 15 # ballon initialement à 15 °C
tank.U = 1.0 # pertes actives
tank.Tamb_degC = 12
tank.t = 3600 # 1 h par pas
# Alimentation : eau à 60 °C, 0,05 kg/s
P = 3e5
tank.Inlet.fluid = "water"
tank.Inlet.P = P
tank.Inlet.F = 0.05
tank.Inlet.h = ThermoPropsSI("H", "P", P, "T", 60 + 273.15, "water")
for _ in range(6): # 6 pas horaires successifs
tank.calculate()
print("T ballon :", round(tank.T_degC, 2), "°C")
print("Énergie cumulée :", round(tank.cumul_Qstr_kWh, 3), "kWh")