diff --git a/examples/simple/processes.csv b/examples/simple/processes.csv index 63f48a97..59ea10bf 100644 --- a/examples/simple/processes.csv +++ b/examples/simple/processes.csv @@ -1,7 +1,7 @@ -id,description,regions,primary_output,start_year,end_year,capacity_to_activity -GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0 -GASPRC,Gas processing,all,GASNAT,2020,2040,1.0 -WNDFRM,Wind farm,all,ELCTRI,2020,2040,31.54 -GASCGT,Gas combined cycle turbine,all,ELCTRI,2020,2040,31.54 -RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0 -RELCHP,Heat pump,all,RSHEAT,2020,2040,1.0 +id,description,regions,primary_output,start_year,end_year,capacity_to_activity,unit_size +GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0, +GASPRC,Gas processing,all,GASNAT,2020,2040,1.0, +WNDFRM,Wind farm,all,ELCTRI,2020,2040,31.54, +GASCGT,Gas combined cycle turbine,all,ELCTRI,2020,2040,31.54, +RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0, +RELCHP,Heat pump,all,RSHEAT,2020,2040,1.0, diff --git a/schemas/input/processes.yaml b/schemas/input/processes.yaml index 1f6a8215..aa47081a 100644 --- a/schemas/input/processes.yaml +++ b/schemas/input/processes.yaml @@ -28,12 +28,18 @@ fields: notes: Must be >= to `start_year` - name: capacity_to_activity type: number - description: Factor relating capacity units (e.g. GW) to activity units (e.g. PJ). It is the maximum activity per year for one unit of capacity. + description: Factor relating capacity units (e.g. GW) to activity units (e.g. PJ). It is the + maximum activity per year for one unit of capacity. notes: Must be >=0. Optional (defaults to 1.0). - name: unit_size type: number - description: Capacity of the units in which an asset for this process will be divided into when commissioned, if any. - notes: - If present, must be >0. Optional (defaults to None). It should be noted that making this number too small with respect the typical - size of an asset might create hundreds or thousands of children assets, with a very negative effect on the performance. Users are advised - to use this feature with care. + description: Capacity of the units in which an asset for this process will be divided into when + commissioned, if any. + notes: If present, must be >0. Optional (defaults to None). Assets with a defined unit size are + divided into n = ceil(C / U) equal units, where C is overall capacity and U is unit_size + (i.e. rounding up the number of units, which may result in a total capacity greater than C, if + C is not an exact multiple of U). + + It should be noted that making this number too small with respect to the typical size of an + asset might create hundreds or thousands of children assets, with a very negative effect on + the performance. Users are advised to use this feature with care. diff --git a/src/asset.rs b/src/asset.rs index f31c3c32..3129c77a 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -838,32 +838,40 @@ impl Asset { /// Divides an asset if it is divisible and returns a vector of children /// - /// The children assets are identical to the parent (including state) but with a capacity defined - /// by the `unit_size`. Only Future or Selected assets can be divided. + /// The child assets are identical to the parent (including state) but with a capacity + /// defined by the `unit_size`. From a parent asset of capacity `C` and unit size `U`, + /// `n = ceil(C / U)` child assets are created, each with capacity `U`. In other words, the + /// total combined capacity of the children may be larger than that of the parent, + /// if `C` is not an exact multiple of `U`. + /// + /// Only `Future` and `Selected` assets can be divided. pub fn divide_asset(&self) -> Vec { assert!( matches!( self.state, AssetState::Future { .. } | AssetState::Selected { .. } ), - "Assets with state {0} cannot be divided. Only Future or Selected assets can be divided", + "Assets with state {} cannot be divided. Only Future or Selected assets can be divided", self.state ); - // Divide the asset into children until all capacity is allocated - let mut capacity = self.capacity; let unit_size = self.process.unit_size.expect( "Only assets corresponding to processes with a unit size defined can be divided", ); - let mut children = Vec::new(); - while capacity > Capacity(0.0) { - let mut child = self.clone(); - child.capacity = unit_size.min(capacity); - capacity -= child.capacity; - children.push(child.into()); - } - children + // Calculate the number of units corresponding to the asset's capacity + // Safe because capacity and unit_size are both positive finite numbers, so their ratio + // must also be positive and finite. + #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + let n_units = (self.capacity / unit_size).value().ceil() as usize; + + // Divide the asset into `n_units` children of size `unit_size` + let child_asset = Self { + capacity: unit_size, + ..self.clone() + }; + let child_asset = AssetRef::from(Rc::new(child_asset)); + std::iter::repeat_n(child_asset, n_units).collect() } } @@ -1072,8 +1080,7 @@ impl AssetPool { // If it is divisible, we divide and commission all the children if asset.is_divisible() { - let children = asset.divide_asset(); - for mut child in children { + for mut child in asset.divide_asset() { child.make_mut().commission( AssetID(self.next_id), Some(AssetGroupID(self.next_group_id)), @@ -1490,31 +1497,49 @@ mod tests { } #[rstest] - fn divide_asset_works(asset_divisible: Asset) { - assert!( - asset_divisible.is_divisible(), - "Divisbile asset cannot be divided!" - ); + #[case::exact_multiple(Capacity(12.0), Capacity(4.0), 3)] // 12 / 4 = 3 + #[case::rounded_up(Capacity(11.0), Capacity(4.0), 3)] // 11 / 4 = 2.75 -> 3 + #[case::unit_size_equals_capacity(Capacity(4.0), Capacity(4.0), 1)] // 4 / 4 = 1 + #[case::unit_size_greater_than_capacity(Capacity(3.0), Capacity(4.0), 1)] // 3 / 4 = 0.75 -> 1 + fn divide_asset( + mut process: Process, + #[case] capacity: Capacity, + #[case] unit_size: Capacity, + #[case] n_expected_children: usize, + ) { + process.unit_size = Some(unit_size); + let asset = Asset::new_future( + "agent1".into(), + Rc::new(process), + "GBR".into(), + capacity, + 2010, + ) + .unwrap(); - // Check number of children - let children = asset_divisible.divide_asset(); - let expected_children = expected_children_for_divisible(&asset_divisible); + assert!(asset.is_divisible(), "Asset should be divisible!"); + + let children = asset.divide_asset(); assert_eq!( children.len(), - expected_children, + n_expected_children, "Unexpected number of children" ); - // Check capacity of the children - let max_child_capacity = asset_divisible.process.unit_size.unwrap(); + // Check all children have capacity equal to unit_size for child in children.clone() { - assert!( - child.capacity <= max_child_capacity, - "Child capacity is too large!" + assert_eq!( + child.capacity, unit_size, + "Child capacity should equal unit_size" ); } - let children_capacity: Capacity = children.iter().map(|a| a.capacity).sum(); - assert_eq!(asset_divisible.capacity, children_capacity); + + // Check total capacity is >= parent capacity + let total_child_capacity: Capacity = children.iter().map(|child| child.capacity).sum(); + assert!( + total_child_capacity >= asset.capacity, + "Total capacity should be >= parent capacity" + ); } #[rstest] @@ -1558,9 +1583,6 @@ mod tests { assert!(!asset_pool.active.is_empty()); assert_eq!(asset_pool.active.len(), expected_children); assert_eq!(asset_pool.next_group_id, 1); - - let children_capacity: Capacity = asset_pool.active.iter().map(|a| a.capacity).sum(); - assert_eq!(asset_divisible.capacity, children_capacity); } #[rstest] @@ -2024,8 +2046,8 @@ mod tests { #[test] fn commission_year_before_time_horizon() { let processes_patch = FilePatch::new("processes.csv") - .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0") - .with_addition("GASDRV,Dry gas extraction,all,GASPRD,1980,2040,1.0"); + .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0,") + .with_addition("GASDRV,Dry gas extraction,all,GASPRD,1980,2040,1.0,"); // Check we can run model with asset commissioned before time horizon (simple starts in // 2020) @@ -2049,8 +2071,8 @@ mod tests { #[test] fn commission_year_after_time_horizon() { let processes_patch = FilePatch::new("processes.csv") - .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0") - .with_addition("GASDRV,Dry gas extraction,all,GASPRD,2020,2050,1.0"); + .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0,") + .with_addition("GASDRV,Dry gas extraction,all,GASPRD,2020,2050,1.0,"); // Check we can run model with asset commissioned after time horizon (simple ends in 2040) let patches = vec![ diff --git a/src/input/asset.rs b/src/input/asset.rs index 4f7612ff..451b706a 100644 --- a/src/input/asset.rs +++ b/src/input/asset.rs @@ -7,8 +7,10 @@ use crate::process::ProcessMap; use crate::region::RegionID; use crate::units::Capacity; use anyhow::{Context, Result, ensure}; +use float_cmp::approx_eq; use indexmap::IndexSet; use itertools::Itertools; +use log::warn; use serde::Deserialize; use std::path::Path; use std::rc::Rc; @@ -103,6 +105,24 @@ where asset.agent_id, ); + // Check that capacity is approximately a multiple of the process unit size + // If not, raise a warning + if let Some(unit_size) = process.unit_size { + let ratio = (asset.capacity / unit_size).value(); + if !approx_eq!(f64, ratio, ratio.ceil()) { + let n_units = ratio.ceil(); + warn!( + "Asset capacity {} for process {} is not a multiple of unit size {}. \ + Asset will be divided into {} units with combined capacity of {}.", + asset.capacity, + asset.process_id, + unit_size, + n_units, + unit_size.value() * n_units + ); + } + } + Asset::new_future_with_max_decommission( agent_id.clone(), Rc::clone(process), diff --git a/src/input/process/flow.rs b/src/input/process/flow.rs index 9e322870..fc7b769e 100644 --- a/src/input/process/flow.rs +++ b/src/input/process/flow.rs @@ -563,8 +563,8 @@ mod tests { // non-milestone years. let patches = vec![ FilePatch::new("processes.csv") - .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0") - .with_addition("GASDRV,Dry gas extraction,all,GASPRD,1980,2040,1.0"), + .with_deletion("GASDRV,Dry gas extraction,all,GASPRD,2020,2040,1.0,") + .with_addition("GASDRV,Dry gas extraction,all,GASPRD,1980,2040,1.0,"), FilePatch::new("process_flows.csv") .with_deletion("GASPRC,GASPRD,all,all,-1.05,fixed,") .with_addition("GASPRC,GASPRD,all,2020;2030;2040,-1.05,fixed,"), diff --git a/src/patch.rs b/src/patch.rs index e8068e70..1f60c305 100644 --- a/src/patch.rs +++ b/src/patch.rs @@ -26,7 +26,6 @@ impl ModelPatch { } /// Create a new empty `ModelPatch` for an example model - #[cfg(test)] pub fn from_example(name: &str) -> Self { let base_model_dir = PathBuf::from("examples").join(name); ModelPatch::new(base_model_dir) @@ -62,7 +61,7 @@ impl ModelPatch { } /// Build this `ModelPatch` into `out_dir` (creating/overwriting files there). - fn build>(&self, out_dir: O) -> Result<()> { + pub fn build>(&self, out_dir: O) -> Result<()> { let base_dir = self.base_model_dir.as_path(); let out_path = out_dir.as_ref(); diff --git a/tests/data/simple_divisible/assets.csv b/tests/data/simple_divisible/assets.csv new file mode 100644 index 00000000..5be4861d --- /dev/null +++ b/tests/data/simple_divisible/assets.csv @@ -0,0 +1,15 @@ +asset_id,process_id,region_id,agent_id,group_id,commission_year,decommission_year,capacity +0,GASDRV,GBR,A0_GEX,,2020,,4002.26 +1,GASPRC,GBR,A0_GPR,,2020,,3782.13 +2,WNDFRM,GBR,A0_ELC,,2020,2040,3.964844 +3,GASCGT,GBR,A0_ELC,,2020,2040,2.43 +4,RGASBR,GBR,A0_RES,,2020,2035,1000.0 +5,RGASBR,GBR,A0_RES,,2020,2035,1000.0 +6,RGASBR,GBR,A0_RES,,2020,2035,1000.0 +7,RELCHP,GBR,A0_RES,,2020,2035,399.98 +8,RGASBR,GBR,A0_RES,1,2030,,1000.0 +9,GASCGT,GBR,A0_ELC,,2030,2040,0.44245235762867363 +10,RGASBR,GBR,A0_RES,2,2040,,1000.0 +11,RGASBR,GBR,A0_RES,2,2040,,1000.0 +12,RGASBR,GBR,A0_RES,2,2040,,1000.0 +13,RGASBR,GBR,A0_RES,2,2040,,1000.0 diff --git a/tests/data/simple_divisible/commodity_flows.csv b/tests/data/simple_divisible/commodity_flows.csv new file mode 100644 index 00000000..0c290708 --- /dev/null +++ b/tests/data/simple_divisible/commodity_flows.csv @@ -0,0 +1,1057 @@ +milestone_year,asset_id,commodity_id,time_slice,flow +2020,0,GASPRD,winter.night,0.0 +2020,0,CO2EMT,winter.night,0.0 +2020,0,GASPRD,winter.day,151.10360181069296 +2020,0,CO2EMT,winter.day,772.5927160580732 +2020,0,GASPRD,winter.peak,125.070625 +2020,0,CO2EMT,winter.peak,639.486105625 +2020,0,GASPRD,winter.evening,166.76083466742 +2020,0,CO2EMT,winter.evening,852.6481476545185 +2020,0,GASPRD,peak.night,0.0 +2020,0,CO2EMT,peak.night,0.0 +2020,0,GASPRD,peak.day,0.0 +2020,0,CO2EMT,peak.day,0.0 +2020,0,GASPRD,peak.peak,58.675825622557085 +2020,0,CO2EMT,peak.peak,300.0094964081344 +2020,0,GASPRD,peak.evening,166.76083466742 +2020,0,CO2EMT,peak.evening,852.6481476545185 +2020,0,GASPRD,summer.night,0.0 +2020,0,CO2EMT,summer.night,0.0 +2020,0,GASPRD,summer.day,0.0 +2020,0,CO2EMT,summer.day,0.0 +2020,0,GASPRD,summer.peak,0.0 +2020,0,CO2EMT,summer.peak,0.0 +2020,0,GASPRD,summer.evening,0.16861964795988574 +2020,0,CO2EMT,summer.evening,0.8621522600188959 +2020,0,GASPRD,autumn.night,0.0 +2020,0,CO2EMT,autumn.night,0.0 +2020,0,GASPRD,autumn.day,0.0 +2020,0,CO2EMT,autumn.day,0.0 +2020,0,GASPRD,autumn.peak,0.0 +2020,0,CO2EMT,autumn.peak,0.0 +2020,0,GASPRD,autumn.evening,163.3883025525992 +2020,0,CO2EMT,autumn.evening,835.4043909514398 +2020,1,GASPRD,winter.night,-0.0 +2020,1,GASNAT,winter.night,0.0 +2020,1,CO2EMT,winter.night,0.0 +2020,1,GASPRD,winter.day,-153.36573202936748 +2020,1,GASNAT,winter.day,146.06260193273093 +2020,1,CO2EMT,winter.day,373.40904184102664 +2020,1,GASPRD,winter.peak,-124.10114062500001 +2020,1,GASNAT,winter.peak,118.1915625 +2020,1,CO2EMT,winter.peak,302.15672953125005 +2020,1,GASPRD,winter.evening,-165.4681888237455 +2020,1,GASNAT,winter.evening,157.58875126070998 +2020,1,CO2EMT,winter.evening,402.87564259800513 +2020,1,GASPRD,peak.night,-0.0 +2020,1,GASNAT,peak.night,0.0 +2020,1,CO2EMT,peak.night,0.0 +2020,1,GASPRD,peak.day,-0.0 +2020,1,GASNAT,peak.day,0.0 +2020,1,CO2EMT,peak.day,0.0 +2020,1,GASPRD,peak.peak,-59.9684714662316 +2020,1,GASNAT,peak.peak,57.112829967839616 +2020,1,CO2EMT,peak.peak,146.008949812782 +2020,1,GASPRD,peak.evening,-165.4681888237455 +2020,1,GASNAT,peak.evening,157.58875126070998 +2020,1,CO2EMT,peak.evening,402.87564259800513 +2020,1,GASPRD,summer.night,-0.0 +2020,1,GASNAT,summer.night,0.0 +2020,1,CO2EMT,summer.night,0.0 +2020,1,GASPRD,summer.day,-0.0 +2020,1,GASNAT,summer.day,0.0 +2020,1,CO2EMT,summer.day,0.0 +2020,1,GASPRD,summer.peak,-0.0 +2020,1,GASNAT,summer.peak,0.0 +2020,1,CO2EMT,summer.peak,0.0 +2020,1,GASPRD,summer.evening,-0.16861964795988574 +2020,1,GASNAT,summer.evening,0.1605901409141769 +2020,1,CO2EMT,summer.evening,0.41054869524709325 +2020,1,GASPRD,autumn.night,-0.0 +2020,1,GASNAT,autumn.night,0.0 +2020,1,CO2EMT,autumn.night,0.0 +2020,1,GASPRD,autumn.day,-0.0 +2020,1,GASNAT,autumn.day,0.0 +2020,1,CO2EMT,autumn.day,0.0 +2020,1,GASPRD,autumn.peak,-0.0 +2020,1,GASNAT,autumn.peak,0.0 +2020,1,CO2EMT,autumn.peak,0.0 +2020,1,GASPRD,autumn.evening,-163.3883025525992 +2020,1,GASNAT,autumn.evening,155.60790719295161 +2020,1,CO2EMT,autumn.evening,397.81161473878086 +2020,2,ELCTRI,winter.night,4.435312795545212 +2020,2,ELCTRI,winter.day,7.075379933645912 +2020,2,ELCTRI,winter.peak,1.9712501261051125 +2020,2,ELCTRI,winter.evening,2.5696653598405335 +2020,2,ELCTRI,peak.night,2.851272517283696 +2020,2,ELCTRI,peak.day,6.3713620320039785 +2020,2,ELCTRI,peak.peak,1.7776452018191917 +2020,2,ELCTRI,peak.evening,1.72484387381507 +2020,2,ELCTRI,summer.night,1.6368416242136155 +2020,2,ELCTRI,summer.day,2.9055524196533997 +2020,2,ELCTRI,summer.peak,0.9567924409494001 +2020,2,ELCTRI,summer.evening,0.7124084843502 +2020,2,ELCTRI,autumn.night,3.203281465982185 +2020,2,ELCTRI,autumn.day,6.001752635595889 +2020,2,ELCTRI,autumn.peak,1.5488393825638174 +2020,2,ELCTRI,autumn.evening,1.9008483513729915 +2020,3,GASNAT,winter.night,-7.783808997678887 +2020,3,ELCTRI,winter.night,5.189205998452591 +2020,3,CO2EMT,winter.night,397.9861540513214 +2020,3,GASNAT,winter.day,-10.010898915527838 +2020,3,ELCTRI,winter.day,6.6739326103518914 +2020,3,CO2EMT,winter.day,511.8572615509383 +2020,3,GASNAT,winter.peak,-3.2303154358423316 +2020,3,ELCTRI,winter.peak,2.1535436238948877 +2020,3,CO2EMT,winter.peak,165.1660282346184 +2020,3,GASNAT,winter.evening,-4.395089526235901 +2020,3,ELCTRI,winter.evening,2.9300596841572673 +2020,3,CO2EMT,winter.evening,224.7209274764416 +2020,3,GASNAT,peak.night,-8.382740663321101 +2020,3,ELCTRI,peak.night,5.5884937755474 +2020,3,CO2EMT,peak.night,428.6095301156078 +2020,3,GASNAT,peak.day,-11.066925767990737 +2020,3,ELCTRI,peak.day,7.3779505119938245 +2020,3,CO2EMT,peak.day,565.8519145173664 +2020,3,GASNAT,peak.peak,-3.520722822271213 +2020,3,ELCTRI,peak.peak,2.3471485481808085 +2020,3,CO2EMT,peak.peak,180.0145579027271 +2020,3,GASNAT,peak.evening,-4.790137538321099 +2020,3,ELCTRI,peak.evening,3.1934250255473997 +2020,3,CO2EMT,peak.evening,244.9197323343578 +2020,3,GASNAT,summer.night,-0.1605901409141769 +2020,3,ELCTRI,summer.night,0.1070600939427846 +2020,3,CO2EMT,summer.night,8.210973904941865 +2020,3,GASNAT,summer.day,-0.0 +2020,3,ELCTRI,summer.day,0.0 +2020,3,CO2EMT,summer.day,0.0 +2020,3,GASNAT,summer.peak,-0.0 +2020,3,ELCTRI,summer.peak,0.0 +2020,3,CO2EMT,summer.peak,0.0 +2020,3,GASNAT,summer.evening,-0.0 +2020,3,ELCTRI,summer.evening,0.0 +2020,3,CO2EMT,summer.evening,0.0 +2020,3,GASNAT,autumn.night,-8.382740663321101 +2020,3,ELCTRI,autumn.night,5.5884937755474 +2020,3,CO2EMT,autumn.night,428.6095301156078 +2020,3,GASNAT,autumn.day,-11.621339862602872 +2020,3,ELCTRI,autumn.day,7.747559908401914 +2020,3,CO2EMT,autumn.day,594.1991071748848 +2020,3,GASNAT,autumn.peak,-3.592603125 +2020,3,ELCTRI,autumn.peak,2.39506875 +2020,3,CO2EMT,autumn.peak,183.68979778124998 +2020,3,GASNAT,autumn.evening,-4.790137538321099 +2020,3,ELCTRI,autumn.evening,3.1934250255473997 +2020,3,CO2EMT,autumn.evening,244.9197323343578 +2020,4,GASNAT,winter.night,-0.0 +2020,4,RSHEAT,winter.night,0.0 +2020,4,CO2EMT,winter.night,0.0 +2020,4,GASNAT,winter.day,-0.0 +2020,4,RSHEAT,winter.day,0.0 +2020,4,CO2EMT,winter.day,0.0 +2020,4,GASNAT,winter.peak,-32.34372974118598 +2020,4,RSHEAT,winter.peak,28.12498238363999 +2020,4,CO2EMT,winter.peak,1653.7349016668395 +2020,4,GASNAT,winter.evening,-0.0 +2020,4,RSHEAT,winter.evening,0.0 +2020,4,CO2EMT,winter.evening,0.0 +2020,4,GASNAT,peak.night,-0.0 +2020,4,RSHEAT,peak.night,0.0 +2020,4,CO2EMT,peak.night,0.0 +2020,4,GASNAT,peak.day,-0.0 +2020,4,RSHEAT,peak.day,0.0 +2020,4,CO2EMT,peak.day,0.0 +2020,4,GASNAT,peak.peak,-0.0 +2020,4,RSHEAT,peak.peak,0.0 +2020,4,CO2EMT,peak.peak,0.0 +2020,4,GASNAT,peak.evening,-0.0 +2020,4,RSHEAT,peak.evening,0.0 +2020,4,CO2EMT,peak.evening,0.0 +2020,4,GASNAT,summer.night,-0.0 +2020,4,RSHEAT,summer.night,0.0 +2020,4,CO2EMT,summer.night,0.0 +2020,4,GASNAT,summer.day,-0.0 +2020,4,RSHEAT,summer.day,0.0 +2020,4,CO2EMT,summer.day,0.0 +2020,4,GASNAT,summer.peak,-0.0 +2020,4,RSHEAT,summer.peak,0.0 +2020,4,CO2EMT,summer.peak,0.0 +2020,4,GASNAT,summer.evening,-0.0 +2020,4,RSHEAT,summer.evening,0.0 +2020,4,CO2EMT,summer.evening,0.0 +2020,4,GASNAT,autumn.night,-0.0 +2020,4,RSHEAT,autumn.night,0.0 +2020,4,CO2EMT,autumn.night,0.0 +2020,4,GASNAT,autumn.day,-0.0 +2020,4,RSHEAT,autumn.day,0.0 +2020,4,CO2EMT,autumn.day,0.0 +2020,4,GASNAT,autumn.peak,-0.0 +2020,4,RSHEAT,autumn.peak,0.0 +2020,4,CO2EMT,autumn.peak,0.0 +2020,4,GASNAT,autumn.evening,-0.0 +2020,4,RSHEAT,autumn.evening,0.0 +2020,4,CO2EMT,autumn.evening,0.0 +2020,5,GASNAT,winter.night,-0.0 +2020,5,RSHEAT,winter.night,0.0 +2020,5,CO2EMT,winter.night,0.0 +2020,5,GASNAT,winter.day,-73.47806748857997 +2020,5,RSHEAT,winter.day,63.893971729199976 +2020,5,CO2EMT,winter.day,3756.933590691094 +2020,5,GASNAT,winter.peak,-35.9375 +2020,5,RSHEAT,winter.peak,31.25 +2020,5,CO2EMT,winter.peak,1837.484375 +2020,5,GASNAT,winter.evening,-14.704802914679998 +2020,5,RSHEAT,winter.evening,12.7867851432 +2020,5,CO2EMT,winter.evening,751.8565730275884 +2020,5,GASNAT,peak.night,-0.0 +2020,5,RSHEAT,peak.night,0.0 +2020,5,CO2EMT,peak.night,0.0 +2020,5,GASNAT,peak.day,-0.0 +2020,5,RSHEAT,peak.day,0.0 +2020,5,CO2EMT,peak.day,0.0 +2020,5,GASNAT,peak.peak,-22.353777616306004 +2020,5,RSHEAT,peak.peak,19.438067492440005 +2020,5,CO2EMT,peak.peak,1142.948649521726 +2020,5,GASNAT,peak.evening,-0.0 +2020,5,RSHEAT,peak.evening,0.0 +2020,5,CO2EMT,peak.evening,0.0 +2020,5,GASNAT,summer.night,-0.0 +2020,5,RSHEAT,summer.night,0.0 +2020,5,CO2EMT,summer.night,0.0 +2020,5,GASNAT,summer.day,-0.0 +2020,5,RSHEAT,summer.day,0.0 +2020,5,CO2EMT,summer.day,0.0 +2020,5,GASNAT,summer.peak,-0.0 +2020,5,RSHEAT,summer.peak,0.0 +2020,5,CO2EMT,summer.peak,0.0 +2020,5,GASNAT,summer.evening,-0.0 +2020,5,RSHEAT,summer.evening,0.0 +2020,5,CO2EMT,summer.evening,0.0 +2020,5,GASNAT,autumn.night,-0.0 +2020,5,RSHEAT,autumn.night,0.0 +2020,5,CO2EMT,autumn.night,0.0 +2020,5,GASNAT,autumn.day,-0.0 +2020,5,RSHEAT,autumn.day,0.0 +2020,5,CO2EMT,autumn.day,0.0 +2020,5,GASNAT,autumn.peak,-8.442726050956358 +2020,5,RSHEAT,autumn.peak,7.341500913875095 +2020,5,CO2EMT,autumn.peak,431.6765829853986 +2020,5,GASNAT,autumn.evening,-0.0 +2020,5,RSHEAT,autumn.evening,0.0 +2020,5,CO2EMT,autumn.evening,0.0 +2020,6,GASNAT,winter.night,-36.31286857370999 +2020,6,RSHEAT,winter.night,31.576407455399995 +2020,6,CO2EMT,winter.night,1856.6769701737921 +2020,6,GASNAT,winter.day,-119.79166705 +2020,6,RSHEAT,winter.day,104.166667 +2020,6,CO2EMT,winter.day,6124.947936266501 +2020,6,GASNAT,winter.peak,-35.9375 +2020,6,RSHEAT,winter.peak,31.25 +2020,6,CO2EMT,winter.peak,1837.484375 +2020,6,GASNAT,winter.evening,-47.916667049999994 +2020,6,RSHEAT,winter.evening,41.666667 +2020,6,CO2EMT,winter.evening,2449.9791862664997 +2020,6,GASNAT,peak.night,-19.52227251698524 +2020,6,RSHEAT,peak.night,16.975889145204558 +2020,6,CO2EMT,peak.night,998.1737937934555 +2020,6,GASNAT,peak.day,-82.18418839575197 +2020,6,RSHEAT,peak.day,71.46451164847998 +2020,6,CO2EMT,peak.day,4202.077552674799 +2020,6,GASNAT,peak.peak,-35.9375 +2020,6,RSHEAT,peak.peak,31.25 +2020,6,CO2EMT,peak.peak,1837.484375 +2020,6,GASNAT,peak.evening,-26.943315907602276 +2020,6,RSHEAT,peak.evening,23.428970354436764 +2020,6,CO2EMT,peak.evening,1377.6117423557046 +2020,6,GASNAT,summer.night,-0.0 +2020,6,RSHEAT,summer.night,0.0 +2020,6,CO2EMT,summer.night,0.0 +2020,6,GASNAT,summer.day,-0.0 +2020,6,RSHEAT,summer.day,0.0 +2020,6,CO2EMT,summer.day,0.0 +2020,6,GASNAT,summer.peak,-0.0 +2020,6,RSHEAT,summer.peak,0.0 +2020,6,CO2EMT,summer.peak,0.0 +2020,6,GASNAT,summer.evening,-0.0 +2020,6,RSHEAT,summer.evening,0.0 +2020,6,CO2EMT,summer.evening,0.0 +2020,6,GASNAT,autumn.night,-9.10896122967321 +2020,6,RSHEAT,autumn.night,7.920835851889748 +2020,6,CO2EMT,autumn.night,465.7411876731913 +2020,6,GASNAT,autumn.day,-56.69422338503598 +2020,6,RSHEAT,autumn.day,49.29932468263999 +2020,6,CO2EMT,autumn.day,2898.7756416768902 +2020,6,GASNAT,autumn.peak,-35.9375 +2020,6,RSHEAT,autumn.peak,31.25 +2020,6,CO2EMT,autumn.peak,1837.484375 +2020,6,GASNAT,autumn.evening,-17.037675338040994 +2020,6,RSHEAT,autumn.evening,14.815369859166085 +2020,6,CO2EMT,autumn.evening,871.1363400340363 +2020,7,ELCTRI,winter.night,-9.624518793997803 +2020,7,RSHEAT,winter.night,29.165208466660005 +2020,7,ELCTRI,winter.day,-13.749312543997803 +2020,7,RSHEAT,winter.day,41.664583466660005 +2020,7,ELCTRI,winter.peak,-4.12479375 +2020,7,RSHEAT,winter.peak,12.499375 +2020,7,ELCTRI,winter.evening,-5.499725043997801 +2020,7,RSHEAT,winter.evening,16.66583346666 +2020,7,ELCTRI,peak.night,-8.439766292831097 +2020,7,RSHEAT,peak.night,25.575049372215442 +2020,7,ELCTRI,peak.day,-13.749312543997803 +2020,7,RSHEAT,peak.day,41.664583466660005 +2020,7,ELCTRI,peak.peak,-4.12479375 +2020,7,RSHEAT,peak.peak,12.499375 +2020,7,ELCTRI,peak.evening,-4.91826889936247 +2020,7,RSHEAT,peak.evening,14.903845149583242 +2020,7,ELCTRI,summer.night,-1.7439017181564 +2020,7,RSHEAT,summer.night,5.28455066108 +2020,7,ELCTRI,summer.day,-2.9055524196533997 +2020,7,RSHEAT,summer.day,8.80470430198 +2020,7,ELCTRI,summer.peak,-0.9567924409494001 +2020,7,RSHEAT,summer.peak,2.89937103318 +2020,7,ELCTRI,summer.evening,-0.7124084843502 +2020,7,RSHEAT,summer.evening,2.1588135889399998 +2020,7,ELCTRI,autumn.night,-8.791775241529585 +2020,7,RSHEAT,autumn.night,26.641743156150255 +2020,7,ELCTRI,autumn.day,-13.749312543997803 +2020,7,RSHEAT,autumn.day,41.664583466660005 +2020,7,ELCTRI,autumn.peak,-3.9439081325638172 +2020,7,RSHEAT,autumn.peak,11.9512367653449 +2020,7,ELCTRI,autumn.evening,-5.094273376920391 +2020,7,RSHEAT,autumn.evening,15.437192051273913 +2030,0,GASPRD,winter.night,0.0 +2030,0,CO2EMT,winter.night,0.0 +2030,0,GASPRD,winter.day,209.0073635849431 +2030,0,CO2EMT,winter.day,1068.6546500098143 +2030,0,GASPRD,winter.peak,125.070625 +2030,0,CO2EMT,winter.peak,639.486105625 +2030,0,GASPRD,winter.evening,166.76083466742 +2030,0,CO2EMT,winter.evening,852.6481476545185 +2030,0,GASPRD,peak.night,0.0 +2030,0,CO2EMT,peak.night,0.0 +2030,0,GASPRD,peak.day,0.0 +2030,0,CO2EMT,peak.day,0.0 +2030,0,GASPRD,peak.peak,88.83225416513676 +2030,0,CO2EMT,peak.peak,454.1993155463443 +2030,0,GASPRD,peak.evening,166.76083466742 +2030,0,CO2EMT,peak.evening,852.6481476545185 +2030,0,GASPRD,summer.night,0.0 +2030,0,CO2EMT,summer.night,0.0 +2030,0,GASPRD,summer.day,0.0 +2030,0,CO2EMT,summer.day,0.0 +2030,0,GASPRD,summer.peak,0.0 +2030,0,CO2EMT,summer.peak,0.0 +2030,0,GASPRD,summer.evening,0.464792220809886 +2030,0,CO2EMT,summer.evening,2.3764826250009476 +2030,0,GASPRD,autumn.night,0.0 +2030,0,CO2EMT,autumn.night,0.0 +2030,0,GASPRD,autumn.day,0.0 +2030,0,CO2EMT,autumn.day,0.0 +2030,0,GASPRD,autumn.peak,20.534211026060348 +2030,0,CO2EMT,autumn.peak,104.99142097624657 +2030,0,GASPRD,autumn.evening,166.76083466742 +2030,0,CO2EMT,autumn.evening,852.6481476545185 +2030,1,GASPRD,winter.night,-0.0 +2030,1,GASNAT,winter.night,0.0 +2030,1,CO2EMT,winter.night,0.0 +2030,1,GASPRD,winter.day,-211.2694938036176 +2030,1,GASNAT,winter.day,201.20904171773103 +2030,1,CO2EMT,winter.day,514.3909151513794 +2030,1,GASPRD,winter.peak,-124.10114062500001 +2030,1,GASNAT,winter.peak,118.1915625 +2030,1,CO2EMT,winter.peak,302.15672953125005 +2030,1,GASPRD,winter.evening,-165.4681888237455 +2030,1,GASNAT,winter.evening,157.58875126070998 +2030,1,CO2EMT,winter.evening,402.87564259800513 +2030,1,GASPRD,peak.night,-0.0 +2030,1,GASNAT,peak.night,0.0 +2030,1,CO2EMT,peak.night,0.0 +2030,1,GASPRD,peak.day,-0.0 +2030,1,GASNAT,peak.day,0.0 +2030,1,CO2EMT,peak.day,0.0 +2030,1,GASPRD,peak.peak,-90.12490000881128 +2030,1,GASNAT,peak.peak,85.83323810362978 +2030,1,CO2EMT,peak.peak,219.43267321192957 +2030,1,GASPRD,peak.evening,-165.4681888237455 +2030,1,GASNAT,peak.evening,157.58875126070998 +2030,1,CO2EMT,peak.evening,402.87564259800513 +2030,1,GASPRD,summer.night,-0.0 +2030,1,GASNAT,summer.night,0.0 +2030,1,CO2EMT,summer.night,0.0 +2030,1,GASPRD,summer.day,-0.0 +2030,1,GASNAT,summer.day,0.0 +2030,1,CO2EMT,summer.day,0.0 +2030,1,GASPRD,summer.peak,-0.0 +2030,1,GASNAT,summer.peak,0.0 +2030,1,CO2EMT,summer.peak,0.0 +2030,1,GASPRD,summer.evening,-0.464792220809886 +2030,1,GASNAT,summer.evening,0.44265925791417715 +2030,1,CO2EMT,summer.evening,1.131658392857594 +2030,1,GASPRD,autumn.night,-0.0 +2030,1,GASNAT,autumn.night,0.0 +2030,1,CO2EMT,autumn.night,0.0 +2030,1,GASPRD,autumn.day,-0.0 +2030,1,GASNAT,autumn.day,0.0 +2030,1,CO2EMT,autumn.day,0.0 +2030,1,GASPRD,autumn.peak,-21.826856869734865 +2030,1,GASNAT,autumn.peak,20.78748273308082 +2030,1,CO2EMT,autumn.peak,53.143199607121126 +2030,1,GASPRD,autumn.evening,-165.4681888237455 +2030,1,GASNAT,autumn.evening,157.58875126070998 +2030,1,CO2EMT,autumn.evening,402.87564259800513 +2030,2,ELCTRI,winter.night,4.435312795545212 +2030,2,ELCTRI,winter.day,7.075379933645912 +2030,2,ELCTRI,winter.peak,1.9712501261051125 +2030,2,ELCTRI,winter.evening,2.5696653598405335 +2030,2,ELCTRI,peak.night,2.851272517283696 +2030,2,ELCTRI,peak.day,6.3713620320039785 +2030,2,ELCTRI,peak.peak,1.7776452018191917 +2030,2,ELCTRI,peak.evening,1.72484387381507 +2030,2,ELCTRI,summer.night,1.6368416242136155 +2030,2,ELCTRI,summer.day,3.2188600626534005 +2030,2,ELCTRI,summer.peak,1.0599640039494003 +2030,2,ELCTRI,summer.evening,0.7892279633502001 +2030,2,ELCTRI,autumn.night,3.203281465982185 +2030,2,ELCTRI,autumn.day,6.001752635595889 +2030,2,ELCTRI,autumn.peak,1.5488393825638174 +2030,2,ELCTRI,autumn.evening,1.9008483513729915 +2030,3,GASNAT,winter.night,-7.783808997678887 +2030,3,ELCTRI,winter.night,5.189205998452591 +2030,3,CO2EMT,winter.night,397.9861540513214 +2030,3,GASNAT,winter.day,-10.010898915527838 +2030,3,ELCTRI,winter.day,6.6739326103518914 +2030,3,CO2EMT,winter.day,511.8572615509383 +2030,3,GASNAT,winter.peak,-2.5761772783606895 +2030,3,ELCTRI,winter.peak,1.7174515189071262 +2030,3,CO2EMT,winter.peak,131.71994424258205 +2030,3,GASNAT,winter.evening,-3.5229053092829044 +2030,3,ELCTRI,winter.evening,2.3486035395219362 +2030,3,CO2EMT,winter.evening,180.12614846363488 +2030,3,GASNAT,peak.night,-8.382740663321101 +2030,3,ELCTRI,peak.night,5.5884937755474 +2030,3,CO2EMT,peak.night,428.6095301156078 +2030,3,GASNAT,peak.day,-8.886465236074457 +2030,3,ELCTRI,peak.day,5.924310157382971 +2030,3,CO2EMT,peak.day,454.3649675204869 +2030,3,GASNAT,peak.peak,-3.520722822271213 +2030,3,ELCTRI,peak.peak,2.3471485481808085 +2030,3,CO2EMT,peak.peak,180.0145579027271 +2030,3,GASNAT,peak.evening,-4.790137538321099 +2030,3,ELCTRI,peak.evening,3.1934250255473997 +2030,3,CO2EMT,peak.evening,244.9197323343578 +2030,3,GASNAT,summer.night,-0.0 +2030,3,ELCTRI,summer.night,0.0 +2030,3,CO2EMT,summer.night,0.0 +2030,3,GASNAT,summer.day,-0.0 +2030,3,ELCTRI,summer.day,0.0 +2030,3,CO2EMT,summer.day,0.0 +2030,3,GASNAT,summer.peak,-0.0 +2030,3,ELCTRI,summer.peak,0.0 +2030,3,CO2EMT,summer.peak,0.0 +2030,3,GASNAT,summer.evening,-0.0 +2030,3,ELCTRI,summer.evening,0.0 +2030,3,CO2EMT,summer.evening,0.0 +2030,3,GASNAT,autumn.night,-8.105533617588788 +2030,3,ELCTRI,autumn.night,5.403689078392525 +2030,3,CO2EMT,autumn.night,414.4359338673147 +2030,3,GASNAT,autumn.day,-11.621339862602872 +2030,3,ELCTRI,autumn.day,7.747559908401914 +2030,3,CO2EMT,autumn.day,594.1991071748848 +2030,3,GASNAT,autumn.peak,-3.592603125 +2030,3,ELCTRI,autumn.peak,2.39506875 +2030,3,CO2EMT,autumn.peak,183.68979778124998 +2030,3,GASNAT,autumn.evening,-4.526130821984218 +2030,3,ELCTRI,autumn.evening,3.0174205479894782 +2030,3,CO2EMT,autumn.evening,231.42106892805302 +2030,4,GASNAT,winter.night,-0.0 +2030,4,RSHEAT,winter.night,0.0 +2030,4,CO2EMT,winter.night,0.0 +2030,4,GASNAT,winter.day,-0.0 +2030,4,RSHEAT,winter.day,0.0 +2030,4,CO2EMT,winter.day,0.0 +2030,4,GASNAT,winter.peak,-9.194192711186016 +2030,4,RSHEAT,winter.peak,7.9949501836400145 +2030,4,CO2EMT,winter.peak,470.099073322941 +2030,4,GASNAT,winter.evening,-0.0 +2030,4,RSHEAT,winter.evening,0.0 +2030,4,CO2EMT,winter.evening,0.0 +2030,4,GASNAT,peak.night,-0.0 +2030,4,RSHEAT,peak.night,0.0 +2030,4,CO2EMT,peak.night,0.0 +2030,4,GASNAT,peak.day,-0.0 +2030,4,RSHEAT,peak.day,0.0 +2030,4,CO2EMT,peak.day,0.0 +2030,4,GASNAT,peak.peak,-0.0 +2030,4,RSHEAT,peak.peak,0.0 +2030,4,CO2EMT,peak.peak,0.0 +2030,4,GASNAT,peak.evening,-0.0 +2030,4,RSHEAT,peak.evening,0.0 +2030,4,CO2EMT,peak.evening,0.0 +2030,4,GASNAT,summer.night,-0.0 +2030,4,RSHEAT,summer.night,0.0 +2030,4,CO2EMT,summer.night,0.0 +2030,4,GASNAT,summer.day,-0.0 +2030,4,RSHEAT,summer.day,0.0 +2030,4,CO2EMT,summer.day,0.0 +2030,4,GASNAT,summer.peak,-0.0 +2030,4,RSHEAT,summer.peak,0.0 +2030,4,CO2EMT,summer.peak,0.0 +2030,4,GASNAT,summer.evening,-0.0 +2030,4,RSHEAT,summer.evening,0.0 +2030,4,CO2EMT,summer.evening,0.0 +2030,4,GASNAT,autumn.night,-0.0 +2030,4,RSHEAT,autumn.night,0.0 +2030,4,CO2EMT,autumn.night,0.0 +2030,4,GASNAT,autumn.day,-0.0 +2030,4,RSHEAT,autumn.day,0.0 +2030,4,CO2EMT,autumn.day,0.0 +2030,4,GASNAT,autumn.peak,-0.0 +2030,4,RSHEAT,autumn.peak,0.0 +2030,4,CO2EMT,autumn.peak,0.0 +2030,4,GASNAT,autumn.evening,-0.0 +2030,4,RSHEAT,autumn.evening,0.0 +2030,4,CO2EMT,autumn.evening,0.0 +2030,5,GASNAT,winter.night,-0.0 +2030,5,RSHEAT,winter.night,0.0 +2030,5,CO2EMT,winter.night,0.0 +2030,5,GASNAT,winter.day,-0.0 +2030,5,RSHEAT,winter.day,0.0 +2030,5,CO2EMT,winter.day,0.0 +2030,5,GASNAT,winter.peak,-35.9375 +2030,5,RSHEAT,winter.peak,31.25 +2030,5,CO2EMT,winter.peak,1837.484375 +2030,5,GASNAT,winter.evening,-0.0 +2030,5,RSHEAT,winter.evening,0.0 +2030,5,CO2EMT,winter.evening,0.0 +2030,5,GASNAT,peak.night,-0.0 +2030,5,RSHEAT,peak.night,0.0 +2030,5,CO2EMT,peak.night,0.0 +2030,5,GASNAT,peak.day,-0.0 +2030,5,RSHEAT,peak.day,0.0 +2030,5,CO2EMT,peak.day,0.0 +2030,5,GASNAT,peak.peak,-0.0 +2030,5,RSHEAT,peak.peak,0.0 +2030,5,CO2EMT,peak.peak,0.0 +2030,5,GASNAT,peak.evening,-0.0 +2030,5,RSHEAT,peak.evening,0.0 +2030,5,CO2EMT,peak.evening,0.0 +2030,5,GASNAT,summer.night,-0.0 +2030,5,RSHEAT,summer.night,0.0 +2030,5,CO2EMT,summer.night,0.0 +2030,5,GASNAT,summer.day,-0.0 +2030,5,RSHEAT,summer.day,0.0 +2030,5,CO2EMT,summer.day,0.0 +2030,5,GASNAT,summer.peak,-0.0 +2030,5,RSHEAT,summer.peak,0.0 +2030,5,CO2EMT,summer.peak,0.0 +2030,5,GASNAT,summer.evening,-0.0 +2030,5,RSHEAT,summer.evening,0.0 +2030,5,CO2EMT,summer.evening,0.0 +2030,5,GASNAT,autumn.night,-0.0 +2030,5,RSHEAT,autumn.night,0.0 +2030,5,CO2EMT,autumn.night,0.0 +2030,5,GASNAT,autumn.day,-0.0 +2030,5,RSHEAT,autumn.day,0.0 +2030,5,CO2EMT,autumn.day,0.0 +2030,5,GASNAT,autumn.peak,-0.0 +2030,5,RSHEAT,autumn.peak,0.0 +2030,5,CO2EMT,autumn.peak,0.0 +2030,5,GASNAT,autumn.evening,-0.0 +2030,5,RSHEAT,autumn.evening,0.0 +2030,5,CO2EMT,autumn.evening,0.0 +2030,6,GASNAT,winter.night,-0.0 +2030,6,RSHEAT,winter.night,0.0 +2030,6,CO2EMT,winter.night,0.0 +2030,6,GASNAT,winter.day,-99.48509864357999 +2030,6,RSHEAT,winter.day,86.5087814292 +2030,6,CO2EMT,winter.day,5086.673093646245 +2030,6,GASNAT,winter.peak,-35.9375 +2030,6,RSHEAT,winter.peak,31.25 +2030,6,CO2EMT,winter.peak,1837.484375 +2030,6,GASNAT,winter.evening,-23.523968569680008 +2030,6,RSHEAT,winter.evening,20.45562484320001 +2030,6,CO2EMT,winter.evening,1202.780512967739 +2030,6,GASNAT,peak.night,-0.0 +2030,6,RSHEAT,peak.night,0.0 +2030,6,CO2EMT,peak.night,0.0 +2030,6,GASNAT,peak.day,-0.0 +2030,6,RSHEAT,peak.day,0.0 +2030,6,CO2EMT,peak.day,0.0 +2030,6,GASNAT,peak.peak,-30.18935298630602 +2030,6,RSHEAT,peak.peak,26.251611292440018 +2030,6,CO2EMT,peak.peak,1543.581618189827 +2030,6,GASNAT,peak.evening,-0.0 +2030,6,RSHEAT,peak.evening,0.0 +2030,6,CO2EMT,peak.evening,0.0 +2030,6,GASNAT,summer.night,-0.0 +2030,6,RSHEAT,summer.night,0.0 +2030,6,CO2EMT,summer.night,0.0 +2030,6,GASNAT,summer.day,-0.0 +2030,6,RSHEAT,summer.day,0.0 +2030,6,CO2EMT,summer.day,0.0 +2030,6,GASNAT,summer.peak,-0.0 +2030,6,RSHEAT,summer.peak,0.0 +2030,6,CO2EMT,summer.peak,0.0 +2030,6,GASNAT,summer.evening,-0.0 +2030,6,RSHEAT,summer.evening,0.0 +2030,6,CO2EMT,summer.evening,0.0 +2030,6,GASNAT,autumn.night,-0.0 +2030,6,RSHEAT,autumn.night,0.0 +2030,6,CO2EMT,autumn.night,0.0 +2030,6,GASNAT,autumn.day,-0.0 +2030,6,RSHEAT,autumn.day,0.0 +2030,6,CO2EMT,autumn.day,0.0 +2030,6,GASNAT,autumn.peak,-14.079932516103002 +2030,6,RSHEAT,autumn.peak,12.243419579220003 +2030,6,CO2EMT,autumn.peak,719.9069495483466 +2030,6,GASNAT,autumn.evening,-0.0 +2030,6,RSHEAT,autumn.evening,0.0 +2030,6,CO2EMT,autumn.evening,0.0 +2030,7,ELCTRI,winter.night,-9.624518793997803 +2030,7,RSHEAT,winter.night,29.165208466660005 +2030,7,ELCTRI,winter.day,-13.749312543997803 +2030,7,RSHEAT,winter.day,41.664583466660005 +2030,7,ELCTRI,winter.peak,-4.12479375 +2030,7,RSHEAT,winter.peak,12.499375 +2030,7,ELCTRI,winter.evening,-5.499725043997801 +2030,7,RSHEAT,winter.evening,16.66583346666 +2030,7,ELCTRI,peak.night,-9.457314542454188 +2030,7,RSHEAT,peak.night,28.658528916527843 +2030,7,ELCTRI,peak.day,-13.749312543997803 +2030,7,RSHEAT,peak.day,41.664583466660005 +2030,7,ELCTRI,peak.peak,-4.12479375 +2030,7,RSHEAT,peak.peak,12.499375 +2030,7,ELCTRI,peak.evening,-5.499725043997801 +2030,7,RSHEAT,peak.evening,16.66583346666 +2030,7,ELCTRI,summer.night,-1.9319477961564002 +2030,7,RSHEAT,summer.night,5.85438726108 +2030,7,ELCTRI,summer.day,-3.2188600626534005 +2030,7,RSHEAT,summer.day,9.75412140198 +2030,7,ELCTRI,summer.peak,-1.0599640039494003 +2030,7,RSHEAT,summer.peak,3.2120121331800005 +2030,7,ELCTRI,summer.evening,-0.7892279633502001 +2030,7,RSHEAT,summer.evening,2.39159988894 +2030,7,ELCTRI,autumn.night,-9.624518793997803 +2030,7,RSHEAT,autumn.night,29.165208466660005 +2030,7,ELCTRI,autumn.day,-13.749312543997803 +2030,7,RSHEAT,autumn.day,41.664583466660005 +2030,7,ELCTRI,autumn.peak,-4.12479375 +2030,7,RSHEAT,autumn.peak,12.499375 +2030,7,ELCTRI,autumn.evening,-5.499725043997801 +2030,7,RSHEAT,autumn.evening,16.66583346666 +2030,8,GASNAT,winter.night,-43.845148578709995 +2030,8,RSHEAT,winter.night,38.1262161554 +2030,8,CO2EMT,winter.night,2241.8024468294425 +2030,8,GASNAT,winter.day,-119.79166705 +2030,8,RSHEAT,winter.day,104.166667 +2030,8,CO2EMT,winter.day,6124.947936266501 +2030,8,GASNAT,winter.peak,-35.9375 +2030,8,RSHEAT,winter.peak,31.25 +2030,8,CO2EMT,winter.peak,1837.484375 +2030,8,GASNAT,winter.evening,-47.916667049999994 +2030,8,RSHEAT,winter.evening,41.666667 +2030,8,CO2EMT,winter.evening,2449.9791862664997 +2030,8,GASNAT,peak.night,-21.252811326025988 +2030,8,RSHEAT,peak.night,18.480705500892164 +2030,8,CO2EMT,peak.night,1086.6562430997087 +2030,8,GASNAT,peak.day,-96.21279149075198 +2030,8,RSHEAT,peak.day,83.66329694848 +2030,8,CO2EMT,peak.day,4919.3600289221495 +2030,8,GASNAT,peak.peak,-35.9375 +2030,8,RSHEAT,peak.peak,31.25 +2030,8,CO2EMT,peak.peak,1837.484375 +2030,8,GASNAT,peak.evening,-29.670500177964005 +2030,8,RSHEAT,peak.evening,25.800434937360006 +2030,8,CO2EMT,peak.evening,1517.0526740992998 +2030,8,GASNAT,summer.night,-0.0 +2030,8,RSHEAT,summer.night,0.0 +2030,8,CO2EMT,summer.night,0.0 +2030,8,GASNAT,summer.day,-0.0 +2030,8,RSHEAT,summer.day,0.0 +2030,8,CO2EMT,summer.day,0.0 +2030,8,GASNAT,summer.peak,-0.0 +2030,8,RSHEAT,summer.peak,0.0 +2030,8,CO2EMT,summer.peak,0.0 +2030,8,GASNAT,summer.evening,-0.0 +2030,8,RSHEAT,summer.evening,0.0 +2030,8,CO2EMT,summer.evening,0.0 +2030,8,GASNAT,autumn.night,-10.492917792587003 +2030,8,RSHEAT,autumn.night,9.124276341380003 +2030,8,CO2EMT,autumn.night,536.5028867349736 +2030,8,GASNAT,autumn.day,-67.97422666003601 +2030,8,RSHEAT,autumn.day,59.10802318264001 +2030,8,CO2EMT,autumn.day,3475.5222091276414 +2030,8,GASNAT,autumn.peak,-35.9375 +2030,8,RSHEAT,autumn.peak,31.25 +2030,8,CO2EMT,autumn.peak,1837.484375 +2030,8,GASNAT,autumn.evening,-19.376214580347 +2030,8,RSHEAT,autumn.evening,16.84888224378 +2030,8,CO2EMT,autumn.evening,990.7058514931422 +2030,9,GASNAT,winter.night,-0.0 +2030,9,ELCTRI,winter.night,0.0 +2030,9,CO2EMT,winter.night,0.0 +2030,9,GASNAT,winter.day,-0.0 +2030,9,ELCTRI,winter.day,0.0 +2030,9,CO2EMT,winter.day,0.0 +2030,9,GASNAT,winter.peak,-0.6541381574816421 +2030,9,ELCTRI,winter.peak,0.4360921049877614 +2030,9,CO2EMT,winter.peak,33.44608399203636 +2030,9,GASNAT,winter.evening,-0.8721842169529965 +2030,9,ELCTRI,winter.evening,0.581456144635331 +2030,9,CO2EMT,winter.evening,44.59477901280671 +2030,9,GASNAT,peak.night,-1.5263223744346388 +2030,9,ELCTRI,peak.night,1.0175482496230925 +2030,9,CO2EMT,peak.night,78.04086300484308 +2030,9,GASNAT,peak.day,-2.180460531916281 +2030,9,ELCTRI,peak.day,1.4536403546108538 +2030,9,CO2EMT,peak.day,111.48694699687942 +2030,9,GASNAT,peak.peak,-0.0 +2030,9,ELCTRI,peak.peak,0.0 +2030,9,CO2EMT,peak.peak,0.0 +2030,9,GASNAT,peak.evening,-0.8721842169529959 +2030,9,ELCTRI,peak.evening,0.5814561446353306 +2030,9,CO2EMT,peak.evening,44.594779012806676 +2030,9,GASNAT,summer.night,-0.44265925791417715 +2030,9,ELCTRI,summer.night,0.29510617194278477 +2030,9,CO2EMT,summer.night,22.633167857151875 +2030,9,GASNAT,summer.day,-0.0 +2030,9,ELCTRI,summer.day,0.0 +2030,9,CO2EMT,summer.day,0.0 +2030,9,GASNAT,summer.peak,-0.0 +2030,9,ELCTRI,summer.peak,0.0 +2030,9,CO2EMT,summer.peak,0.0 +2030,9,GASNAT,summer.evening,-0.0 +2030,9,ELCTRI,summer.evening,0.0 +2030,9,CO2EMT,summer.evening,0.0 +2030,9,GASNAT,autumn.night,-1.5263223744346388 +2030,9,ELCTRI,autumn.night,1.0175482496230925 +2030,9,CO2EMT,autumn.night,78.04086300484308 +2030,9,GASNAT,autumn.day,-0.0 +2030,9,ELCTRI,autumn.day,0.0 +2030,9,CO2EMT,autumn.day,0.0 +2030,9,GASNAT,autumn.peak,-0.27132842615427455 +2030,9,ELCTRI,autumn.peak,0.18088561743618303 +2030,9,CO2EMT,autumn.peak,13.873022429268056 +2030,9,GASNAT,autumn.evening,-0.8721842169529965 +2030,9,ELCTRI,autumn.evening,0.581456144635331 +2030,9,CO2EMT,autumn.evening,44.59477901280671 +2040,0,GASPRD,winter.night,0.0 +2040,0,CO2EMT,winter.night,0.0 +2040,0,GASPRD,winter.day,360.96396982311984 +2040,0,CO2EMT,winter.day,1845.6087777056118 +2040,0,GASPRD,winter.peak,125.070625 +2040,0,CO2EMT,winter.peak,639.486105625 +2040,0,GASPRD,winter.evening,166.76083466742 +2040,0,CO2EMT,winter.evening,852.6481476545185 +2040,0,GASPRD,peak.night,0.0 +2040,0,CO2EMT,peak.night,0.0 +2040,0,GASPRD,peak.day,85.71569060312169 +2040,0,CO2EMT,peak.day,438.26432605376124 +2040,0,GASPRD,peak.peak,125.070625 +2040,0,CO2EMT,peak.peak,639.486105625 +2040,0,GASPRD,peak.evening,166.76083466742 +2040,0,CO2EMT,peak.evening,852.6481476545185 +2040,0,GASPRD,summer.night,0.0 +2040,0,CO2EMT,summer.night,0.0 +2040,0,GASPRD,summer.day,0.0 +2040,0,CO2EMT,summer.day,0.0 +2040,0,GASPRD,summer.peak,0.0 +2040,0,CO2EMT,summer.peak,0.0 +2040,0,GASPRD,summer.evening,28.106738155604855 +2040,0,CO2EMT,summer.evening,143.70975218960763 +2040,0,GASPRD,autumn.night,0.0 +2040,0,CO2EMT,autumn.night,0.0 +2040,0,GASPRD,autumn.day,11.030571054582538 +2040,0,CO2EMT,autumn.day,56.39930980208052 +2040,0,GASPRD,autumn.peak,125.070625 +2040,0,CO2EMT,autumn.peak,639.486105625 +2040,0,GASPRD,autumn.evening,166.76083466742 +2040,0,CO2EMT,autumn.evening,852.6481476545185 +2040,1,GASPRD,winter.night,-0.0 +2040,1,GASNAT,winter.night,0.0 +2040,1,CO2EMT,winter.night,0.0 +2040,1,GASPRD,winter.day,-363.2261000417943 +2040,1,GASNAT,winter.day,345.92961908742313 +2040,1,CO2EMT,winter.day,884.3690711969973 +2040,1,GASPRD,winter.peak,-124.10114062500001 +2040,1,GASNAT,winter.peak,118.1915625 +2040,1,CO2EMT,winter.peak,302.15672953125005 +2040,1,GASPRD,winter.evening,-165.4681888237455 +2040,1,GASNAT,winter.evening,157.58875126070998 +2040,1,CO2EMT,winter.evening,402.87564259800513 +2040,1,GASPRD,peak.night,-0.0 +2040,1,GASNAT,peak.night,0.0 +2040,1,CO2EMT,peak.night,0.0 +2040,1,GASPRD,peak.day,-87.97782082179617 +2040,1,GASNAT,peak.day,83.78840078266302 +2040,1,CO2EMT,peak.day,214.20504660087803 +2040,1,GASPRD,peak.peak,-124.10114062500001 +2040,1,GASNAT,peak.peak,118.1915625 +2040,1,CO2EMT,peak.peak,302.15672953125005 +2040,1,GASPRD,peak.evening,-165.4681888237455 +2040,1,GASNAT,peak.evening,157.58875126070998 +2040,1,CO2EMT,peak.evening,402.87564259800513 +2040,1,GASPRD,summer.night,-0.0 +2040,1,GASNAT,summer.night,0.0 +2040,1,CO2EMT,summer.night,0.0 +2040,1,GASPRD,summer.day,-0.0 +2040,1,GASNAT,summer.day,0.0 +2040,1,CO2EMT,summer.day,0.0 +2040,1,GASPRD,summer.peak,-0.0 +2040,1,GASNAT,summer.peak,0.0 +2040,1,CO2EMT,summer.peak,0.0 +2040,1,GASPRD,summer.evening,-28.106738155604855 +2040,1,GASNAT,summer.evening,26.768322052957004 +2040,1,CO2EMT,summer.evening,68.43321532838459 +2040,1,GASPRD,autumn.night,-0.0 +2040,1,GASNAT,autumn.night,0.0 +2040,1,CO2EMT,autumn.night,0.0 +2040,1,GASPRD,autumn.day,-13.292701273257007 +2040,1,GASNAT,autumn.day,12.659715498340006 +2040,1,CO2EMT,autumn.day,32.36456267150623 +2040,1,GASPRD,autumn.peak,-124.10114062500001 +2040,1,GASNAT,autumn.peak,118.1915625 +2040,1,CO2EMT,autumn.peak,302.15672953125005 +2040,1,GASPRD,autumn.evening,-165.4681888237455 +2040,1,GASNAT,autumn.evening,157.58875126070998 +2040,1,CO2EMT,autumn.evening,402.87564259800513 +2040,8,GASNAT,winter.night,-0.0 +2040,8,RSHEAT,winter.night,0.0 +2040,8,CO2EMT,winter.night,0.0 +2040,8,GASNAT,winter.day,-0.0 +2040,8,RSHEAT,winter.day,0.0 +2040,8,CO2EMT,winter.day,0.0 +2040,8,GASNAT,winter.peak,-0.4189369311860147 +2040,8,RSHEAT,winter.peak,0.36429298364001284 +2040,8,CO2EMT,winter.peak,21.420245291540937 +2040,8,GASNAT,winter.evening,-0.0 +2040,8,RSHEAT,winter.evening,0.0 +2040,8,CO2EMT,winter.evening,0.0 +2040,8,GASNAT,peak.night,-0.0 +2040,8,RSHEAT,peak.night,0.0 +2040,8,CO2EMT,peak.night,0.0 +2040,8,GASNAT,peak.day,-0.0 +2040,8,RSHEAT,peak.day,0.0 +2040,8,CO2EMT,peak.day,0.0 +2040,8,GASNAT,peak.peak,-0.0 +2040,8,RSHEAT,peak.peak,0.0 +2040,8,CO2EMT,peak.peak,0.0 +2040,8,GASNAT,peak.evening,-0.0 +2040,8,RSHEAT,peak.evening,0.0 +2040,8,CO2EMT,peak.evening,0.0 +2040,8,GASNAT,summer.night,-0.0 +2040,8,RSHEAT,summer.night,0.0 +2040,8,CO2EMT,summer.night,0.0 +2040,8,GASNAT,summer.day,-0.0 +2040,8,RSHEAT,summer.day,0.0 +2040,8,CO2EMT,summer.day,0.0 +2040,8,GASNAT,summer.peak,-0.0 +2040,8,RSHEAT,summer.peak,0.0 +2040,8,CO2EMT,summer.peak,0.0 +2040,8,GASNAT,summer.evening,-0.0 +2040,8,RSHEAT,summer.evening,0.0 +2040,8,CO2EMT,summer.evening,0.0 +2040,8,GASNAT,autumn.night,-0.0 +2040,8,RSHEAT,autumn.night,0.0 +2040,8,CO2EMT,autumn.night,0.0 +2040,8,GASNAT,autumn.day,-0.0 +2040,8,RSHEAT,autumn.day,0.0 +2040,8,CO2EMT,autumn.day,0.0 +2040,8,GASNAT,autumn.peak,-0.0 +2040,8,RSHEAT,autumn.peak,0.0 +2040,8,CO2EMT,autumn.peak,0.0 +2040,8,GASNAT,autumn.evening,-0.0 +2040,8,RSHEAT,autumn.evening,0.0 +2040,8,CO2EMT,autumn.evening,0.0 +2040,10,GASNAT,winter.night,-0.0 +2040,10,RSHEAT,winter.night,0.0 +2040,10,CO2EMT,winter.night,0.0 +2040,10,GASNAT,winter.day,-0.0 +2040,10,RSHEAT,winter.day,0.0 +2040,10,CO2EMT,winter.day,0.0 +2040,10,GASNAT,winter.peak,-35.9375 +2040,10,RSHEAT,winter.peak,31.25 +2040,10,CO2EMT,winter.peak,1837.484375 +2040,10,GASNAT,winter.evening,-0.0 +2040,10,RSHEAT,winter.evening,0.0 +2040,10,CO2EMT,winter.evening,0.0 +2040,10,GASNAT,peak.night,-0.0 +2040,10,RSHEAT,peak.night,0.0 +2040,10,CO2EMT,peak.night,0.0 +2040,10,GASNAT,peak.day,-0.0 +2040,10,RSHEAT,peak.day,0.0 +2040,10,CO2EMT,peak.day,0.0 +2040,10,GASNAT,peak.peak,-0.0 +2040,10,RSHEAT,peak.peak,0.0 +2040,10,CO2EMT,peak.peak,0.0 +2040,10,GASNAT,peak.evening,-0.0 +2040,10,RSHEAT,peak.evening,0.0 +2040,10,CO2EMT,peak.evening,0.0 +2040,10,GASNAT,summer.night,-0.0 +2040,10,RSHEAT,summer.night,0.0 +2040,10,CO2EMT,summer.night,0.0 +2040,10,GASNAT,summer.day,-0.0 +2040,10,RSHEAT,summer.day,0.0 +2040,10,CO2EMT,summer.day,0.0 +2040,10,GASNAT,summer.peak,-0.0 +2040,10,RSHEAT,summer.peak,0.0 +2040,10,CO2EMT,summer.peak,0.0 +2040,10,GASNAT,summer.evening,-0.0 +2040,10,RSHEAT,summer.evening,0.0 +2040,10,CO2EMT,summer.evening,0.0 +2040,10,GASNAT,autumn.night,-0.0 +2040,10,RSHEAT,autumn.night,0.0 +2040,10,CO2EMT,autumn.night,0.0 +2040,10,GASNAT,autumn.day,-0.0 +2040,10,RSHEAT,autumn.day,0.0 +2040,10,CO2EMT,autumn.day,0.0 +2040,10,GASNAT,autumn.peak,-0.0 +2040,10,RSHEAT,autumn.peak,0.0 +2040,10,CO2EMT,autumn.peak,0.0 +2040,10,GASNAT,autumn.evening,-0.0 +2040,10,RSHEAT,autumn.evening,0.0 +2040,10,CO2EMT,autumn.evening,0.0 +2040,11,GASNAT,winter.night,-0.0 +2040,11,RSHEAT,winter.night,0.0 +2040,11,CO2EMT,winter.night,0.0 +2040,11,GASNAT,winter.day,-53.61473373523902 +2040,11,RSHEAT,winter.day,46.621507595860024 +2040,11,CO2EMT,winter.day,2741.3213358827716 +2040,11,GASNAT,winter.peak,-35.9375 +2040,11,RSHEAT,winter.peak,31.25 +2040,11,CO2EMT,winter.peak,1837.484375 +2040,11,GASNAT,winter.evening,-3.5921756613390228 +2040,11,RSHEAT,winter.evening,3.12363100986002 +2040,11,CO2EMT,winter.evening,183.66794156426425 +2040,11,GASNAT,peak.night,-0.0 +2040,11,RSHEAT,peak.night,0.0 +2040,11,CO2EMT,peak.night,0.0 +2040,11,GASNAT,peak.day,-0.0 +2040,11,RSHEAT,peak.day,0.0 +2040,11,CO2EMT,peak.day,0.0 +2040,11,GASNAT,peak.peak,-16.46170960630601 +2040,11,RSHEAT,peak.peak,14.314530092440009 +2040,11,CO2EMT,peak.peak,841.6872121704263 +2040,11,GASNAT,peak.evening,-0.0 +2040,11,RSHEAT,peak.evening,0.0 +2040,11,CO2EMT,peak.evening,0.0 +2040,11,GASNAT,summer.night,-0.0 +2040,11,RSHEAT,summer.night,0.0 +2040,11,CO2EMT,summer.night,0.0 +2040,11,GASNAT,summer.day,-0.0 +2040,11,RSHEAT,summer.day,0.0 +2040,11,CO2EMT,summer.day,0.0 +2040,11,GASNAT,summer.peak,-0.0 +2040,11,RSHEAT,summer.peak,0.0 +2040,11,CO2EMT,summer.peak,0.0 +2040,11,GASNAT,summer.evening,-0.0 +2040,11,RSHEAT,summer.evening,0.0 +2040,11,CO2EMT,summer.evening,0.0 +2040,11,GASNAT,autumn.night,-0.0 +2040,11,RSHEAT,autumn.night,0.0 +2040,11,CO2EMT,autumn.night,0.0 +2040,11,GASNAT,autumn.day,-0.0 +2040,11,RSHEAT,autumn.day,0.0 +2040,11,CO2EMT,autumn.day,0.0 +2040,11,GASNAT,autumn.peak,-0.0 +2040,11,RSHEAT,autumn.peak,0.0 +2040,11,CO2EMT,autumn.peak,0.0 +2040,11,GASNAT,autumn.evening,-0.0 +2040,11,RSHEAT,autumn.evening,0.0 +2040,11,CO2EMT,autumn.evening,0.0 +2040,12,GASNAT,winter.night,-1.0632512703690025 +2040,12,RSHEAT,winter.night,0.9245663220600022 +2040,12,CO2EMT,winter.night,54.3640374539671 +2040,12,GASNAT,winter.day,-119.79166705 +2040,12,RSHEAT,winter.day,104.166667 +2040,12,CO2EMT,winter.day,6124.947936266501 +2040,12,GASNAT,winter.peak,-35.9375 +2040,12,RSHEAT,winter.peak,31.25 +2040,12,CO2EMT,winter.peak,1837.484375 +2040,12,GASNAT,winter.evening,-47.916667049999994 +2040,12,RSHEAT,winter.evening,41.666667 +2040,12,CO2EMT,winter.evening,2449.9791862664997 +2040,12,GASNAT,peak.night,-0.0 +2040,12,RSHEAT,peak.night,0.0 +2040,12,CO2EMT,peak.night,0.0 +2040,12,GASNAT,peak.day,-38.36399852241101 +2040,12,RSHEAT,peak.day,33.35999871514001 +2040,12,CO2EMT,peak.day,1961.551244450875 +2040,12,GASNAT,peak.peak,-35.9375 +2040,12,RSHEAT,peak.peak,31.25 +2040,12,CO2EMT,peak.peak,1837.484375 +2040,12,GASNAT,peak.evening,-5.6730124496230125 +2040,12,RSHEAT,peak.evening,4.933054304020011 +2040,12,CO2EMT,peak.evening,290.06112654922464 +2040,12,GASNAT,summer.night,-0.0 +2040,12,RSHEAT,summer.night,0.0 +2040,12,CO2EMT,summer.night,0.0 +2040,12,GASNAT,summer.day,-0.0 +2040,12,RSHEAT,summer.day,0.0 +2040,12,CO2EMT,summer.day,0.0 +2040,12,GASNAT,summer.peak,-0.0 +2040,12,RSHEAT,summer.peak,0.0 +2040,12,CO2EMT,summer.peak,0.0 +2040,12,GASNAT,summer.evening,-0.0 +2040,12,RSHEAT,summer.evening,0.0 +2040,12,CO2EMT,summer.evening,0.0 +2040,12,GASNAT,autumn.night,-0.0 +2040,12,RSHEAT,autumn.night,0.0 +2040,12,CO2EMT,autumn.night,0.0 +2040,12,GASNAT,autumn.day,-7.376833871695004 +2040,12,RSHEAT,autumn.day,6.4146381493000035 +2040,12,CO2EMT,autumn.day,377.17751585976555 +2040,12,GASNAT,autumn.peak,-34.721779201103004 +2040,12,RSHEAT,autumn.peak,30.192851479220003 +2040,12,CO2EMT,autumn.peak,1775.3245705523966 +2040,12,GASNAT,autumn.evening,-0.0 +2040,12,RSHEAT,autumn.evening,0.0 +2040,12,CO2EMT,autumn.evening,0.0 +2040,13,GASNAT,winter.night,-83.85416705 +2040,13,RSHEAT,winter.night,72.916667 +2040,13,CO2EMT,winter.night,4287.463561266501 +2040,13,GASNAT,winter.day,-119.79166705 +2040,13,RSHEAT,winter.day,104.166667 +2040,13,CO2EMT,winter.day,6124.947936266501 +2040,13,GASNAT,winter.peak,-35.9375 +2040,13,RSHEAT,winter.peak,31.25 +2040,13,CO2EMT,winter.peak,1837.484375 +2040,13,GASNAT,winter.evening,-47.916667049999994 +2040,13,RSHEAT,winter.evening,41.666667 +2040,13,CO2EMT,winter.evening,2449.9791862664997 +2040,13,GASNAT,peak.night,-59.486659865033 +2040,13,RSHEAT,peak.night,51.727530317420005 +2040,13,CO2EMT,peak.night,3041.5529188991377 +2040,13,GASNAT,peak.day,-119.79166705 +2040,13,RSHEAT,peak.day,104.166667 +2040,13,CO2EMT,peak.day,6124.947936266501 +2040,13,GASNAT,peak.peak,-35.9375 +2040,13,RSHEAT,peak.peak,31.25 +2040,13,CO2EMT,peak.peak,1837.484375 +2040,13,GASNAT,peak.evening,-47.916667049999994 +2040,13,RSHEAT,peak.evening,41.666667 +2040,13,CO2EMT,peak.evening,2449.9791862664997 +2040,13,GASNAT,summer.night,-7.3878574402420005 +2040,13,RSHEAT,summer.night,6.424223861080001 +2040,13,CO2EMT,summer.night,377.7411509195735 +2040,13,GASNAT,summer.day,-12.309069277277 +2040,13,RSHEAT,summer.day,10.70353850198 +2040,13,CO2EMT,summer.day,629.362712147173 +2040,13,GASNAT,summer.peak,-4.053351218157 +2040,13,RSHEAT,summer.peak,3.5246532331800005 +2040,13,CO2EMT,summer.peak,207.24784778436745 +2040,13,GASNAT,summer.evening,-3.0180441172809997 +2040,13,RSHEAT,summer.evening,2.62438618894 +2040,13,CO2EMT,summer.evening,154.31259571657753 +2040,13,GASNAT,autumn.night,-48.318849199246 +2040,13,RSHEAT,autumn.night,42.016390608040005 +2040,13,CO2EMT,autumn.night,2470.5427595574483 +2040,13,GASNAT,autumn.day,-119.79166705 +2040,13,RSHEAT,autumn.day,104.166667 +2040,13,CO2EMT,autumn.day,6124.947936266501 +2040,13,GASNAT,autumn.peak,-35.9375 +2040,13,RSHEAT,autumn.peak,31.25 +2040,13,CO2EMT,autumn.peak,1837.484375 +2040,13,GASNAT,autumn.evening,-42.293399937006 +2040,13,RSHEAT,autumn.evening,36.77686951044 +2040,13,CO2EMT,autumn.evening,2162.461538779117 diff --git a/tests/data/simple_divisible/commodity_prices.csv b/tests/data/simple_divisible/commodity_prices.csv new file mode 100644 index 00000000..6f51160f --- /dev/null +++ b/tests/data/simple_divisible/commodity_prices.csv @@ -0,0 +1,177 @@ +milestone_year,commodity_id,region_id,time_slice,price +2020,GASPRD,GBR,winter.night,2.20452 +2020,GASPRD,GBR,winter.day,2.20452 +2020,GASPRD,GBR,winter.peak,2.20452 +2020,GASPRD,GBR,winter.evening,2.20452 +2020,GASPRD,GBR,peak.night,2.20452 +2020,GASPRD,GBR,peak.day,2.20452 +2020,GASPRD,GBR,peak.peak,2.20452 +2020,GASPRD,GBR,peak.evening,2.20452 +2020,GASPRD,GBR,summer.night,2.20452 +2020,GASPRD,GBR,summer.day,2.20452 +2020,GASPRD,GBR,summer.peak,2.20452 +2020,GASPRD,GBR,summer.evening,2.20452 +2020,GASPRD,GBR,autumn.night,2.20452 +2020,GASPRD,GBR,autumn.day,2.20452 +2020,GASPRD,GBR,autumn.peak,2.20452 +2020,GASPRD,GBR,autumn.evening,2.20452 +2020,GASNAT,GBR,winter.night,2.9170059999999998 +2020,GASNAT,GBR,winter.day,2.9170059999999998 +2020,GASNAT,GBR,winter.peak,2.9170059999999998 +2020,GASNAT,GBR,winter.evening,2.9170059999999998 +2020,GASNAT,GBR,peak.night,2.9170059999999998 +2020,GASNAT,GBR,peak.day,2.9170059999999998 +2020,GASNAT,GBR,peak.peak,2.9170059999999998 +2020,GASNAT,GBR,peak.evening,2.9170059999999998 +2020,GASNAT,GBR,summer.night,2.9170059999999998 +2020,GASNAT,GBR,summer.day,2.9170059999999998 +2020,GASNAT,GBR,summer.peak,2.9170059999999998 +2020,GASNAT,GBR,summer.evening,2.9170059999999998 +2020,GASNAT,GBR,autumn.night,2.9170059999999998 +2020,GASNAT,GBR,autumn.day,2.9170059999999998 +2020,GASNAT,GBR,autumn.peak,2.9170059999999998 +2020,GASNAT,GBR,autumn.evening,2.9170059999999998 +2020,ELCTRI,GBR,winter.night,7.993308999999999 +2020,ELCTRI,GBR,winter.day,7.993308999999999 +2020,ELCTRI,GBR,winter.peak,7.993308999999999 +2020,ELCTRI,GBR,winter.evening,7.993308999999999 +2020,ELCTRI,GBR,peak.night,17.26223303030303 +2020,ELCTRI,GBR,peak.day,7.993308999999999 +2020,ELCTRI,GBR,peak.peak,7.993308999999999 +2020,ELCTRI,GBR,peak.evening,17.26223303030303 +2020,ELCTRI,GBR,summer.night,7.993308999999999 +2020,ELCTRI,GBR,summer.day,0.4 +2020,ELCTRI,GBR,summer.peak,0.4 +2020,ELCTRI,GBR,summer.evening,0.4 +2020,ELCTRI,GBR,autumn.night,17.26223303030303 +2020,ELCTRI,GBR,autumn.day,7.993308999999999 +2020,ELCTRI,GBR,autumn.peak,17.26223303030303 +2020,ELCTRI,GBR,autumn.evening,17.26223303030303 +2020,RSHEAT,GBR,winter.night,5.8665369 +2020,RSHEAT,GBR,winter.day,5.8665369 +2020,RSHEAT,GBR,winter.peak,5.8665369 +2020,RSHEAT,GBR,winter.evening,5.8665369 +2020,RSHEAT,GBR,peak.night,5.8665369 +2020,RSHEAT,GBR,peak.day,5.8665369 +2020,RSHEAT,GBR,peak.peak,5.8665369 +2020,RSHEAT,GBR,peak.evening,5.8665369 +2020,RSHEAT,GBR,summer.night,2.80779197 +2020,RSHEAT,GBR,summer.day,0.30200000000000005 +2020,RSHEAT,GBR,summer.peak,0.30200000000000005 +2020,RSHEAT,GBR,summer.evening,0.30200000000000005 +2020,RSHEAT,GBR,autumn.night,5.8665369 +2020,RSHEAT,GBR,autumn.day,5.8665369 +2020,RSHEAT,GBR,autumn.peak,5.8665369 +2020,RSHEAT,GBR,autumn.evening,5.8665369 +2030,GASPRD,GBR,winter.night,2.20452 +2030,GASPRD,GBR,winter.day,2.20452 +2030,GASPRD,GBR,winter.peak,2.20452 +2030,GASPRD,GBR,winter.evening,2.20452 +2030,GASPRD,GBR,peak.night,2.20452 +2030,GASPRD,GBR,peak.day,2.20452 +2030,GASPRD,GBR,peak.peak,2.20452 +2030,GASPRD,GBR,peak.evening,2.20452 +2030,GASPRD,GBR,summer.night,2.20452 +2030,GASPRD,GBR,summer.day,2.20452 +2030,GASPRD,GBR,summer.peak,2.20452 +2030,GASPRD,GBR,summer.evening,2.20452 +2030,GASPRD,GBR,autumn.night,2.20452 +2030,GASPRD,GBR,autumn.day,2.20452 +2030,GASPRD,GBR,autumn.peak,2.20452 +2030,GASPRD,GBR,autumn.evening,2.20452 +2030,GASNAT,GBR,winter.night,2.9170059999999998 +2030,GASNAT,GBR,winter.day,2.9170059999999998 +2030,GASNAT,GBR,winter.peak,2.9170059999999998 +2030,GASNAT,GBR,winter.evening,2.9170059999999998 +2030,GASNAT,GBR,peak.night,2.9170059999999998 +2030,GASNAT,GBR,peak.day,2.9170059999999998 +2030,GASNAT,GBR,peak.peak,2.9170059999999998 +2030,GASNAT,GBR,peak.evening,2.9170059999999998 +2030,GASNAT,GBR,summer.night,2.9170059999999998 +2030,GASNAT,GBR,summer.day,2.9170059999999998 +2030,GASNAT,GBR,summer.peak,2.9170059999999998 +2030,GASNAT,GBR,summer.evening,2.9170059999999998 +2030,GASNAT,GBR,autumn.night,2.9170059999999998 +2030,GASNAT,GBR,autumn.day,2.9170059999999998 +2030,GASNAT,GBR,autumn.peak,2.9170059999999998 +2030,GASNAT,GBR,autumn.evening,2.9170059999999998 +2030,ELCTRI,GBR,winter.night,7.993308999999999 +2030,ELCTRI,GBR,winter.day,7.993308999999999 +2030,ELCTRI,GBR,winter.peak,7.993308999999999 +2030,ELCTRI,GBR,winter.evening,7.993308999999999 +2030,ELCTRI,GBR,peak.night,17.26223303030303 +2030,ELCTRI,GBR,peak.day,7.993308999999999 +2030,ELCTRI,GBR,peak.peak,7.993308999999999 +2030,ELCTRI,GBR,peak.evening,7.993308999999999 +2030,ELCTRI,GBR,summer.night,7.993308999999999 +2030,ELCTRI,GBR,summer.day,0.4 +2030,ELCTRI,GBR,summer.peak,0.4 +2030,ELCTRI,GBR,summer.evening,0.4 +2030,ELCTRI,GBR,autumn.night,7.993308999999999 +2030,ELCTRI,GBR,autumn.day,7.993308999999999 +2030,ELCTRI,GBR,autumn.peak,7.993308999999999 +2030,ELCTRI,GBR,autumn.evening,7.993308999999999 +2030,RSHEAT,GBR,winter.night,5.8665369 +2030,RSHEAT,GBR,winter.day,5.8665369 +2030,RSHEAT,GBR,winter.peak,5.8665369 +2030,RSHEAT,GBR,winter.evening,5.8665369 +2030,RSHEAT,GBR,peak.night,5.8665369 +2030,RSHEAT,GBR,peak.day,5.8665369 +2030,RSHEAT,GBR,peak.peak,5.8665369 +2030,RSHEAT,GBR,peak.evening,5.8665369 +2030,RSHEAT,GBR,summer.night,2.80779197 +2030,RSHEAT,GBR,summer.day,0.30200000000000005 +2030,RSHEAT,GBR,summer.peak,0.30200000000000005 +2030,RSHEAT,GBR,summer.evening,0.30200000000000005 +2030,RSHEAT,GBR,autumn.night,5.8665369 +2030,RSHEAT,GBR,autumn.day,5.8665369 +2030,RSHEAT,GBR,autumn.peak,5.8665369 +2030,RSHEAT,GBR,autumn.evening,5.8665369 +2040,GASPRD,GBR,winter.night,2.20452 +2040,GASPRD,GBR,winter.day,2.20452 +2040,GASPRD,GBR,winter.peak,2.20452 +2040,GASPRD,GBR,winter.evening,2.20452 +2040,GASPRD,GBR,peak.night,2.20452 +2040,GASPRD,GBR,peak.day,2.20452 +2040,GASPRD,GBR,peak.peak,2.20452 +2040,GASPRD,GBR,peak.evening,2.20452 +2040,GASPRD,GBR,summer.night,2.20452 +2040,GASPRD,GBR,summer.day,2.20452 +2040,GASPRD,GBR,summer.peak,2.20452 +2040,GASPRD,GBR,summer.evening,2.20452 +2040,GASPRD,GBR,autumn.night,2.20452 +2040,GASPRD,GBR,autumn.day,2.20452 +2040,GASPRD,GBR,autumn.peak,2.20452 +2040,GASPRD,GBR,autumn.evening,2.20452 +2040,GASNAT,GBR,winter.night,2.9170059999999998 +2040,GASNAT,GBR,winter.day,2.9170059999999998 +2040,GASNAT,GBR,winter.peak,2.9170059999999998 +2040,GASNAT,GBR,winter.evening,2.9170059999999998 +2040,GASNAT,GBR,peak.night,2.9170059999999998 +2040,GASNAT,GBR,peak.day,2.9170059999999998 +2040,GASNAT,GBR,peak.peak,2.9170059999999998 +2040,GASNAT,GBR,peak.evening,2.9170059999999998 +2040,GASNAT,GBR,summer.night,2.9170059999999998 +2040,GASNAT,GBR,summer.day,2.9170059999999998 +2040,GASNAT,GBR,summer.peak,2.9170059999999998 +2040,GASNAT,GBR,summer.evening,2.9170059999999998 +2040,GASNAT,GBR,autumn.night,2.9170059999999998 +2040,GASNAT,GBR,autumn.day,2.9170059999999998 +2040,GASNAT,GBR,autumn.peak,2.9170059999999998 +2040,GASNAT,GBR,autumn.evening,2.9170059999999998 +2040,RSHEAT,GBR,winter.night,5.8665369 +2040,RSHEAT,GBR,winter.day,5.8665369 +2040,RSHEAT,GBR,winter.peak,5.8665369 +2040,RSHEAT,GBR,winter.evening,5.8665369 +2040,RSHEAT,GBR,peak.night,5.8665369 +2040,RSHEAT,GBR,peak.day,5.8665369 +2040,RSHEAT,GBR,peak.peak,5.8665369 +2040,RSHEAT,GBR,peak.evening,5.8665369 +2040,RSHEAT,GBR,summer.night,5.8665369 +2040,RSHEAT,GBR,summer.day,5.8665369 +2040,RSHEAT,GBR,summer.peak,5.8665369 +2040,RSHEAT,GBR,summer.evening,5.8665369 +2040,RSHEAT,GBR,autumn.night,5.8665369 +2040,RSHEAT,GBR,autumn.day,5.8665369 +2040,RSHEAT,GBR,autumn.peak,5.8665369 +2040,RSHEAT,GBR,autumn.evening,5.8665369 diff --git a/tests/regression.rs b/tests/regression.rs index 45b47a24..31b67c9b 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -1,8 +1,11 @@ //! Common code for running regression tests. +use anyhow::Result; use float_cmp::approx_eq; use itertools::Itertools; use muse2::cli::RunOpts; use muse2::cli::example::handle_example_run_command; +use muse2::cli::handle_run_command; +use muse2::patch::{FilePatch, ModelPatch}; use muse2::settings::Settings; use std::env; use std::fs::{File, read_dir}; @@ -18,23 +21,48 @@ const FLOAT_CMP_TOLERANCE: f64 = 1e-10; /// Run a regression test for an example model #[allow(dead_code)] pub fn run_regression_test(example_name: &str) { - run_regression_test_debug_opt(example_name, false); + run_regression_test_common(example_name, false, |opts, settings| { + handle_example_run_command(example_name, opts, settings) + }); } /// Run a regression test for an example model #[allow(dead_code)] pub fn run_regression_test_with_debug_files(example_name: &str) { - run_regression_test_debug_opt(example_name, true); + run_regression_test_common(example_name, true, |opts, settings| { + handle_example_run_command(example_name, opts, settings) + }); } -fn run_regression_test_debug_opt(example_name: &str, debug_model: bool) { +/// Run a regression test for an example model with file patches applied +#[allow(dead_code)] +pub fn run_regression_test_with_patches( + example_name: &str, + patches: Vec, + test_case_name: &str, +) { + // Patch model to a temporary directory + let model_dir = ModelPatch::from_example(example_name) + .with_file_patches(patches) + .build_to_tempdir() + .unwrap(); + + run_regression_test_common(test_case_name, false, |opts, settings| { + handle_run_command(model_dir.path(), opts, settings) + }); +} + +fn run_regression_test_common(test_name: &str, debug_model: bool, run_fn: F) +where + F: FnOnce(&RunOpts, Option) -> Result<()>, +{ unsafe { env::set_var("MUSE2_LOG_LEVEL", "off") }; // Allow user to set output dir for regression tests so they can examine results. This is // principally intended for use by CI. let tmp: TempDir; let output_dir = if let Ok(dir) = env::var("MUSE2_TEST_OUTPUT_DIR") { - [&dir, example_name].iter().collect() + [&dir, test_name].iter().collect() } else { tmp = tempdir().unwrap(); tmp.path().to_path_buf() @@ -45,9 +73,10 @@ fn run_regression_test_debug_opt(example_name: &str, debug_model: bool) { overwrite: false, debug_model: Some(true), // NB: Always enable this as it helps to have the files for debugging }; - handle_example_run_command(example_name, &opts, Some(Settings::default())).unwrap(); - let test_data_dir = PathBuf::from(format!("tests/data/{example_name}")); + run_fn(&opts, Some(Settings::default())).unwrap(); + + let test_data_dir = PathBuf::from(format!("tests/data/{test_name}")); compare_output_dirs(&output_dir, &test_data_dir, debug_model); } diff --git a/tests/regression_simple_divisible.rs b/tests/regression_simple_divisible.rs new file mode 100644 index 00000000..b79e0db6 --- /dev/null +++ b/tests/regression_simple_divisible.rs @@ -0,0 +1,13 @@ +//! A regression test for a patched version of the "simple" example with divisible gas boilers. +mod regression; +use muse2::patch::FilePatch; +use regression::run_regression_test_with_patches; + +#[test] +fn regression_simple() { + let patch = FilePatch::new("processes.csv") + .with_deletion("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,") + .with_addition("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,1000"); + + run_regression_test_with_patches("simple", vec![patch], "simple_divisible"); +}