//! Ventilasjon og infiltrasjon. use crate::modell::lost::Lost; use crate::modell::{Skjerming, VentilasjonType}; /// Infiltrasjonsluftmengde, m³/h, etter NS-EN 15242 slik NS 3031 anvender den: /// /// `n_inf = n50 · e / (1 + (f/e) · ((q_til − q_fra) / (V · n50))²)` /// /// `e` er skjermingskoeffisienten og `f` en anleggskoeffisient. Ved balansert ventilasjon /// faller ubalanseleddet bort, og infiltrasjonen blir `n50 · e`. pub fn infiltrasjonsluftmengde(l: &Lost) -> f64 { let e = match l.skjerming { Skjerming::Skjermet => 0.03, Skjerming::Moderat => 0.07, Skjerming::Utsatt => 0.10, }; let f = 15.0; let v = l.volum; let q_snitt = l.ventilasjon.luftmengde * l.bra; let (q_til, q_fra) = match l.ventilasjon.typ { VentilasjonType::Balansert => (q_snitt, q_snitt), VentilasjonType::Avtrekk => (0.0, q_snitt), VentilasjonType::Naturlig => (0.0, 0.0), }; let ubalanse = (q_til - q_fra).abs(); let nevner = if l.n50 * v > 1e-9 { 1.0 + (f / e) * (ubalanse / (v * l.n50)).powi(2) } else { 1.0 }; let n_inf = l.n50 * e / nevner; n_inf * v } /// Om ventilasjonen går med driftsluftmengde i time `t` av året. pub fn i_drift(l: &Lost, t: usize) -> bool { l.laster.driftsdag(t) && l.ventilasjon.driftstid.aktiv(t % 24) } /// Ventilasjonsluftmengde i time `t` av året, m³/h. pub fn luftmengde(l: &Lost, t: usize) -> f64 { let spesifikk = if i_drift(l, t) { l.ventilasjon.luftmengde } else { l.ventilasjon.luftmengde_natt }; spesifikk * l.bra } /// Tilluftstemperatur etter varmegjenvinner (uten ettervarming), °C. /// /// Gjenvinneren reguleres ned når den ellers ville varmet tilluften over settpunktet, slik /// en roterende gjenvinner med turtallsregulering eller et omløpsspjeld gjør. Når det er /// varmere ute enn inne, kjøler gjenvinneren tilluften og går for fullt. pub fn tilluftstemperatur(l: &Lost, t_ute: f64, t_avtrekk: f64) -> f64 { match l.ventilasjon.typ { VentilasjonType::Balansert => { let gjenvunnet = t_ute + l.ventilasjon.gjenvinning * (t_avtrekk - t_ute); if gjenvunnet > t_ute { gjenvunnet.min(l.ventilasjon.tilluft_settpunkt.max(t_ute)) } else { gjenvunnet } } _ => t_ute, } } /// Vifteeffekt i time `t` av året, W. pub fn vifteeffekt(l: &Lost, t: usize) -> f64 { if matches!(l.ventilasjon.typ, VentilasjonType::Naturlig) { return 0.0; } let q = luftmengde(l, t) / 3600.0; // m³/s l.ventilasjon.sfp * 1000.0 * q }