diff --git a/src/asset.rs b/src/asset.rs index 7a59d54e4..a56ea7d7f 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -1100,6 +1100,41 @@ impl AssetRef { f(Some(&self), child); } } + + /// Get an [`AssetRef`] representing a subset of this parent's children. + /// + /// # Panics + /// + /// Panics if this asset is not a parent asset or `num_units` is zero or exceeds the total + /// capacity of this asset. + pub fn make_partial_parent(&self, num_units: u32) -> Self { + assert!( + self.is_parent(), + "Cannot make a partial parent from a non-parent asset" + ); + assert!( + num_units > 0, + "Cannot make a partial parent with zero units" + ); + + let (max_num_units, unit_size) = match self.capacity() { + AssetCapacity::Discrete(max_num_units, unit_size) => (max_num_units, unit_size), + // We know asset capacity type is discrete as this is a parent asset + AssetCapacity::Continuous(_) => unreachable!(), + }; + match num_units.cmp(&max_num_units) { + // Make a new Asset with fewer units + Ordering::Less => Self::from(Asset { + capacity: Cell::new(AssetCapacity::Discrete(num_units, unit_size)), + ..Asset::clone(self) + }), + // Same number of units as self + Ordering::Equal => self.clone(), + Ordering::Greater => { + panic!("Cannot make a partial parent with more units than original") + } + } + } } impl From> for AssetRef { @@ -1429,6 +1464,64 @@ mod tests { assert_eq!(count, 1); } + #[fixture] + fn parent_asset(asset_divisible: Asset) -> AssetRef { + let asset = AssetRef::from(asset_divisible); + let mut parent = None; + + asset.into_for_each_child(&mut 0, |maybe_parent, _| { + if parent.is_none() { + parent = maybe_parent.cloned(); + } + }); + + parent.expect("Divisible asset should create a parent") + } + + #[rstest] + #[case::subset_of_children(2, false)] + #[case::all_children(3, true)] + fn make_partial_parent( + parent_asset: AssetRef, + #[case] num_units: u32, + #[case] expect_same_asset: bool, + ) { + let parent = parent_asset; + assert!(parent.is_parent()); + + let partial_parent = parent.make_partial_parent(num_units); + + assert!(partial_parent.is_parent()); + assert_eq!( + partial_parent.capacity(), + AssetCapacity::Discrete(num_units, Capacity(4.0)) + ); + assert_eq!(partial_parent.num_children(), Some(num_units)); + assert_eq!(partial_parent.group_id(), parent.group_id()); + assert_eq!(partial_parent.agent_id(), parent.agent_id()); + assert_eq!(Rc::ptr_eq(&partial_parent.0, &parent.0), expect_same_asset); + assert_eq!(parent.capacity(), AssetCapacity::Discrete(3, Capacity(4.0))); + } + + #[rstest] + #[should_panic(expected = "Cannot make a partial parent from a non-parent asset")] + fn make_partial_parent_panics_for_non_parent_asset(asset_divisible: Asset) { + let asset = AssetRef::from(asset_divisible); + asset.make_partial_parent(1); + } + + #[rstest] + #[should_panic(expected = "Cannot make a partial parent with zero units")] + fn make_partial_parent_panics_for_zero_units(parent_asset: AssetRef) { + parent_asset.make_partial_parent(0); + } + + #[rstest] + #[should_panic(expected = "Cannot make a partial parent with more units than original")] + fn make_partial_parent_panics_for_too_many_units(parent_asset: AssetRef) { + parent_asset.make_partial_parent(4); + } + #[rstest] fn asset_commission(process: Process) { // Test successful commissioning of Future asset diff --git a/src/simulation/optimisation.rs b/src/simulation/optimisation.rs index e14926033..372750559 100644 --- a/src/simulation/optimisation.rs +++ b/src/simulation/optimisation.rs @@ -17,9 +17,9 @@ use crate::units::{ use anyhow::{Result, bail, ensure}; use highs::{HighsModelStatus, HighsStatus, RowProblem as Problem, Sense}; use indexmap::{IndexMap, IndexSet}; -use itertools::{Itertools, chain, iproduct}; +use itertools::{chain, iproduct}; use std::cell::Cell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::error::Error; use std::fmt; use std::ops::Range; @@ -434,15 +434,30 @@ fn filter_input_prices( /// /// Child assets are converted to their parents and non-divisible assets are returned as is. Each /// parent asset is returned only once. -fn get_parent_or_self(assets: &[AssetRef]) -> impl Iterator { - let mut parents = HashSet::new(); - assets - .iter() - .filter_map(move |asset| match asset.parent() { - Some(parent) => parents.insert(parent.clone()).then_some(parent), - None => Some(asset), - }) - .cloned() +/// +/// If only a subset of a parent's children are present in `assets`, a new parent asset representing +/// a portion of the total capacity will be created. This will have the same hash as the original +/// parent. +fn get_parent_or_self(assets: &[AssetRef]) -> Vec { + let mut child_counts: IndexMap<&AssetRef, u32> = IndexMap::new(); + let mut out = Vec::new(); + + for asset in assets { + if let Some(parent) = asset.parent() { + // For child assets, keep count of number of children per parent + *child_counts.entry(parent).or_default() += 1; + } else { + // Non-divisible assets can be returned as is + out.push(asset.clone()); + } + } + + for (parent, child_count) in child_counts { + // Convert to an object representing the appropriate portion of the parent's capacity + out.push(parent.make_partial_parent(child_count)); + } + + out } /// Provides the interface for running the dispatch optimisation. @@ -621,7 +636,7 @@ impl<'model, 'run> DispatchRun<'model, 'run> { allow_unmet_demand: bool, input_prices: Option<&CommodityPrices>, ) -> Result, ModelError> { - let parent_assets = get_parent_or_self(self.existing_assets).collect_vec(); + let parent_assets = get_parent_or_self(self.existing_assets); // Set up problem let mut problem = Problem::default(); diff --git a/tests/data/simple_divisible/commodity_flows.csv b/tests/data/simple_divisible/commodity_flows.csv index 03b9efc40..f308854df 100644 --- a/tests/data/simple_divisible/commodity_flows.csv +++ b/tests/data/simple_divisible/commodity_flows.csv @@ -11,8 +11,8 @@ milestone_year,asset_id,commodity_id,time_slice,flow 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.67582562255717 -2020,0,CO2EMT,peak.peak,300.00949640813485 +2020,0,GASPRD,peak.peak,58.67582562255711 +2020,0,CO2EMT,peak.peak,300.00949640813457 2020,0,GASPRD,peak.evening,166.76083466742 2020,0,CO2EMT,peak.evening,852.6481476545185 2020,0,GASPRD,summer.night,0.0 @@ -49,9 +49,9 @@ milestone_year,asset_id,commodity_id,time_slice,flow 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.96847146623166 -2020,1,GASNAT,peak.peak,57.11282996783967 -2020,1,CO2EMT,peak.peak,146.00894981278213 +2020,1,GASPRD,peak.peak,-59.96847146623163 +2020,1,GASNAT,peak.peak,57.112829967839644 +2020,1,CO2EMT,peak.peak,146.00894981278208 2020,1,GASPRD,peak.evening,-165.4681888237455 2020,1,GASNAT,peak.evening,157.58875126070998 2020,1,CO2EMT,peak.evening,402.87564259800513 @@ -179,7 +179,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,GASNAT,winter.day,-64.42324484619333 2020,4,GASNAT,winter.peak,-34.73957658039533 2020,4,GASNAT,winter.evening,-20.873823321559996 -2020,4,GASNAT,peak.night,-6.507424172328413 +2020,4,GASNAT,peak.night,-6.507424172328412 2020,4,GASNAT,peak.day,-27.39472946525066 2020,4,GASNAT,peak.peak,-19.430425872102003 2020,4,GASNAT,peak.evening,-8.981105302534091 @@ -187,7 +187,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,GASNAT,summer.day,-0.0 2020,4,GASNAT,summer.peak,-0.0 2020,4,GASNAT,summer.evening,-0.0 -2020,4,GASNAT,autumn.night,-3.03632040989107 +2020,4,GASNAT,autumn.night,-3.0363204098910686 2020,4,GASNAT,autumn.day,-18.89807446167866 2020,4,GASNAT,autumn.peak,-14.793408683652117 2020,4,GASNAT,autumn.evening,-5.6792251126803315 @@ -195,7 +195,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,RSHEAT,winter.day,56.020212909733324 2020,4,RSHEAT,winter.peak,30.20832746121333 2020,4,RSHEAT,winter.evening,18.1511507144 -2020,4,RSHEAT,peak.night,5.658629715068186 +2020,4,RSHEAT,peak.night,5.658629715068185 2020,4,RSHEAT,peak.day,23.82150388282666 2020,4,RSHEAT,peak.peak,16.89602249748 2020,4,RSHEAT,peak.evening,7.809656784812255 @@ -203,7 +203,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,RSHEAT,summer.day,0.0 2020,4,RSHEAT,summer.peak,0.0 2020,4,RSHEAT,summer.evening,0.0 -2020,4,RSHEAT,autumn.night,2.6402786172965826 +2020,4,RSHEAT,autumn.night,2.6402786172965818 2020,4,RSHEAT,autumn.day,16.433108227546665 2020,4,RSHEAT,autumn.peak,12.863833637958365 2020,4,RSHEAT,autumn.evening,4.938456619722028 @@ -211,7 +211,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,CO2EMT,winter.day,3293.960508985865 2020,4,CO2EMT,winter.peak,1776.2345505556132 2020,4,CO2EMT,winter.evening,1067.2785864313628 -2020,4,CO2EMT,peak.night,332.72459793115183 +2020,4,CO2EMT,peak.night,332.7245979311518 2020,4,CO2EMT,peak.day,1400.6925175582664 2020,4,CO2EMT,peak.peak,993.4776748405753 2020,4,CO2EMT,peak.evening,459.2039141185682 @@ -219,7 +219,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,4,CO2EMT,summer.day,0.0 2020,4,CO2EMT,summer.peak,0.0 2020,4,CO2EMT,summer.evening,0.0 -2020,4,CO2EMT,autumn.night,155.24706255773043 +2020,4,CO2EMT,autumn.night,155.24706255773035 2020,4,CO2EMT,autumn.day,966.2585472256301 2020,4,CO2EMT,autumn.peak,756.3869859951329 2020,4,CO2EMT,autumn.evening,290.37878001134544 @@ -227,7 +227,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,GASNAT,winter.day,-64.42324484619333 2020,5,GASNAT,winter.peak,-34.73957658039533 2020,5,GASNAT,winter.evening,-20.873823321559996 -2020,5,GASNAT,peak.night,-6.507424172328413 +2020,5,GASNAT,peak.night,-6.507424172328412 2020,5,GASNAT,peak.day,-27.39472946525066 2020,5,GASNAT,peak.peak,-19.430425872102003 2020,5,GASNAT,peak.evening,-8.981105302534091 @@ -235,7 +235,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,GASNAT,summer.day,-0.0 2020,5,GASNAT,summer.peak,-0.0 2020,5,GASNAT,summer.evening,-0.0 -2020,5,GASNAT,autumn.night,-3.03632040989107 +2020,5,GASNAT,autumn.night,-3.0363204098910686 2020,5,GASNAT,autumn.day,-18.89807446167866 2020,5,GASNAT,autumn.peak,-14.793408683652117 2020,5,GASNAT,autumn.evening,-5.6792251126803315 @@ -243,7 +243,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,RSHEAT,winter.day,56.020212909733324 2020,5,RSHEAT,winter.peak,30.20832746121333 2020,5,RSHEAT,winter.evening,18.1511507144 -2020,5,RSHEAT,peak.night,5.658629715068186 +2020,5,RSHEAT,peak.night,5.658629715068185 2020,5,RSHEAT,peak.day,23.82150388282666 2020,5,RSHEAT,peak.peak,16.89602249748 2020,5,RSHEAT,peak.evening,7.809656784812255 @@ -251,7 +251,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,RSHEAT,summer.day,0.0 2020,5,RSHEAT,summer.peak,0.0 2020,5,RSHEAT,summer.evening,0.0 -2020,5,RSHEAT,autumn.night,2.6402786172965826 +2020,5,RSHEAT,autumn.night,2.6402786172965818 2020,5,RSHEAT,autumn.day,16.433108227546665 2020,5,RSHEAT,autumn.peak,12.863833637958365 2020,5,RSHEAT,autumn.evening,4.938456619722028 @@ -259,7 +259,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,CO2EMT,winter.day,3293.960508985865 2020,5,CO2EMT,winter.peak,1776.2345505556132 2020,5,CO2EMT,winter.evening,1067.2785864313628 -2020,5,CO2EMT,peak.night,332.72459793115183 +2020,5,CO2EMT,peak.night,332.7245979311518 2020,5,CO2EMT,peak.day,1400.6925175582664 2020,5,CO2EMT,peak.peak,993.4776748405753 2020,5,CO2EMT,peak.evening,459.2039141185682 @@ -267,7 +267,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,5,CO2EMT,summer.day,0.0 2020,5,CO2EMT,summer.peak,0.0 2020,5,CO2EMT,summer.evening,0.0 -2020,5,CO2EMT,autumn.night,155.24706255773043 +2020,5,CO2EMT,autumn.night,155.24706255773035 2020,5,CO2EMT,autumn.day,966.2585472256301 2020,5,CO2EMT,autumn.peak,756.3869859951329 2020,5,CO2EMT,autumn.evening,290.37878001134544 @@ -275,7 +275,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,GASNAT,winter.day,-64.42324484619333 2020,6,GASNAT,winter.peak,-34.73957658039533 2020,6,GASNAT,winter.evening,-20.873823321559996 -2020,6,GASNAT,peak.night,-6.507424172328413 +2020,6,GASNAT,peak.night,-6.507424172328412 2020,6,GASNAT,peak.day,-27.39472946525066 2020,6,GASNAT,peak.peak,-19.430425872102003 2020,6,GASNAT,peak.evening,-8.981105302534091 @@ -283,7 +283,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,GASNAT,summer.day,-0.0 2020,6,GASNAT,summer.peak,-0.0 2020,6,GASNAT,summer.evening,-0.0 -2020,6,GASNAT,autumn.night,-3.03632040989107 +2020,6,GASNAT,autumn.night,-3.0363204098910686 2020,6,GASNAT,autumn.day,-18.89807446167866 2020,6,GASNAT,autumn.peak,-14.793408683652117 2020,6,GASNAT,autumn.evening,-5.6792251126803315 @@ -291,7 +291,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,RSHEAT,winter.day,56.020212909733324 2020,6,RSHEAT,winter.peak,30.20832746121333 2020,6,RSHEAT,winter.evening,18.1511507144 -2020,6,RSHEAT,peak.night,5.658629715068186 +2020,6,RSHEAT,peak.night,5.658629715068185 2020,6,RSHEAT,peak.day,23.82150388282666 2020,6,RSHEAT,peak.peak,16.89602249748 2020,6,RSHEAT,peak.evening,7.809656784812255 @@ -299,7 +299,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,RSHEAT,summer.day,0.0 2020,6,RSHEAT,summer.peak,0.0 2020,6,RSHEAT,summer.evening,0.0 -2020,6,RSHEAT,autumn.night,2.6402786172965826 +2020,6,RSHEAT,autumn.night,2.6402786172965818 2020,6,RSHEAT,autumn.day,16.433108227546665 2020,6,RSHEAT,autumn.peak,12.863833637958365 2020,6,RSHEAT,autumn.evening,4.938456619722028 @@ -307,7 +307,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,CO2EMT,winter.day,3293.960508985865 2020,6,CO2EMT,winter.peak,1776.2345505556132 2020,6,CO2EMT,winter.evening,1067.2785864313628 -2020,6,CO2EMT,peak.night,332.72459793115183 +2020,6,CO2EMT,peak.night,332.7245979311518 2020,6,CO2EMT,peak.day,1400.6925175582664 2020,6,CO2EMT,peak.peak,993.4776748405753 2020,6,CO2EMT,peak.evening,459.2039141185682 @@ -315,7 +315,7 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2020,6,CO2EMT,summer.day,0.0 2020,6,CO2EMT,summer.peak,0.0 2020,6,CO2EMT,summer.evening,0.0 -2020,6,CO2EMT,autumn.night,155.24706255773043 +2020,6,CO2EMT,autumn.night,155.24706255773035 2020,6,CO2EMT,autumn.day,966.2585472256301 2020,6,CO2EMT,autumn.peak,756.3869859951329 2020,6,CO2EMT,autumn.evening,290.37878001134544 @@ -421,12 +421,12 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2030,3,GASNAT,winter.day,-11.975343788321101 2030,3,ELCTRI,winter.day,7.9835625255474 2030,3,CO2EMT,winter.day,612.2993278968578 -2030,3,GASNAT,winter.peak,-3.592603125 -2030,3,ELCTRI,winter.peak,2.39506875 -2030,3,CO2EMT,winter.peak,183.68979778124998 -2030,3,GASNAT,winter.evening,-4.790137538321099 -2030,3,ELCTRI,winter.evening,3.1934250255473997 -2030,3,CO2EMT,winter.evening,244.9197323343578 +2030,3,GASNAT,winter.peak,-2.57617727836069 +2030,3,ELCTRI,winter.peak,1.7174515189071267 +2030,3,CO2EMT,winter.peak,131.71994424258207 +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 @@ -460,9 +460,9 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2030,3,GASNAT,autumn.peak,-3.2097933936726317 2030,3,ELCTRI,autumn.peak,2.139862262448421 2030,3,CO2EMT,autumn.peak,164.11673621848163 -2030,3,GASNAT,autumn.evening,-4.790137538321099 -2030,3,ELCTRI,autumn.evening,3.1934250255473997 -2030,3,CO2EMT,autumn.evening,244.9197323343578 +2030,3,GASNAT,autumn.evening,-4.526130821984218 +2030,3,ELCTRI,autumn.evening,3.0174205479894782 +2030,3,CO2EMT,autumn.evening,231.42106892805302 2030,7,ELCTRI,winter.night,-9.624518793997803 2030,7,RSHEAT,winter.night,29.165208466660005 2030,7,ELCTRI,winter.day,-13.749312543997803 @@ -533,12 +533,12 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2030,9,GASNAT,winter.day,-11.2272229724261 2030,9,ELCTRI,winter.day,7.484815314950733 2030,9,CO2EMT,winter.day,574.0479105801464 -2030,9,GASNAT,winter.peak,-3.5952126517441387 -2030,9,ELCTRI,winter.peak,2.3968084344960925 -2030,9,CO2EMT,winter.peak,183.8232228836778 -2030,9,GASNAT,winter.evening,-4.881619151330547 -2030,9,ELCTRI,winter.evening,3.2544127675536982 -2030,9,CO2EMT,winter.evening,249.59718720753085 +2030,9,GASNAT,winter.peak,-4.611638498383449 +2030,9,ELCTRI,winter.peak,3.0744256655889663 +2030,9,CO2EMT,winter.peak,235.79307642234576 +2030,9,GASNAT,winter.evening,-6.148851380368743 +2030,9,ELCTRI,winter.evening,4.099234253579162 +2030,9,CO2EMT,winter.evening,314.3907710782538 2030,9,GASNAT,peak.night,-10.67427159737626 2030,9,ELCTRI,peak.night,7.116181064917506 2030,9,CO2EMT,peak.night,545.7755067738481 @@ -572,153 +572,153 @@ milestone_year,asset_id,commodity_id,time_slice,flow 2030,9,GASNAT,autumn.peak,-4.611638498383449 2030,9,ELCTRI,autumn.peak,3.0744256655889663 2030,9,CO2EMT,autumn.peak,235.79307642234576 -2030,9,GASNAT,autumn.evening,-5.88484466403186 -2030,9,ELCTRI,autumn.evening,3.9232297760212402 -2030,9,CO2EMT,autumn.evening,300.892107671949 +2030,9,GASNAT,autumn.evening,-6.148851380368743 +2030,9,ELCTRI,autumn.evening,4.099234253579162 +2030,9,CO2EMT,autumn.evening,314.3907710782538 2030,4,GASNAT,winter.night,-7.464010718179302 -2030,4,GASNAT,winter.day,-62.876485519407304 +2030,4,GASNAT,winter.day,-62.87648551940729 2030,4,GASNAT,winter.peak,-35.93749999999999 -2030,4,GASNAT,winter.evening,-19.72723730223131 +2030,4,GASNAT,winter.evening,-19.727237302231305 2030,4,GASNAT,peak.night,-0.0 -2030,4,GASNAT,peak.day,-21.85516078513129 +2030,4,GASNAT,peak.day,-21.855160785131293 2030,4,GASNAT,peak.peak,-18.97755342504 -2030,4,GASNAT,peak.evening,-5.8038588216593086 +2030,4,GASNAT,peak.evening,-5.80385882165931 2030,4,GASNAT,summer.night,-0.0 2030,4,GASNAT,summer.day,-0.0 2030,4,GASNAT,summer.peak,-0.0 2030,4,GASNAT,summer.evening,-0.0 2030,4,GASNAT,autumn.night,-0.0 -2030,4,GASNAT,autumn.day,-12.442305841559296 +2030,4,GASNAT,autumn.day,-12.442305841559298 2030,4,GASNAT,autumn.peak,-13.607746601638993 -2030,4,GASNAT,autumn.evening,-2.3724302891203073 +2030,4,GASNAT,autumn.evening,-2.3724302891203077 2030,4,RSHEAT,winter.night,6.49044410276461 -2030,4,RSHEAT,winter.day,54.67520479948462 +2030,4,RSHEAT,winter.day,54.67520479948461 2030,4,RSHEAT,winter.peak,31.25 2030,4,RSHEAT,winter.evening,17.154119393244617 2030,4,RSHEAT,peak.night,0.0 -2030,4,RSHEAT,peak.day,19.0044876392446 +2030,4,RSHEAT,peak.day,19.004487639244605 2030,4,RSHEAT,peak.peak,16.5022203696 -2030,4,RSHEAT,peak.evening,5.046833757964617 +2030,4,RSHEAT,peak.evening,5.046833757964618 2030,4,RSHEAT,summer.night,0.0 2030,4,RSHEAT,summer.day,0.0 2030,4,RSHEAT,summer.peak,0.0 2030,4,RSHEAT,summer.evening,0.0 2030,4,RSHEAT,autumn.night,0.0 -2030,4,RSHEAT,autumn.day,10.819396383964607 +2030,4,RSHEAT,autumn.day,10.819396383964609 2030,4,RSHEAT,autumn.peak,11.832823131859996 -2030,4,RSHEAT,autumn.evening,2.062982860104615 +2030,4,RSHEAT,autumn.evening,2.0629828601046154 2030,4,CO2EMT,winter.night,381.6348680205078 -2030,4,CO2EMT,winter.day,3214.8747046072963 +2030,4,CO2EMT,winter.day,3214.8747046072954 2030,4,CO2EMT,winter.peak,1837.484375 -2030,4,CO2EMT,winter.evening,1008.6536432630869 +2030,4,CO2EMT,winter.evening,1008.6536432630868 2030,4,CO2EMT,peak.night,0.0 -2030,4,CO2EMT,peak.day,1117.454370943763 +2030,4,CO2EMT,peak.day,1117.4543709437633 2030,4,CO2EMT,peak.peak,970.3223066222953 -2030,4,CO2EMT,peak.evening,296.75130155144046 +2030,4,CO2EMT,peak.evening,296.7513015514405 2030,4,CO2EMT,summer.night,0.0 2030,4,CO2EMT,summer.day,0.0 2030,4,CO2EMT,summer.peak,0.0 2030,4,CO2EMT,summer.evening,0.0 2030,4,CO2EMT,autumn.night,0.0 -2030,4,CO2EMT,autumn.day,636.1750976789269 +2030,4,CO2EMT,autumn.day,636.175097678927 2030,4,CO2EMT,autumn.peak,695.7640837418018 -2030,4,CO2EMT,autumn.evening,121.30236068272131 +2030,4,CO2EMT,autumn.evening,121.30236068272136 2030,5,GASNAT,winter.night,-7.464010718179302 -2030,5,GASNAT,winter.day,-62.876485519407304 +2030,5,GASNAT,winter.day,-62.87648551940729 2030,5,GASNAT,winter.peak,-35.93749999999999 -2030,5,GASNAT,winter.evening,-19.72723730223131 +2030,5,GASNAT,winter.evening,-19.727237302231305 2030,5,GASNAT,peak.night,-0.0 -2030,5,GASNAT,peak.day,-21.85516078513129 +2030,5,GASNAT,peak.day,-21.855160785131293 2030,5,GASNAT,peak.peak,-18.97755342504 -2030,5,GASNAT,peak.evening,-5.8038588216593086 +2030,5,GASNAT,peak.evening,-5.80385882165931 2030,5,GASNAT,summer.night,-0.0 2030,5,GASNAT,summer.day,-0.0 2030,5,GASNAT,summer.peak,-0.0 2030,5,GASNAT,summer.evening,-0.0 2030,5,GASNAT,autumn.night,-0.0 -2030,5,GASNAT,autumn.day,-12.442305841559296 +2030,5,GASNAT,autumn.day,-12.442305841559298 2030,5,GASNAT,autumn.peak,-13.607746601638993 -2030,5,GASNAT,autumn.evening,-2.3724302891203073 +2030,5,GASNAT,autumn.evening,-2.3724302891203077 2030,5,RSHEAT,winter.night,6.49044410276461 -2030,5,RSHEAT,winter.day,54.67520479948462 +2030,5,RSHEAT,winter.day,54.67520479948461 2030,5,RSHEAT,winter.peak,31.25 2030,5,RSHEAT,winter.evening,17.154119393244617 2030,5,RSHEAT,peak.night,0.0 -2030,5,RSHEAT,peak.day,19.0044876392446 +2030,5,RSHEAT,peak.day,19.004487639244605 2030,5,RSHEAT,peak.peak,16.5022203696 -2030,5,RSHEAT,peak.evening,5.046833757964617 +2030,5,RSHEAT,peak.evening,5.046833757964618 2030,5,RSHEAT,summer.night,0.0 2030,5,RSHEAT,summer.day,0.0 2030,5,RSHEAT,summer.peak,0.0 2030,5,RSHEAT,summer.evening,0.0 2030,5,RSHEAT,autumn.night,0.0 -2030,5,RSHEAT,autumn.day,10.819396383964607 +2030,5,RSHEAT,autumn.day,10.819396383964609 2030,5,RSHEAT,autumn.peak,11.832823131859996 -2030,5,RSHEAT,autumn.evening,2.062982860104615 +2030,5,RSHEAT,autumn.evening,2.0629828601046154 2030,5,CO2EMT,winter.night,381.6348680205078 -2030,5,CO2EMT,winter.day,3214.8747046072963 +2030,5,CO2EMT,winter.day,3214.8747046072954 2030,5,CO2EMT,winter.peak,1837.484375 -2030,5,CO2EMT,winter.evening,1008.6536432630869 +2030,5,CO2EMT,winter.evening,1008.6536432630868 2030,5,CO2EMT,peak.night,0.0 -2030,5,CO2EMT,peak.day,1117.454370943763 +2030,5,CO2EMT,peak.day,1117.4543709437633 2030,5,CO2EMT,peak.peak,970.3223066222953 -2030,5,CO2EMT,peak.evening,296.75130155144046 +2030,5,CO2EMT,peak.evening,296.7513015514405 2030,5,CO2EMT,summer.night,0.0 2030,5,CO2EMT,summer.day,0.0 2030,5,CO2EMT,summer.peak,0.0 2030,5,CO2EMT,summer.evening,0.0 2030,5,CO2EMT,autumn.night,0.0 -2030,5,CO2EMT,autumn.day,636.1750976789269 +2030,5,CO2EMT,autumn.day,636.175097678927 2030,5,CO2EMT,autumn.peak,695.7640837418018 -2030,5,CO2EMT,autumn.evening,121.30236068272131 +2030,5,CO2EMT,autumn.evening,121.30236068272136 2030,6,GASNAT,winter.night,-7.464010718179302 -2030,6,GASNAT,winter.day,-62.876485519407304 +2030,6,GASNAT,winter.day,-62.87648551940729 2030,6,GASNAT,winter.peak,-35.93749999999999 -2030,6,GASNAT,winter.evening,-19.72723730223131 +2030,6,GASNAT,winter.evening,-19.727237302231305 2030,6,GASNAT,peak.night,-0.0 -2030,6,GASNAT,peak.day,-21.85516078513129 +2030,6,GASNAT,peak.day,-21.855160785131293 2030,6,GASNAT,peak.peak,-18.97755342504 -2030,6,GASNAT,peak.evening,-5.8038588216593086 +2030,6,GASNAT,peak.evening,-5.80385882165931 2030,6,GASNAT,summer.night,-0.0 2030,6,GASNAT,summer.day,-0.0 2030,6,GASNAT,summer.peak,-0.0 2030,6,GASNAT,summer.evening,-0.0 2030,6,GASNAT,autumn.night,-0.0 -2030,6,GASNAT,autumn.day,-12.442305841559296 +2030,6,GASNAT,autumn.day,-12.442305841559298 2030,6,GASNAT,autumn.peak,-13.607746601638993 -2030,6,GASNAT,autumn.evening,-2.3724302891203073 +2030,6,GASNAT,autumn.evening,-2.3724302891203077 2030,6,RSHEAT,winter.night,6.49044410276461 -2030,6,RSHEAT,winter.day,54.67520479948462 +2030,6,RSHEAT,winter.day,54.67520479948461 2030,6,RSHEAT,winter.peak,31.25 2030,6,RSHEAT,winter.evening,17.154119393244617 2030,6,RSHEAT,peak.night,0.0 -2030,6,RSHEAT,peak.day,19.0044876392446 +2030,6,RSHEAT,peak.day,19.004487639244605 2030,6,RSHEAT,peak.peak,16.5022203696 -2030,6,RSHEAT,peak.evening,5.046833757964617 +2030,6,RSHEAT,peak.evening,5.046833757964618 2030,6,RSHEAT,summer.night,0.0 2030,6,RSHEAT,summer.day,0.0 2030,6,RSHEAT,summer.peak,0.0 2030,6,RSHEAT,summer.evening,0.0 2030,6,RSHEAT,autumn.night,0.0 -2030,6,RSHEAT,autumn.day,10.819396383964607 +2030,6,RSHEAT,autumn.day,10.819396383964609 2030,6,RSHEAT,autumn.peak,11.832823131859996 -2030,6,RSHEAT,autumn.evening,2.062982860104615 +2030,6,RSHEAT,autumn.evening,2.0629828601046154 2030,6,CO2EMT,winter.night,381.6348680205078 -2030,6,CO2EMT,winter.day,3214.8747046072963 +2030,6,CO2EMT,winter.day,3214.8747046072954 2030,6,CO2EMT,winter.peak,1837.484375 -2030,6,CO2EMT,winter.evening,1008.6536432630869 +2030,6,CO2EMT,winter.evening,1008.6536432630868 2030,6,CO2EMT,peak.night,0.0 -2030,6,CO2EMT,peak.day,1117.454370943763 +2030,6,CO2EMT,peak.day,1117.4543709437633 2030,6,CO2EMT,peak.peak,970.3223066222953 -2030,6,CO2EMT,peak.evening,296.75130155144046 +2030,6,CO2EMT,peak.evening,296.7513015514405 2030,6,CO2EMT,summer.night,0.0 2030,6,CO2EMT,summer.day,0.0 2030,6,CO2EMT,summer.peak,0.0 2030,6,CO2EMT,summer.evening,0.0 2030,6,CO2EMT,autumn.night,0.0 -2030,6,CO2EMT,autumn.day,636.1750976789269 +2030,6,CO2EMT,autumn.day,636.175097678927 2030,6,CO2EMT,autumn.peak,695.7640837418018 -2030,6,CO2EMT,autumn.evening,121.30236068272131 +2030,6,CO2EMT,autumn.evening,121.30236068272136 2040,0,GASPRD,winter.night,0.0 2040,0,CO2EMT,winter.night,0.0 2040,0,GASPRD,winter.day,291.6944707979391