Files
enok/tests/referansebygg.rs
T
blandClaude Opus 5 0964cacba3 Energiberegning etter NS 3031:2025 med timesmetode og energirapport
enok leser en bygningsbeskrivelse i TOML, henter typisk klimaår for kommunen,
simulerer 8760 timer etter NS-EN ISO 52016-1 og skriver energirapport, CSV og JSON.

Motor
- Femnodemodell for opake bygningsdeler, tonodemodell for vinduer, luftnode og
  strålingsnode per sone, implisitt løsning per time med egen tett LU-løser.
- Varme- og kjølebehov ved eksakt interpolasjon mellom to løsninger, siden systemet
  er lineært. Vinduslufting for bygninger uten kjøleanlegg.
- Solberegning etter ISO 52010-1, kontrollert mot pvlib med avvik under 1 prosent.

Beregningsgang
- Beregningspunktene A til E: netto, brutto, tilført, levert per energibærer og
  vektet levert energi, med solceller, klimakorrigering og effektbehov.
- Energikarakter etter Enovas skala fra 1.1.2026, med arealkorreksjon.

Inndata
- TOML med scenarier for tiltak, og import fra IFC, gbXML og regneark.
- Normerte verdier, karakterskala, vektingsfaktorer og klimadata i data/,
  som kan overstyres med --data.

Kontroll
- Stasjonært varmetap mot U·A·ΔT innenfor 2 prosent, energibalansen innenfor
  2 prosent, varmetapsbudsjettet for TEK17-referansebygget identisk med publisert
  tabell. Kjent avvik i romoppvarming mot Simien 8 er dokumentert i README.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o
2026-09-14 18:03:00 +02:00

100 lines
3.8 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.
//! Kontroll mot Standard Norges lanseringseksempel for NS 3031:2025 (Multiconsult, mai 2025):
//! småhus med TEK17-standard i Oslo-klima.
//!
//! Eksempelet er beregnet med Simien 8. Varmetapsbudsjettet og de normerte energipostene
//! gjengis her nøyaktig. Romoppvarmingen avviker, se kommentaren nederst i filen.
use enok::data::Datakilde;
use enok::inndata;
use enok::kjor;
use std::path::Path;
fn kjor_referansebygg() -> kjor::Resultat {
let b = inndata::les_bygning(Path::new("eksempler/tek17-smaahus.toml")).unwrap();
kjor::kjor(&b, &Datakilde::default()).unwrap()
}
fn post(r: &kjor::Resultat, nr: &str) -> f64 {
let p = r.budsjett.poster.iter().find(|p| p.nr == nr).unwrap();
p.netto / r.lost.bra
}
fn naer(faktisk: f64, forventet: f64, toleranse: f64, hva: &str) {
assert!(
(faktisk - forventet).abs() <= toleranse,
"{hva}: beregnet {faktisk:.2}, forventet {forventet:.2} (toleranse {toleranse})"
);
}
/// Varmetapsbudsjettet skal gjengi NS 3031:2025 Tabell 3 for TEK17-referansebygget.
#[test]
fn varmetapsbudsjett_som_publisert() {
let r = kjor_referansebygg();
let v = &r.varmetap;
naer(v.vegger, 0.22, 0.005, "vegger");
naer(v.tak, 0.07, 0.005, "tak");
naer(v.gulv, 0.05, 0.005, "gulv");
naer(v.vinduer_dorer, 0.20, 0.005, "vinduer og dører");
naer(v.kuldebroer, 0.05, 0.005, "kuldebroer");
naer(v.transmisjon, 0.59, 0.005, "transmisjon");
naer(v.infiltrasjon, 0.04, 0.005, "infiltrasjon");
naer(v.klimaskjerm, 0.63, 0.005, "klimaskjerm");
naer(v.ventilasjon, 0.06, 0.005, "ventilasjon");
naer(v.totalt, 0.69, 0.005, "totalt varmetapstall");
}
/// De normerte energipostene skal treffe verdiene i NS 3031:2025 Tillegg A for småhus.
#[test]
fn normerte_energiposter_som_publisert() {
let r = kjor_referansebygg();
naer(post(&r, "2"), 25.1, 0.2, "varmtvann");
naer(post(&r, "5"), 11.4, 0.2, "belysning");
naer(post(&r, "6"), 17.5, 0.2, "teknisk utstyr");
naer(post(&r, "3a"), 0.0, 0.01, "romkjøling");
naer(post(&r, "3b"), 0.0, 0.01, "ventilasjonskjøling");
}
/// Energikarakteren for et TEK17-bygg skal være B, jf. energimerkeforskriften § 10b.
#[test]
fn tek17_bygg_faar_karakter_b_eller_bedre() {
let r = kjor_referansebygg();
assert!(
matches!(r.karakter.bokstav, "A" | "B"),
"TEK17-referansebygget fikk karakter {}, forventet A eller B",
r.karakter.bokstav
);
}
/// Regresjonsvakt for romoppvarming og samlet netto energibehov.
///
/// Det publiserte eksempelet oppgir 46,2 kWh/(m²·år) romoppvarming og 106,4 kWh/(m²·år)
/// netto energibehov. enok beregner vesentlig lavere romoppvarming. Kontrollene som er gjort:
///
/// * solinnstrålingen på skrå og orienterte flater er sammenlignet med pvlib (HayDavies) og
/// avviker under 1 % for alle himmelretninger i Oslo-klima;
/// * varmetapet i stasjonær tilstand stemmer med U·A·ΔT innenfor 2 % (se `tests/motor.rs`);
/// * årlig energibalanse går opp innenfor 2 %;
/// * varmetapsbudsjettet og de normerte energipostene er identiske med de publiserte.
///
/// Avviket ligger dermed i hvor stor del av solvarmen som nyttiggjøres. NS 3031:2025 Tillegg A
/// er ikke offentlig tilgjengelig, så de normerte solfaktorene, skjermingsforutsetningene og
/// timesprofilene som Simien 8 bruker, lar seg ikke etterprøve her. Testen låser dagens verdier
/// slik at endringer i motoren blir synlige, og oppdateres når standardens forutsetninger er
/// tilgjengelige.
#[test]
fn regresjonsvakt_for_romoppvarming() {
let r = kjor_referansebygg();
naer(
post(&r, "1a"),
24.7,
1.5,
"romoppvarming (regresjon, publisert verdi 46,2)",
);
naer(
r.budsjett.netto_spesifikk(r.lost.bra),
84.1,
2.0,
"netto energibehov (regresjon, publisert verdi 106,4)",
);
}