643 lines
21 KiB
Markdown
643 lines
21 KiB
Markdown
# Exemple Détaillé : Chiller Air-Glycol 2 Circuits avec Screw Économisé + MCHX
|
||
|
||
## Vue d'ensemble
|
||
|
||
Ce document détaille la conception et l'implémentation d'un chiller air-glycol complet dans Entropyk, incluant:
|
||
|
||
- **2 circuits réfrigérants** indépendants
|
||
- **Compresseurs Screw économisés** avec contrôle VFD (25–60 Hz)
|
||
- **Condenseurs MCHX** (Microchannel Heat Exchanger) à air ambiant (35°C)
|
||
- **Évaporateurs flooded** avec eau glycolée MEG 35% (entrée 12°C, sortie 7°C)
|
||
|
||
---
|
||
|
||
## 1. Architecture du Système
|
||
|
||
### 1.1 Topologie par Circuit
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ CIRCUIT N (×2) │
|
||
│ │
|
||
│ BrineSource(MEG35%, 12°C) │
|
||
│ ↓ │
|
||
│ ┌─────────────────┐ │
|
||
│ │ FloodedEvaporator│ ←── Drum ←── Economizer(flash) │
|
||
│ └────────┬────────┘ ↑ │
|
||
│ │ │ │
|
||
│ ↓ │ │
|
||
│ ┌─────────────────────────────┐ │ │
|
||
│ │ ScrewEconomizerCompressor │────────┘ │
|
||
│ │ (suction, discharge, eco) │ │
|
||
│ └────────────┬────────────────┘ │
|
||
│ │ │
|
||
│ ↓ │
|
||
│ ┌────────────────────┐ │
|
||
│ │ FlowSplitter (1→2) │ │
|
||
│ └────────┬───────────┘ │
|
||
│ │ │
|
||
│ ┌─────┴─────┐ │
|
||
│ ↓ ↓ │
|
||
│ ┌─────────┐ ┌─────────┐ │
|
||
│ │MchxCoil │ │MchxCoil │ ← 2 coils par circuit │
|
||
│ │ +Fan │ │ +Fan │ (4 coils total pour 2 circuits) │
|
||
│ └────┬────┘ └────┬────┘ │
|
||
│ │ │ │
|
||
│ └─────┬─────┘ │
|
||
│ ↓ │
|
||
│ ┌────────────────────┐ │
|
||
│ │ FlowMerger (2→1) │ │
|
||
│ └────────┬───────────┘ │
|
||
│ │ │
|
||
│ ↓ │
|
||
│ ┌────────────────────┐ │
|
||
│ │ ExpansionValve │ │
|
||
│ └────────┬───────────┘ │
|
||
│ │ │
|
||
│ ↓ │
|
||
│ BrineSink(MEG35%, 7°C) │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 1.2 Spécifications Techniques
|
||
|
||
| Paramètre | Valeur | Unité |
|
||
|-----------|--------|-------|
|
||
| Réfrigérant | R134a | - |
|
||
| Nombre de circuits | 2 | - |
|
||
| Capacité nominale | 400 | kW |
|
||
| Air ambiant | 35 | °C |
|
||
| Entrée glycol | 12 | °C |
|
||
| Sortie glycol | 7 | °C |
|
||
| Type glycol | MEG 35% | - |
|
||
| Condenseurs | 4 × MCHX | 15 kW/K chacun |
|
||
| Compresseurs | 2 × Screw économisé | ~200 kW/circuit |
|
||
| VFD | 25–60 | Hz |
|
||
|
||
---
|
||
|
||
## 2. Composants Principaux
|
||
|
||
### 2.1 ScrewEconomizerCompressor
|
||
|
||
#### 2.1.1 Description Physique
|
||
|
||
Un compresseur à vis avec port d'injection économiseur opère en deux étages de compression internes:
|
||
|
||
```
|
||
Stage 1:
|
||
Suction (P_evap, h_suc) → compression vers P_intermediate
|
||
|
||
Injection Intermédiaire:
|
||
Flash-gas depuis l'économiseur à (P_eco, h_eco) s'injecte dans les lobes
|
||
du rotor à la pression intermédiaire. Ceci refroidit le gaz comprimé et
|
||
augmente le débit total délivré au stage 2.
|
||
|
||
Stage 2:
|
||
Gaz mélangé (P_intermediate, h_mix) → compression vers P_discharge
|
||
|
||
Résultat net:
|
||
- Capacité supérieure vs. simple mono-étage (~10-20%)
|
||
- Meilleur COP (~8-15%) pour mêmes températures condensation/évaporation
|
||
- Gamme de fonctionnement étendue (ratios compression plus élevés)
|
||
```
|
||
|
||
#### 2.1.2 Ports (3 total)
|
||
|
||
| Port | Type | Description |
|
||
|------|------|-------------|
|
||
| `port_suction` | Entrée | Fluide basse pression depuis évaporateur/drum |
|
||
| `port_discharge` | Sortie | Fluide haute pression vers condenseur |
|
||
| `port_economizer` | Entrée | Injection flash-gas à pression intermédiaire |
|
||
|
||
#### 2.1.3 Variables d'État (5 total)
|
||
|
||
| Index | Variable | Unité | Description |
|
||
|-------|----------|-------|-------------|
|
||
| 0 | `ṁ_suction` | kg/s | Débit massique aspiration |
|
||
| 1 | `ṁ_eco` | kg/s | Débit massique économiseur |
|
||
| 2 | `h_suction` | J/kg | Enthalpie aspiration |
|
||
| 3 | `h_discharge` | J/kg | Enthalpie refoulement |
|
||
| 4 | `W_shaft` | W | Puissance arbre |
|
||
|
||
#### 2.1.4 Équations (5 total)
|
||
|
||
```rust
|
||
// Équation 1: Débit aspiration (courbe fabricant)
|
||
r[0] = ṁ_suc_calc(SST, SDT) × (freq/50) - ṁ_suction_state
|
||
|
||
// Équation 2: Débit économiseur
|
||
r[1] = x_eco × ṁ_suction - ṁ_eco_state
|
||
|
||
// Équation 3: Bilan énergétique (adiabatique)
|
||
// ṁ_suc × h_suc + ṁ_eco × h_eco + W/η = ṁ_total × h_dis
|
||
let ṁ_total = ṁ_suc + ṁ_eco;
|
||
r[2] = ṁ_suc × h_suc + ṁ_eco × h_eco + W/η_mech - ṁ_total × h_dis
|
||
|
||
// Équation 4: Pression économiseur (moyenne géométrique)
|
||
r[3] = P_eco - sqrt(P_suc × P_dis)
|
||
|
||
// Équation 5: Puissance (courbe fabricant)
|
||
r[4] = W_calc(SST, SDT) × (freq/50) - W_state
|
||
```
|
||
|
||
#### 2.1.5 Courbes de Performance
|
||
|
||
```rust
|
||
// Exemple: ~200 kW screw R134a à 50 Hz
|
||
// SST reference: +3°C = 276.15 K
|
||
// SDT reference: +50°C = 323.15 K
|
||
|
||
fn make_screw_curves() -> ScrewPerformanceCurves {
|
||
ScrewPerformanceCurves::with_fixed_eco_fraction(
|
||
// ṁ_suc [kg/s] = 1.20 + 0.003×(SST-276) - 0.002×(SDT-323) + 1e-5×(SST-276)×(SDT-323)
|
||
Polynomial2D::bilinear(1.20, 0.003, -0.002, 0.000_01),
|
||
// W [W] = 55000 + 200×(SST-276) - 300×(SDT-323) + 0.5×...
|
||
Polynomial2D::bilinear(55_000.0, 200.0, -300.0, 0.5),
|
||
0.12, // 12% fraction économiseur
|
||
)
|
||
}
|
||
```
|
||
|
||
#### 2.1.6 Contrôle VFD
|
||
|
||
```rust
|
||
// Le ratio de fréquence affecte linéairement le débit
|
||
let frequency_ratio = frequency_hz / nominal_frequency_hz; // ex: 40/50 = 0.8
|
||
|
||
// Scaling:
|
||
// ṁ_suc ∝ frequency_ratio
|
||
// W ∝ frequency_ratio
|
||
// x_eco = constant (géométrie fixe)
|
||
|
||
comp.set_frequency_hz(40.0).unwrap();
|
||
assert!((comp.frequency_ratio() - 0.8).abs() < 1e-10);
|
||
```
|
||
|
||
#### 2.1.7 Création du Composant
|
||
|
||
```rust
|
||
use entropyk_components::{ScrewEconomizerCompressor, ScrewPerformanceCurves, Polynomial2D};
|
||
use entropyk_components::port::{Port, FluidId};
|
||
use entropyk_core::{Pressure, Enthalpy};
|
||
|
||
// Créer les 3 ports connectés
|
||
let suc = make_port("R134a", 3.2, 400.0); // P=3.2 bar, h=400 kJ/kg
|
||
let dis = make_port("R134a", 12.8, 440.0); // P=12.8 bar, h=440 kJ/kg
|
||
let eco = make_port("R134a", 6.4, 260.0); // P=6.4 bar (intermédiaire)
|
||
|
||
let comp = ScrewEconomizerCompressor::new(
|
||
make_screw_curves(),
|
||
"R134a",
|
||
50.0, // fréquence nominale
|
||
0.92, // rendement mécanique
|
||
suc,
|
||
dis,
|
||
eco,
|
||
).expect("compressor creation ok");
|
||
|
||
assert_eq!(comp.n_equations(), 5);
|
||
```
|
||
|
||
---
|
||
|
||
### 2.2 MchxCondenserCoil
|
||
|
||
#### 2.2.1 Description Physique
|
||
|
||
Un MCHX (Microchannel Heat Exchanger) utilise des tubes plats en aluminium extrudé multi-port avec une structure d'ailettes louvrées. Comparé aux condenseurs conventionnels (RTPF):
|
||
|
||
| Propriété | RTPF | MCHX |
|
||
|-----------|------|------|
|
||
| UA côté air | Base | +30–60% par m² |
|
||
| Charge réfrigérant | Base | −25–40% |
|
||
| Perte de charge air | Base | Similaire |
|
||
| Poids | Base | −30% |
|
||
| Sensibilité distribution air | Moins | Plus |
|
||
|
||
#### 2.2.2 Modèle UA Variable
|
||
|
||
```text
|
||
UA_eff = UA_nominal × (ρ_air / ρ_ref)^0.5 × (fan_speed)^n_air
|
||
|
||
où:
|
||
ρ_air = densité air à T_amb [kg/m³]
|
||
ρ_ref = densité air de référence (1.12 kg/m³ à 35°C)
|
||
n_air = 0.5 (ASHRAE louvered fins)
|
||
```
|
||
|
||
#### 2.2.3 Effet de la Vitesse Ventilateur
|
||
|
||
```rust
|
||
// À 100% vitesse ventilateur
|
||
coil.set_fan_speed_ratio(1.0);
|
||
let ua_100 = coil.ua_effective(); // = UA_nominal
|
||
|
||
// À 70% vitesse
|
||
coil.set_fan_speed_ratio(0.70);
|
||
let ua_70 = coil.ua_effective();
|
||
// UA_70 ≈ UA_nom × √0.70 ≈ UA_nom × 0.837
|
||
|
||
// À 60% vitesse
|
||
coil.set_fan_speed_ratio(0.60);
|
||
let ua_60 = coil.ua_effective();
|
||
// UA_60 ≈ UA_nom × √0.60 ≈ UA_nom × 0.775
|
||
```
|
||
|
||
#### 2.2.4 Effet de la Température Ambiante
|
||
|
||
```rust
|
||
// À 35°C (design)
|
||
let coil_35 = MchxCondenserCoil::for_35c_ambient(15_000.0, 0);
|
||
let ua_35 = coil_35.ua_effective();
|
||
|
||
// À 45°C (ambiante élevée)
|
||
let mut coil_45 = MchxCondenserCoil::for_35c_ambient(15_000.0, 0);
|
||
coil_45.set_air_temperature_celsius(45.0);
|
||
let ua_45 = coil_45.ua_effective();
|
||
|
||
// UA diminue avec la température (densité air diminue)
|
||
// Ratio ≈ ρ(45°C)/ρ(35°C) ≈ 1.109/1.12 ≈ 0.99
|
||
assert!(ua_45 < ua_35);
|
||
```
|
||
|
||
#### 2.2.5 Création d'une Banque de 4 Coils
|
||
|
||
```rust
|
||
// 4 coils, 15 kW/K chacun
|
||
let coils: Vec<MchxCondenserCoil> = (0..4)
|
||
.map(|i| MchxCondenserCoil::for_35c_ambient(15_000.0, i))
|
||
.collect();
|
||
|
||
let total_ua: f64 = coils.iter().map(|c| c.ua_effective()).sum();
|
||
// ≈ 60 kW/K total
|
||
|
||
// Simulation anti-override: réduire coil 0 à 70%
|
||
coils[0].set_fan_speed_ratio(0.70);
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 FloodedEvaporator
|
||
|
||
#### 2.3.1 Description
|
||
|
||
L'évaporateur noyé (flooded) maintient un niveau de liquide constant dans la calandre. Le réfrigérant bout à la surface des tubes où circule le fluide secondaire (eau glycolée).
|
||
|
||
#### 2.3.2 Configuration JSON
|
||
|
||
```json
|
||
{
|
||
"type": "FloodedEvaporator",
|
||
"name": "evap_0",
|
||
"ua": 20000.0,
|
||
"refrigerant": "R134a",
|
||
"secondary_fluid": "MEG",
|
||
"target_quality": 0.7
|
||
}
|
||
```
|
||
|
||
#### 2.3.3 Bilan Énergétique
|
||
|
||
```text
|
||
Q_evap = ṁ_ref × (h_out - h_in) (côté réfrigérant)
|
||
Q_evap = ṁ_brine × Cp_brine × ΔT_brine (côté secondaire)
|
||
|
||
où:
|
||
ṁ_brine = débit glycol MEG 35% [kg/s]
|
||
Cp_brine ≈ 3.6 kJ/(kg·K) à 10°C
|
||
ΔT_brine = T_in - T_out = 12 - 7 = 5 K
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Configuration JSON Complète
|
||
|
||
### 3.1 Structure du Fichier
|
||
|
||
```json
|
||
{
|
||
"name": "Chiller Air-Glycol 2 Circuits",
|
||
"description": "Machine frigorifique 2 circuits indépendants",
|
||
"fluid": "R134a",
|
||
|
||
"circuits": [
|
||
{
|
||
"id": 0,
|
||
"components": [ ... ],
|
||
"edges": [ ... ]
|
||
},
|
||
{
|
||
"id": 1,
|
||
"components": [ ... ],
|
||
"edges": [ ... ]
|
||
}
|
||
],
|
||
|
||
"solver": {
|
||
"strategy": "fallback",
|
||
"max_iterations": 150,
|
||
"tolerance": 1e-6
|
||
},
|
||
|
||
"metadata": { ... }
|
||
}
|
||
```
|
||
|
||
### 3.2 Circuit 0 Détaillé
|
||
|
||
```json
|
||
{
|
||
"id": 0,
|
||
"components": [
|
||
{
|
||
"type": "ScrewEconomizerCompressor",
|
||
"name": "screw_0",
|
||
"fluid": "R134a",
|
||
"nominal_frequency_hz": 50.0,
|
||
"mechanical_efficiency": 0.92,
|
||
"economizer_fraction": 0.12,
|
||
"mf_a00": 1.20, "mf_a10": 0.003, "mf_a01": -0.002, "mf_a11": 0.00001,
|
||
"pw_b00": 55000.0, "pw_b10": 200.0, "pw_b01": -300.0, "pw_b11": 0.5,
|
||
"p_suction_bar": 3.2, "h_suction_kj_kg": 400.0,
|
||
"p_discharge_bar": 12.8, "h_discharge_kj_kg": 440.0,
|
||
"p_eco_bar": 6.4, "h_eco_kj_kg": 260.0
|
||
},
|
||
{
|
||
"type": "MchxCondenserCoil",
|
||
"name": "mchx_0a",
|
||
"ua": 15000.0,
|
||
"coil_index": 0,
|
||
"n_air": 0.5,
|
||
"t_air_celsius": 35.0,
|
||
"fan_speed_ratio": 1.0
|
||
},
|
||
{
|
||
"type": "MchxCondenserCoil",
|
||
"name": "mchx_0b",
|
||
"ua": 15000.0,
|
||
"coil_index": 1,
|
||
"n_air": 0.5,
|
||
"t_air_celsius": 35.0,
|
||
"fan_speed_ratio": 1.0
|
||
},
|
||
{
|
||
"type": "Placeholder",
|
||
"name": "exv_0",
|
||
"n_equations": 2
|
||
},
|
||
{
|
||
"type": "FloodedEvaporator",
|
||
"name": "evap_0",
|
||
"ua": 20000.0,
|
||
"refrigerant": "R134a",
|
||
"secondary_fluid": "MEG",
|
||
"target_quality": 0.7
|
||
}
|
||
],
|
||
"edges": [
|
||
{ "from": "screw_0:outlet", "to": "mchx_0a:inlet" },
|
||
{ "from": "mchx_0a:outlet", "to": "mchx_0b:inlet" },
|
||
{ "from": "mchx_0b:outlet", "to": "exv_0:inlet" },
|
||
{ "from": "exv_0:outlet", "to": "evap_0:inlet" },
|
||
{ "from": "evap_0:outlet", "to": "screw_0:inlet" }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Tests d'Intégration
|
||
|
||
### 4.1 Test: Création Screw + Residuals
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_screw_compressor_creation_and_residuals() {
|
||
let suc = make_port("R134a", 3.2, 400.0);
|
||
let dis = make_port("R134a", 12.8, 440.0);
|
||
let eco = make_port("R134a", 6.4, 260.0);
|
||
|
||
let comp = ScrewEconomizerCompressor::new(
|
||
make_screw_curves(), "R134a", 50.0, 0.92, suc, dis, eco
|
||
).expect("compressor creation ok");
|
||
|
||
assert_eq!(comp.n_equations(), 5);
|
||
|
||
// État plausible
|
||
let state = vec![1.2, 0.144, 400_000.0, 440_000.0, 55_000.0];
|
||
let mut residuals = vec![0.0; 5];
|
||
comp.compute_residuals(&state, &mut residuals).expect("ok");
|
||
|
||
// Tous résiduals finis
|
||
for (i, r) in residuals.iter().enumerate() {
|
||
assert!(r.is_finite(), "residual[{}] not finite", i);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 Test: VFD Scaling
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_screw_vfd_scaling() {
|
||
let mut comp = /* ... */;
|
||
|
||
// Pleine vitesse (50 Hz)
|
||
let state_full = vec![1.2, 0.144, 400_000.0, 440_000.0, 55_000.0];
|
||
comp.compute_residuals(&state_full, &mut r_full).unwrap();
|
||
|
||
// 80% vitesse (40 Hz)
|
||
comp.set_frequency_hz(40.0).unwrap();
|
||
assert!((comp.frequency_ratio() - 0.8).abs() < 1e-10);
|
||
|
||
let state_reduced = vec![0.96, 0.115, 400_000.0, 440_000.0, 44_000.0];
|
||
comp.compute_residuals(&state_reduced, &mut r_reduced).unwrap();
|
||
}
|
||
```
|
||
|
||
### 4.3 Test: MCHX UA Correction
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_mchx_ua_correction_with_fan_speed() {
|
||
let mut coil = MchxCondenserCoil::for_35c_ambient(15_000.0, 0);
|
||
|
||
// 100% → UA nominal
|
||
let ua_100 = coil.ua_effective();
|
||
|
||
// 70% → UA × √0.7
|
||
coil.set_fan_speed_ratio(0.70);
|
||
let ua_70 = coil.ua_effective();
|
||
|
||
let expected_ratio = 0.70_f64.sqrt();
|
||
let actual_ratio = ua_70 / ua_100;
|
||
|
||
assert!((actual_ratio - expected_ratio).abs() < 0.02);
|
||
}
|
||
```
|
||
|
||
### 4.4 Test: Topologie 2 Circuits
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_two_circuit_chiller_topology() {
|
||
let mut sys = System::new();
|
||
|
||
// Circuit 0
|
||
let comp0 = /* screw compressor */;
|
||
let comp0_node = sys.add_component_to_circuit(
|
||
Box::new(comp0), CircuitId::ZERO
|
||
).expect("add comp0");
|
||
|
||
// 2 coils pour circuit 0
|
||
for i in 0..2 {
|
||
let coil = MchxCondenserCoil::for_35c_ambient(15_000.0, i);
|
||
let coil_node = sys.add_component_to_circuit(
|
||
Box::new(coil), CircuitId::ZERO
|
||
).expect("add coil");
|
||
sys.add_edge(comp0_node, coil_node).expect("edge");
|
||
}
|
||
|
||
// Circuit 1 (similaire)
|
||
// ...
|
||
|
||
assert_eq!(sys.circuit_count(), 2);
|
||
sys.finalize().expect("finalize should succeed");
|
||
}
|
||
```
|
||
|
||
### 4.5 Test: Anti-Override Ventilateur
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_fan_anti_override_speed_reduction() {
|
||
let mut coil = MchxCondenserCoil::for_35c_ambient(15_000.0, 0);
|
||
|
||
let ua_100 = coil.ua_effective();
|
||
coil.set_fan_speed_ratio(0.80);
|
||
let ua_80 = coil.ua_effective();
|
||
coil.set_fan_speed_ratio(0.60);
|
||
let ua_60 = coil.ua_effective();
|
||
|
||
// UA décroît avec la vitesse ventilateur
|
||
assert!(ua_100 > ua_80);
|
||
assert!(ua_80 > ua_60);
|
||
|
||
// Suit loi puissance: UA ∝ speed^0.5
|
||
assert!((ua_80/ua_100 - 0.80_f64.sqrt()).abs() < 0.03);
|
||
assert!((ua_60/ua_100 - 0.60_f64.sqrt()).abs() < 0.03);
|
||
}
|
||
```
|
||
|
||
### 4.6 Test: Bilan Énergétique Screw
|
||
|
||
```rust
|
||
#[test]
|
||
fn test_screw_energy_balance() {
|
||
let comp = /* screw avec ports P_suc=3.2, P_dis=12.8, P_eco=6.4 */;
|
||
|
||
let m_suc = 1.2;
|
||
let m_eco = 0.144;
|
||
let h_suc = 400_000.0;
|
||
let h_dis = 440_000.0;
|
||
let h_eco = 260_000.0;
|
||
let eta_mech = 0.92;
|
||
|
||
// W ferme le bilan énergétique:
|
||
// m_suc × h_suc + m_eco × h_eco + W/η = (m_suc + m_eco) × h_dis
|
||
let w_expected = ((m_suc + m_eco) * h_dis - m_suc * h_suc - m_eco * h_eco) * eta_mech;
|
||
|
||
let state = vec![m_suc, m_eco, h_suc, h_dis, w_expected];
|
||
let mut residuals = vec![0.0; 5];
|
||
comp.compute_residuals(&state, &mut residuals).unwrap();
|
||
|
||
// residual[2] = bilan énergétique ≈ 0
|
||
assert!(residuals[2].abs() < 1.0);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Fichiers Sources
|
||
|
||
| Fichier | Description |
|
||
|---------|-------------|
|
||
| `crates/components/src/screw_economizer_compressor.rs` | Implémentation ScrewEconomizerCompressor |
|
||
| `crates/components/src/heat_exchanger/mchx_condenser_coil.rs` | Implémentation MchxCondenserCoil |
|
||
| `crates/solver/tests/chiller_air_glycol_integration.rs` | Tests d'intégration (10 tests) |
|
||
| `crates/cli/examples/chiller_screw_mchx_2circuits.json` | Config JSON complète 2 circuits |
|
||
| `crates/cli/examples/chiller_screw_mchx_validate.json` | Config validation 1 circuit |
|
||
|
||
---
|
||
|
||
## 6. Commandes CLI
|
||
|
||
### Validation de Configuration
|
||
|
||
```bash
|
||
# Valider le JSON sans lancer la simulation
|
||
entropyk-cli validate --config chiller_screw_mchx_2circuits.json
|
||
```
|
||
|
||
### Lancement de Simulation
|
||
|
||
```bash
|
||
# Avec backend test (développement)
|
||
entropyk-cli run --config chiller_screw_mchx_2circuits.json --backend test
|
||
|
||
# Avec backend tabular (R134a built-in)
|
||
entropyk-cli run --config chiller_screw_mchx_2circuits.json --backend tabular
|
||
|
||
# Avec CoolProp (si disponible)
|
||
entropyk-cli run --config chiller_screw_mchx_2circuits.json --backend coolprop
|
||
```
|
||
|
||
### Output JSON
|
||
|
||
```bash
|
||
entropyk-cli run --config chiller_screw_mchx_2circuits.json --output results.json
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Références
|
||
|
||
### 7.1 Standards et Corrélations
|
||
|
||
- **ASHRAE Handbook** — Chapitre 4: Heat Transfer (corrélation louvered fins, n=0.5)
|
||
- **AHRI Standard 540** — Performance Rating of Positive Displacement Refrigerant Compressors
|
||
- **Bitzer Technical Documentation** — Screw compressor curves (HSK/CSH series)
|
||
|
||
### 7.2 Stories Connexes
|
||
|
||
| Story | Description |
|
||
|-------|-------------|
|
||
| 11-3 | FloodedEvaporator implémentation |
|
||
| 12-1 | CLI internal state variables |
|
||
| 12-2 | CLI CoolProp backend |
|
||
| 12-3 | CLI Screw compressor config |
|
||
| 12-4 | CLI MCHX config |
|
||
| 12-5 | CLI FloodedEvaporator + Brine |
|
||
| 12-6 | CLI Controls (SH, VFD, fan) |
|
||
|
||
---
|
||
|
||
## 8. Points d'Attention
|
||
|
||
### 8.1 État Actuel (Limitations)
|
||
|
||
1. **Backend TestBackend** — La CLI utilise `TestBackend` qui retourne des zéros. Nécessite CoolProp ou TabularBackend pour des simulations réelles (Story 12.2).
|
||
|
||
2. **Variables d'État Internes** — Le solveur peut retourner "State dimension mismatch" si les composants complexes ne déclarent pas correctement `internal_state_len()` (Story 12.1).
|
||
|
||
3. **Port Économiseur** — Dans la config CLI actuelle, le port économiseur du Screw n'est pas connecté à un composant économiseur séparé. Le modèle utilise une fraction fixe (Story 12.3).
|
||
|
||
### 8.2 Prochaines Étapes
|
||
|
||
1. Implémenter Story 12.1 (variables internes) pour résoudre le mismatch state/equations
|
||
2. Implémenter Story 12.2 (CoolProp backend) pour des propriétés thermodynamiques réelles
|
||
3. Ajouter les contrôles (Story 12.6) pour surchauffe cible et VFD
|
||
4. Valider la convergence sur un point de fonctionnement nominal
|