Files
enok/src/motor/ventilasjon.rs
T
blandClaude Opus 5 d02a3d9666 Legg til barnehage, kontor-, skole-, idretts- og kulturbygg
Driftstidene har nå dager per uke og uker per år, og lastene gjelder bare på driftsdager.
Normerte verdier for de nye kategoriene er hentet fra publiserte Simien-utskrifter og
DiBK-utredninger og kontrollert mot energibudsjettene i de samme kildene. Boligblokk har
fått egne verdier i stedet for en kopi av småhus.

Balanserte anlegg kan ha kjølebatteri, og varmegjenvinneren reguleres ned når den ellers
ville varmet tilluften over settpunktet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o
2026-09-15 20:05:20 +02:00

78 lines
2.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 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
}