chore: sync project state and current artifacts
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
# 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:
|
||||
1. Le flux d'alimentation (feed) depuis l'économiseur
|
||||
2. Le retour de l'évaporateur (mélange enrichi en vapeur)
|
||||
|
||||
Et sépare en:
|
||||
1. Liquide saturé (x=0) vers la pompe de recirculation
|
||||
2. 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
|
||||
|
||||
```rust
|
||||
// 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()` retourne `8`
|
||||
- [ ] 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
|
||||
|
||||
```rust
|
||||
#[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](../planning-artifacts/epic-11-technical-specifications.md)
|
||||
- TESPy `tespy/components/nodes/drum.py`
|
||||
Reference in New Issue
Block a user