5.8 KiB
5.8 KiB
Story 10.3: BrineSource et BrineSink avec Support Glycol
Epic: 10 - Enhanced Boundary Conditions
Priorité: P0-CRITIQUE
Estimation: 3h
Statut: backlog
Dépendances: Story 10-1 (Nouveaux types physiques)
Story
En tant que moteur de simulation thermodynamique,
Je veux queBrineSourceetBrineSinksupportent les mélanges eau-glycol avec concentration,
Afin de pouvoir simuler des circuits de caloporteurs avec propriétés thermophysiques correctes.
Contexte
Les caloporteurs liquides (eau, PEG, MEG, saumures) sont utilisés dans:
- Circuits primaire/secondaire de chillers
- Systèmes de chauffage urbain
- Applications basse température avec protection antigel
La concentration en glycol affecte:
- Viscosité (perte de charge)
- Chaleur massique (capacité thermique)
- Point de congélation (protection antigel)
Spécifications Techniques
BrineSource
/// Source pour fluides caloporteurs liquides (eau, PEG, MEG, saumures).
///
/// Impose une température et une pression fixées sur le port de sortie.
/// La concentration en glycol est prise en compte pour les propriétés.
#[derive(Debug, Clone)]
pub struct BrineSource {
/// Identifiant du fluide (ex: "Water", "MEG", "PEG")
fluid_id: String,
/// Concentration en glycol (% massique, 0 = eau pure)
concentration: Concentration,
/// Température de set-point [K]
t_set: Temperature,
/// Pression de set-point [Pa]
p_set: Pressure,
/// Enthalpie calculée depuis T et concentration [J/kg]
h_set: Enthalpy,
/// Débit massique optionnel [kg/s]
mass_flow: Option<MassFlow>,
/// Débit volumique optionnel [m³/s]
volume_flow: Option<VolumeFlow>,
/// Port de sortie connecté
outlet: ConnectedPort,
}
impl BrineSource {
/// Crée une source d'eau pure.
pub fn water(
temperature: Temperature,
pressure: Pressure,
outlet: ConnectedPort,
) -> Result<Self, ComponentError>;
/// Crée une source de mélange eau-glycol.
pub fn glycol_mixture(
fluid_id: impl Into<String>,
concentration: Concentration,
temperature: Temperature,
pressure: Pressure,
outlet: ConnectedPort,
) -> Result<Self, ComponentError>;
/// Définit le débit massique imposé.
pub fn set_mass_flow(&mut self, mass_flow: MassFlow);
/// Définit le débit volumique imposé.
/// Le débit massique est calculé avec la masse volumique du mélange.
pub fn set_volume_flow(&mut self, volume_flow: VolumeFlow, density: f64);
}
BrineSink
/// Puits pour fluides caloporteurs liquides.
#[derive(Debug, Clone)]
pub struct BrineSink {
/// Identifiant du fluide
fluid_id: String,
/// Concentration en glycol
concentration: Concentration,
/// Contre-pression [Pa]
p_back: Pressure,
/// Température de retour optionnelle [K]
t_back: Option<Temperature>,
/// Port d'entrée connecté
inlet: ConnectedPort,
}
impl BrineSink {
/// Crée un puits pour eau pure.
pub fn water(
pressure: Pressure,
inlet: ConnectedPort,
) -> Result<Self, ComponentError>;
/// Crée un puits pour mélange eau-glycol.
pub fn glycol_mixture(
fluid_id: impl Into<String>,
concentration: Concentration,
pressure: Pressure,
inlet: ConnectedPort,
) -> Result<Self, ComponentError>;
}
Calcul des Propriétés
Enthalpie depuis Température et Concentration
/// Calcule l'enthalpie d'un mélange eau-glycol.
///
/// Utilise CoolProp avec la syntaxe de mélange:
/// - Eau pure: "Water"
/// - Mélange MEG: "MEG-MASS%" ou "INCOMP::MEG-MASS%"
fn calculate_enthalpy(
fluid_id: &str,
concentration: Concentration,
temperature: Temperature,
pressure: Pressure,
) -> Result<Enthalpy, ComponentError> {
// Pour CoolProp, utiliser:
// PropsSI("H", "T", T, "P", P, fluid_string)
// où fluid_string = format!("INCOMP::{}-{}", fluid_id, concentration.to_percent())
}
Fichiers à Créer/Modifier
| Fichier | Action |
|---|---|
crates/components/src/flow_boundary/brine.rs |
Créer BrineSource, BrineSink |
crates/components/src/flow_boundary/mod.rs |
Ajouter ré-exports |
Critères d'Acceptation
BrineSource::water()crée une source d'eau pureBrineSource::glycol_mixture()crée une source avec concentration- L'enthalpie est calculée correctement depuis T et concentration
BrineSink::water()crée un puits pour eauBrineSink::glycol_mixture()crée un puits avec concentrationenergy_transfers()retourne(Power(0), Power(0))port_enthalpies()retourne[h_set]- Validation de la concentration (0-100%)
- Tests unitaires avec différents pourcentages de glycol
Tests Requis
#[cfg(test)]
mod tests {
#[test]
fn test_brine_source_water() { /* ... */ }
#[test]
fn test_brine_source_meg_30_percent() { /* ... */ }
#[test]
fn test_brine_source_enthalpy_calculation() { /* ... */ }
#[test]
fn test_brine_source_volume_flow_conversion() { /* ... */ }
#[test]
fn test_brine_sink_water() { /* ... */ }
#[test]
fn test_brine_sink_meg_mixture() { /* ... */ }
}
Notes d'Implémentation
Support CoolProp pour Mélanges
CoolProp supporte les mélanges incompressibles via la syntaxe:
INCOMP::MEG-30 // MEG à 30% massique
INCOMP::PEG-40 // PEG à 40% massique
Vérifier que le backend CoolProp utilisé dans le projet supporte cette syntaxe.