4.3 KiB
4.3 KiB
Story 11.2: Drum - Ballon de Recirculation
Epic: 11 - Advanced HVAC Components
Priorité: P0-CRITIQUE
Estimation: 6h
Statut: backlog
Dépendances: Story 11.1 (Node)
Story
En tant qu'ingénieur chiller,
Je veux un composant Drum pour la recirculation d'évaporateur,
Afin de simuler des cycles à évaporateur flooded.
Contexte
Le ballon de recirculation (Drum) est un composant essentiel des évaporateurs flooded. Il reçoit:
- Le flux d'alimentation (feed) depuis l'économiseur
- Le retour de l'évaporateur (mélange enrichi en vapeur)
Et sépare en:
- Liquide saturé (x=0) vers la pompe de recirculation
- Vapeur saturée (x=1) vers le compresseur
Équations Mathématiques
Ports:
in1: Feed (depuis économiseur)
in2: Retour évaporateur (diphasique)
out1: Liquide saturé (x=0)
out2: Vapeur saturée (x=1)
Équations (8):
1. Mélange entrées:
ṁ_total = ṁ_in1 + ṁ_in2
h_mixed = (ṁ_in1·h_in1 + ṁ_in2·h_in2) / ṁ_total
2. Bilan masse:
ṁ_out1 + ṁ_out2 = ṁ_total
3. Bilan énergie:
ṁ_out1·h_out1 + ṁ_out2·h_out2 = ṁ_total·h_mixed
4. Pression out1:
P_out1 - P_in1 = 0
5. Pression out2:
P_out2 - P_in1 = 0
6. Liquide saturé:
h_out1 - h_sat(P, x=0) = 0
7. Vapeur saturée:
h_out2 - h_sat(P, x=1) = 0
8. Continuité fluide (implicite via FluidId)
Fichiers à Créer/Modifier
| Fichier | Action |
|---|---|
crates/components/src/drum.rs |
Créer |
crates/components/src/lib.rs |
Ajouter mod drum; pub use drum::* |
Implémentation
// crates/components/src/drum.rs
use entropyk_core::{Power, Calib};
use entropyk_fluids::{FluidBackend, FluidId};
use crate::{Component, ComponentError, ConnectedPort, JacobianBuilder, ResidualVector, SystemState};
use std::sync::Arc;
/// Drum - Ballon de recirculation pour évaporateurs
#[derive(Debug)]
pub struct Drum {
fluid_id: String,
feed_inlet: ConnectedPort,
evaporator_return: ConnectedPort,
liquid_outlet: ConnectedPort,
vapor_outlet: ConnectedPort,
fluid_backend: Arc<dyn FluidBackend>,
calib: Calib,
}
impl Drum {
pub fn new(
fluid: impl Into<String>,
feed_inlet: ConnectedPort,
evaporator_return: ConnectedPort,
liquid_outlet: ConnectedPort,
vapor_outlet: ConnectedPort,
backend: Arc<dyn FluidBackend>,
) -> Result<Self, ComponentError> {
Ok(Self {
fluid_id: fluid.into(),
feed_inlet,
evaporator_return,
liquid_outlet,
vapor_outlet,
fluid_backend: backend,
calib: Calib::default(),
})
}
/// Ratio de recirculation (m_liquid / m_feed)
pub fn recirculation_ratio(&self, state: &SystemState) -> f64 {
let m_liquid = self.liquid_outlet.mass_flow().to_kg_per_s();
let m_feed = self.feed_inlet.mass_flow().to_kg_per_s();
if m_feed > 0.0 { m_liquid / m_feed } else { 0.0 }
}
}
impl Component for Drum {
fn n_equations(&self) -> usize { 8 }
fn compute_residuals(
&self,
state: &SystemState,
residuals: &mut ResidualVector,
) -> Result<(), ComponentError> {
// ... implémentation complète
Ok(())
}
fn energy_transfers(&self, _state: &SystemState) -> Option<(Power, Power)> {
Some((Power::from_watts(0.0), Power::from_watts(0.0)))
}
}
Critères d'Acceptation
Drum::n_equations()retourne8- Liquide outlet est saturé (x=0)
- Vapeur outlet est saturée (x=1)
- Bilan masse satisfait
- Bilan énergie satisfait
- Pressions égales sur tous les ports
recirculation_ratio()retourne m_liq/m_feed- Validation: fluide pur requis
Tests Requis
#[test]
fn test_drum_equations_count() {
assert_eq!(drum.n_equations(), 8);
}
#[test]
fn test_drum_saturated_outlets() {
// Vérifier h_liq = h_sat(x=0), h_vap = h_sat(x=1)
}
#[test]
fn test_drum_mass_balance() {
// m_liq + m_vap = m_feed + m_return
}
#[test]
fn test_drum_recirculation_ratio() {
// ratio = m_liq / m_feed
}
Références
- Epic 11 Technical Specifications
- TESPy
tespy/components/nodes/drum.py