//! 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::() / 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"); }