Files
enok/tests/referansebygg_2015.rs
T

93 lines
3.5 KiB
Rust
Raw Normal View History

//! Kontroll mot de publiserte referansebyggene for energirammene i TEK17.
//!
//! Multiconsult for DiBK, «Grunnlag og forutsetninger for beregnede energirammer»
//! (128298-RIEn-NOT-001, 13. november 2015), gir geometri (tabell 1), komponentverdier
//! (tabell 2) og beregnet netto energibehov (tabell 3) for tretten bygningskategorier,
//! beregnet med Simien etter NS 3031:2014. Modellene er gjengitt i `eksempler/referansebygg/`.
//!
//! Dette er den eneste kontrollen der hele beregningen kan sammenlignes med et publisert
//! resultat for flere bygningskategorier. Testen låser dagens avvik, slik at det blir synlig
//! både når motoren nærmer seg de publiserte tallene og når noe gjør avviket større.
//!
//! Kjør `cargo test --release referansebygg_2015 -- --nocapture` for hele tabellen.
use enok::data::Datakilde;
use enok::{inndata, kjor};
use std::path::Path;
/// Fil, publisert netto energibehov, og enoks verdi slik den er i dag, kWh/(m²·år).
const BYGG: [(&str, f64, f64); 7] = [
("smaahus", 107.5, 85.3),
("boligblokk", 91.8, 77.6),
("barnehage", 132.0, 80.1),
("kontorbygg", 115.3, 93.5),
("skolebygg", 106.8, 72.8),
("idrettsbygg", 144.3, 106.7),
("kulturbygg", 128.0, 73.2),
];
fn netto(navn: &str) -> f64 {
let sti = format!("eksempler/referansebygg/{navn}.toml");
let b = inndata::les_bygning(Path::new(&sti)).unwrap();
let r = kjor::kjor(&b, &Datakilde::default()).unwrap();
r.budsjett.netto_spesifikk(r.lost.bra)
}
/// Verdiene skal ikke endre seg uten at noen har ment det.
#[test]
fn referansebyggene_gir_de_samme_tallene() {
println!(
"\n {:14}{:>10}{:>12}{:>9}",
"bygg", "enok", "publisert", "avvik"
);
let mut avvik = Vec::new();
for (navn, publisert, laast) in BYGG {
let n = netto(navn);
println!(
" {navn:14}{n:10.1}{publisert:12.1}{:8.1} %",
100.0 * (n - publisert) / publisert
);
avvik.push(100.0 * (n - publisert) / publisert);
assert!(
(n - laast).abs() < 1.0,
"{navn}: {n:.1} kWh/(m²·år), låst verdi {laast:.1}"
);
}
let snitt = avvik.iter().sum::<f64>() / avvik.len() as f64;
println!(" {:14}{:>10}{:>12}{snitt:8.1} %\n", "snitt", "", "");
}
/// Varmetapstallet for småhuset skal treffe den publiserte verdien for TEK17-nivå.
///
/// Geometri og U-verdier er dermed riktig gjengitt, og avviket i netto energibehov ligger i
/// den dynamiske beregningen, ikke i inndataene.
#[test]
fn varmetapstallet_for_smaahuset_stemmer() {
let b = inndata::les_bygning(Path::new("eksempler/referansebygg/smaahus.toml")).unwrap();
let r = kjor::kjor(&b, &Datakilde::default()).unwrap();
let publisert = 0.69;
assert!(
(r.varmetap.totalt - publisert).abs() < 0.03,
"varmetapstall {:.2}, publisert {publisert:.2}",
r.varmetap.totalt
);
}
/// De faste postene følger av normerte verdier og skal stemme uavhengig av motoren.
#[test]
fn faste_poster_i_referansebyggene() {
let post = |r: &kjor::Resultat, nr: &str| {
r.budsjett
.poster
.iter()
.find(|p| p.nr == nr)
.map(|p| p.netto / r.lost.bra)
.unwrap_or(0.0)
};
let b = inndata::les_bygning(Path::new("eksempler/referansebygg/smaahus.toml")).unwrap();
let r = kjor::kjor(&b, &Datakilde::default()).unwrap();
assert!((post(&r, "2") - 25.1).abs() < 0.2, "varmtvann");
assert!((post(&r, "5") - 11.4).abs() < 0.2, "belysning");
assert!((post(&r, "6") - 17.5).abs() < 0.2, "teknisk utstyr");
}