diff --git a/src/asset.rs b/src/asset.rs index c115ee646..2062d8d28 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -10,7 +10,7 @@ use crate::simulation::CommodityPrices; use crate::time_slice::{TimeSliceID, TimeSliceSelection}; use crate::units::{ Activity, ActivityPerCapacity, Capacity, Dimensionless, FlowPerActivity, MoneyPerActivity, - MoneyPerCapacity, MoneyPerFlow, + MoneyPerCapacity, MoneyPerFlow, Year, }; use anyhow::{Context, Result, ensure}; use indexmap::IndexMap; @@ -756,33 +756,35 @@ impl Asset { annual_capital_cost(capital_cost, lifetime, discount_rate) } - /// Get the annual capital cost per unit of activity for this asset + /// Get the annual fixed costs (AFC) per unit of activity for this asset /// - /// Total capital costs (cost per capacity * capacity) are shared equally over the year in - /// accordance with the annual activity. - pub fn get_annual_capital_cost_per_activity( + /// Total capital costs and fixed opex are shared equally over the year in accordance with the + /// annual activity. + pub fn get_annual_fixed_costs_per_activity( &self, annual_activity: Activity, ) -> MoneyPerActivity { let annual_capital_cost_per_capacity = self.get_annual_capital_cost_per_capacity(); - let total_annual_capital_cost = annual_capital_cost_per_capacity * self.total_capacity(); + let annual_fixed_opex = self.process_parameter.fixed_operating_cost * Year(1.0); + let total_annual_fixed_costs = + (annual_capital_cost_per_capacity + annual_fixed_opex) * self.total_capacity(); assert!( annual_activity > Activity::EPSILON, - "Cannot calculate annual capital cost per activity for an asset with zero annual activity" + "Cannot calculate annual fixed costs per activity for an asset with zero annual activity" ); - total_annual_capital_cost / annual_activity + total_annual_fixed_costs / annual_activity } - /// Get the annual capital cost per unit of output flow for this asset + /// Get the annual fixed costs (AFC) per unit of output flow for this asset /// - /// Total capital costs (cost per capacity * capacity) are shared equally across all output - /// flows in accordance with the annual activity and total output per unit of activity. - pub fn get_annual_capital_cost_per_flow(&self, annual_activity: Activity) -> MoneyPerFlow { - let annual_capital_cost_per_activity = - self.get_annual_capital_cost_per_activity(annual_activity); + /// Total capital costs and fixed opex are shared equally across all output flows in accordance + /// with the annual activity and total output per unit of activity. + pub fn get_annual_fixed_costs_per_flow(&self, annual_activity: Activity) -> MoneyPerFlow { + let annual_fixed_costs_per_activity = + self.get_annual_fixed_costs_per_activity(annual_activity); let total_output_per_activity = self.get_total_output_per_activity(); assert!(total_output_per_activity > FlowPerActivity::EPSILON); // input checks should guarantee this - annual_capital_cost_per_activity / total_output_per_activity + annual_fixed_costs_per_activity / total_output_per_activity } /// Maximum activity for this asset diff --git a/src/graph/investment.rs b/src/graph/investment.rs index 8d014b78a..4af0d9797 100644 --- a/src/graph/investment.rs +++ b/src/graph/investment.rs @@ -1,8 +1,9 @@ //! Module for solving the investment order of commodities use super::{CommoditiesGraph, GraphEdge, GraphNode}; -use crate::commodity::{CommodityMap, CommodityType}; +use crate::commodity::{CommodityMap, CommodityType, PricingStrategy}; use crate::region::RegionID; use crate::simulation::investment::InvestmentSet; +use anyhow::{Result, ensure}; use highs::{Col, HighsModelStatus, RowProblem, Sense}; use indexmap::IndexMap; use log::warn; @@ -41,14 +42,14 @@ fn solve_investment_order_for_year( graphs: &IndexMap<(RegionID, u32), CommoditiesGraph>, commodities: &CommodityMap, year: u32, -) -> Vec { +) -> Result> { // Initialise InvestmentGraph for this year from the set of original `CommodityGraph`s let mut investment_graph = init_investment_graph_for_year(graphs, year, commodities); // TODO: condense sibling commodities (commodities that share at least one producer) // Condense strongly connected components - investment_graph = compress_cycles(&investment_graph); + investment_graph = compress_cycles(&investment_graph, commodities)?; // Perform a topological sort on the condensed graph // We can safely unwrap because `toposort` will only return an error in case of cycles, which @@ -56,7 +57,7 @@ fn solve_investment_order_for_year( let order = toposort(&investment_graph, None).unwrap(); // Compute layers for investment - compute_layers(&investment_graph, &order) + Ok(compute_layers(&investment_graph, &order)) } /// Initialise an `InvestmentGraph` for the given year from a set of `CommodityGraph`s @@ -117,15 +118,39 @@ fn init_investment_graph_for_year( } /// Compresses cycles into `InvestmentSet::Cycle` nodes -fn compress_cycles(graph: &InvestmentGraph) -> InvestmentGraph { +fn compress_cycles(graph: &InvestmentGraph, commodities: &CommodityMap) -> Result { // Detect strongly connected components let mut condensed_graph = condensation(graph.clone(), true); // Order nodes within each strongly connected component order_sccs(&mut condensed_graph, graph); + // Pre-scan SCCs for offending pricing strategies (FullCost / MarginalCost). + for node_weight in condensed_graph.node_weights() { + if node_weight.len() <= 1 { + continue; + } + let offenders: Vec<_> = node_weight + .iter() + .flat_map(|s| s.iter_markets()) + .filter(|(cid, _)| { + matches!( + &commodities[cid].pricing_strategy, + PricingStrategy::MarginalCost | PricingStrategy::FullCost + ) + }) + .map(|(cid, _)| cid.clone()) + .collect(); + + ensure!( + offenders.is_empty(), + "Cannot use FullCost/MarginalCost pricing strategies for commodities with circular \ + dependencies. Offending commodities: {offenders:?}" + ); + } + // Map to a new InvestmentGraph - condensed_graph.map( + let mapped = condensed_graph.map( // Map nodes to InvestmentSet // If only one member, keep as-is; if multiple members, create Cycle |_, node_weight| match node_weight.len() { @@ -141,7 +166,9 @@ fn compress_cycles(graph: &InvestmentGraph) -> InvestmentGraph { }, // Keep edges the same |_, edge_weight| edge_weight.clone(), - ) + ); + + Ok(mapped) } /// Order the members of each strongly connected component using a mixed-integer linear program. @@ -490,13 +517,13 @@ pub fn solve_investment_order_for_model( commodity_graphs: &IndexMap<(RegionID, u32), CommoditiesGraph>, commodities: &CommodityMap, years: &[u32], -) -> HashMap> { +) -> Result>> { let mut investment_orders = HashMap::new(); for year in years { - let order = solve_investment_order_for_year(commodity_graphs, commodities, *year); + let order = solve_investment_order_for_year(commodity_graphs, commodities, *year)?; investment_orders.insert(*year, order); } - investment_orders + Ok(investment_orders) } #[cfg(test)] @@ -568,7 +595,7 @@ mod tests { commodities.insert("C".into(), Rc::new(svd_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); // Expected order: C, B, A (leaf nodes first) // No cycles or layers, so all investment sets should be `Single` @@ -596,7 +623,7 @@ mod tests { commodities.insert("B".into(), Rc::new(sed_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); // Should be a single `Cycle` investment set containing both commodities assert_eq!(result.len(), 1); @@ -635,7 +662,7 @@ mod tests { commodities.insert("D".into(), Rc::new(svd_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); // Expected order: D, Layer(B, C), A assert_eq!(result.len(), 3); @@ -674,7 +701,7 @@ mod tests { (("GBR".into(), 2020), graph.clone()), (("FRA".into(), 2020), graph), ]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); // Expected order: Should have three layers, each with two commodities (one per region) assert_eq!(result.len(), 3); diff --git a/src/input.rs b/src/input.rs index 7cdfcca23..8ef1e1f04 100644 --- a/src/input.rs +++ b/src/input.rs @@ -263,7 +263,8 @@ pub fn load_model>(model_dir: P) -> Result { )?; // Solve investment order for each region/year - let investment_order = solve_investment_order_for_model(&commodity_graphs, &commodities, years); + let investment_order = + solve_investment_order_for_model(&commodity_graphs, &commodities, years)?; let model_path = model_dir .as_ref() diff --git a/src/simulation/optimisation.rs b/src/simulation/optimisation.rs index c86638224..e14926033 100644 --- a/src/simulation/optimisation.rs +++ b/src/simulation/optimisation.rs @@ -263,6 +263,14 @@ impl Solution<'_> { .map(|((asset, time_slice), &value)| (asset, time_slice, Activity(value))) } + /// Iterate over the keys for activity for each existing asset + pub fn iter_activity_keys_for_existing( + &self, + ) -> impl Iterator { + self.iter_activity_for_existing() + .map(|(asset, time_slice, _activity)| (asset, time_slice)) + } + /// Activity for each candidate asset pub fn iter_activity_for_candidates( &self, @@ -275,6 +283,14 @@ impl Solution<'_> { .map(|((asset, time_slice), &value)| (asset, time_slice, Activity(value))) } + /// Iterate over the keys for activity for each candidate asset + pub fn iter_activity_keys_for_candidates( + &self, + ) -> impl Iterator { + self.iter_activity_for_candidates() + .map(|(asset, time_slice, _activity)| (asset, time_slice)) + } + /// Iterate over unmet demand pub fn iter_unmet_demand( &self, diff --git a/src/simulation/prices.rs b/src/simulation/prices.rs index 1242ef18d..81c2b4f84 100644 --- a/src/simulation/prices.rs +++ b/src/simulation/prices.rs @@ -8,12 +8,8 @@ use crate::time_slice::{TimeSliceID, TimeSliceInfo, TimeSliceSelection}; use crate::units::{Activity, Dimensionless, MoneyPerActivity, MoneyPerFlow, Year}; use anyhow::Result; use indexmap::IndexMap; -use itertools::iproduct; use std::collections::{HashMap, HashSet}; -/// Iterator item type for asset activity iterators -type Item<'a> = (&'a AssetRef, &'a TimeSliceID, Activity); - /// Calculate commodity prices. /// /// Calculate prices for each commodity/region/time-slice according to the commodity's configured @@ -30,73 +26,81 @@ type Item<'a> = (&'a AssetRef, &'a TimeSliceID, Activity); /// A `CommodityPrices` mapping `(commodity, region, time_slice)` to `MoneyPerFlow` representing /// endogenous prices computed from the optimisation solution. pub fn calculate_prices(model: &Model, solution: &Solution, year: u32) -> Result { - // Compute shadow prices for all SED/SVD commodities (needed by all strategies) + // Collect shadow prices for all SED/SVD commodities let shadow_prices = CommodityPrices::from_iter(solution.iter_commodity_balance_duals()); - // Partition markets by pricing strategy into a map keyed by `PricingStrategy`. - // For now, commodities use a single strategy for all regions, but this may change in the future. - let mut pricing_sets = HashMap::new(); - for ((commodity_id, commodity), region_id) in - iproduct!(&model.commodities, model.iter_regions()) - { - if commodity.pricing_strategy == PricingStrategy::Unpriced { - continue; - } - pricing_sets - .entry(&commodity.pricing_strategy) - .or_insert_with(HashSet::new) - .insert((commodity_id.clone(), region_id.clone())); - } - // Set up empty prices map let mut result = CommodityPrices::default(); - // Add prices for shadow-priced commodities - if let Some(shadow_set) = pricing_sets.get(&PricingStrategy::Shadow) { - for (commodity_id, region_id, time_slice) in shadow_prices.keys() { - if shadow_set.contains(&(commodity_id.clone(), region_id.clone())) { - let price = shadow_prices - .get(commodity_id, region_id, time_slice) - .unwrap(); - result.insert(commodity_id, region_id, time_slice, price); + // Get investment order for the year - prices will be calculated in the reverse of this order + let investment_order = &model.investment_order[&year]; + + // Iterate over investment sets in reverse order. Markets within the same set can be priced + // simultaneously, since they are independent (apart from Cycle sets when using the "marginal" + // and "full" strategies, which get flagged at the validation stage). + for investment_set in investment_order.iter().rev() { + // Partition markets by pricing strategy into a map keyed by `PricingStrategy`. + // For now, commodities use a single strategy for all regions, but this may change in the future. + let mut pricing_sets = HashMap::new(); + for (commodity_id, region_id) in investment_set.iter_markets() { + let commodity = &model.commodities[commodity_id]; + if commodity.pricing_strategy == PricingStrategy::Unpriced { + continue; } + pricing_sets + .entry(&commodity.pricing_strategy) + .or_insert_with(HashSet::new) + .insert((commodity_id.clone(), region_id.clone())); } - } - // Add prices for scarcity-adjusted commodities - if let Some(scarcity_set) = pricing_sets.get(&PricingStrategy::ScarcityAdjusted) { - let scarcity_prices = calculate_scarcity_adjusted_prices( - solution.iter_activity_duals(), - &shadow_prices, - scarcity_set, - ); - result.extend(scarcity_prices); - } + // Add prices for shadow-priced commodities + if let Some(shadow_set) = pricing_sets.get(&PricingStrategy::Shadow) { + for (commodity_id, region_id, time_slice) in shadow_prices.keys() { + if shadow_set.contains(&(commodity_id.clone(), region_id.clone())) { + let price = shadow_prices + .get(commodity_id, region_id, time_slice) + .unwrap(); + result.insert(commodity_id, region_id, time_slice, price); + } + } + } - // Add prices for marginal cost commodities - if let Some(marginal_set) = pricing_sets.get(&PricingStrategy::MarginalCost) { - let marginal_cost_prices = calculate_marginal_cost_prices( - solution.iter_activity_for_existing(), - solution.iter_activity_for_candidates(), - &shadow_prices, - year, - marginal_set, - ); - result.extend(marginal_cost_prices); - } + // Add prices for scarcity-adjusted commodities + if let Some(scarcity_set) = pricing_sets.get(&PricingStrategy::ScarcityAdjusted) { + let scarcity_prices = calculate_scarcity_adjusted_prices( + solution.iter_activity_duals(), + &shadow_prices, + scarcity_set, + ); + result.extend(scarcity_prices); + } - // Add prices for full cost commodities - if let Some(fullcost_set) = pricing_sets.get(&PricingStrategy::FullCost) { - let annual_activities = calculate_annual_activities(solution.iter_activity_for_existing()); - let full_cost_prices = calculate_full_cost_prices( - solution.iter_activity_for_existing(), - solution.iter_activity_for_candidates(), - &annual_activities, - &shadow_prices, - year, - fullcost_set, - ); - result.extend(full_cost_prices); + // Add prices for marginal cost commodities + if let Some(marginal_set) = pricing_sets.get(&PricingStrategy::MarginalCost) { + let marginal_cost_prices = calculate_marginal_cost_prices( + solution.iter_activity_keys_for_existing(), + solution.iter_activity_keys_for_candidates(), + &result, + year, + marginal_set, + ); + result.extend(marginal_cost_prices); + } + + // Add prices for full cost commodities + if let Some(fullcost_set) = pricing_sets.get(&PricingStrategy::FullCost) { + let annual_activities = + calculate_annual_activities(solution.iter_activity_for_existing()); + let full_cost_prices = calculate_full_cost_prices( + solution.iter_activity_keys_for_existing(), + solution.iter_activity_keys_for_candidates(), + &annual_activities, + &result, + year, + fullcost_set, + ); + result.extend(full_cost_prices); + } } // Return the completed prices map @@ -345,13 +349,12 @@ where /// /// --- /// -/// If any existing assets produce a given commodity in a particular region and time slice, the -/// price is taken from the asset with the highest marginal cost among those existing assets. If _no_ -/// existing assets produce the commodity in that region and time slice (in particular, this will -/// occur when there's no demand for the commodity), then candidate assets are considered: we -/// take the price from the candidate asset with the _lowest_ marginal cost, assuming full utilisation -/// (i.e. the single candidate asset that would be most competitive if a small amount of demand was -/// added). +/// For each region, the price in each time slice is taken from the installed asset with the highest +/// marginal cost. If there are no producers of the commodity in that region (in particular, this +/// may occur when there's no demand for the commodity), then candidate assets are considered: we +/// take the price from the candidate asset with the _lowest_ marginal cost, assuming full +/// utilisation (i.e. the single candidate asset that would be most competitive if a small amount of +/// demand was added). /// /// Note: this should be similar to the "shadow price" strategy, which is also based on marginal /// costs of the most expensive producer, but may be more successful in cases where there are @@ -359,29 +362,27 @@ where /// /// # Arguments /// -/// * `activity_for_existing` - Iterator over activity from optimisation solution for existing -/// assets -/// * `activity_for_candidates` - Iterator over activity from optimisation solution for candidate -/// assets. Note: we only need the keys, since we assume full utilisation for candidates. -/// * `annual_activities` - Map of annual activities for each asset computed by -/// `calculate_annual_activities`. This only needs to include existing assets. -/// * `shadow_prices` - Shadow prices for all commodities +/// * `activity_keys_for_existing` - Iterator over activity keys from optimisation solution for +/// existing assets +/// * `activity_keys_for_candidates` - Iterator over activity keys from optimisation solution for +/// candidate assets +/// * `upstream_prices` - Prices for commodities upstream of the ones we are calculating prices for /// * `year` - The year for which prices are being calculated -/// * `markets_to_price` - Set of markets to calculate full cost prices for +/// * `markets_to_price` - Set of markets to calculate marginal prices for /// /// # Returns /// /// A map of marginal cost prices for the specified markets in all time slices fn calculate_marginal_cost_prices<'a, I, J>( - activity_for_existing: I, - activity_for_candidates: J, - shadow_prices: &CommodityPrices, + activity_keys_for_existing: I, + activity_keys_for_candidates: J, + upstream_prices: &CommodityPrices, year: u32, markets_to_price: &HashSet<(CommodityID, RegionID)>, ) -> HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> where - I: Iterator>, - J: Iterator>, + I: Iterator, + J: Iterator, { let mut prices: HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = HashMap::new(); @@ -389,17 +390,12 @@ where // Calculate highest marginal cost for each commodity/region/time slice // Keep track of keys with prices - missing keys will be handled by candidates later let mut priced_by_existing = HashSet::new(); - for (asset, time_slice, activity) in activity_for_existing { + for (asset, time_slice) in activity_keys_for_existing { let region_id = asset.region_id(); - // Only proceed if the asset has non-zero activity in this time slice - if activity < Activity::EPSILON { - continue; - } - // Iterate over all the SED/SVD marginal costs for commodities we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - shadow_prices, + upstream_prices, year, time_slice, |commodity_id: &CommodityID| { @@ -418,7 +414,7 @@ where // Next, look at candidate assets for any markets not covered by existing assets // For these, we take the _lowest_ marginal cost - for (asset, time_slice, _activity) in activity_for_candidates { + for (asset, time_slice) in activity_keys_for_candidates { let region_id = asset.region_id(); // Only consider markets not already priced by existing assets @@ -433,7 +429,7 @@ where // Iterate over all the SED/SVD marginal costs for markets we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - shadow_prices, + upstream_prices, year, time_slice, |cid: &CommodityID| should_process(cid), @@ -451,10 +447,10 @@ where prices } -/// Calculated annual activities for each asset by summing across all time slices +/// Calculate annual activities for each asset by summing across all time slices fn calculate_annual_activities<'a, I>(activities: I) -> HashMap where - I: IntoIterator>, + I: IntoIterator, { activities .into_iter() @@ -500,23 +496,23 @@ where /// /// --- /// -/// If any existing assets produce a given commodity in a particular region and time slice, the -/// price is taken from the asset with the highest full cost among those existing assets. If _no_ -/// existing assets produce the commodity in that region and time slice (in particular, this will -/// occur when there's no demand for the commodity), then candidate assets are considered: we -/// take the price from the candidate asset with the _lowest_ full cost, assuming maximum -/// possible dispatch (i.e. the single candidate asset that would be most competitive if a small -/// amount of demand was added). +/// For each region, the price in each time slice is taken from the installed asset with the highest +/// full cost (excluding assets with zero annual activity, as the full cost of these as calculated +/// above would be infinite). If there are no producers of the commodity in that region (in +/// particular, this may occur when there's no demand for the commodity), then candidate assets are +/// considered: we take the price from the candidate asset with the _lowest_ full cost, assuming +/// maximum possible dispatch (i.e. the single candidate asset that would be most competitive if a +/// small amount of demand was added). /// /// # Arguments /// -/// * `activity_for_existing` - Iterator over activity from optimisation solution for existing -/// assets -/// * `activity_for_candidates` - Iterator over activity from optimisation solution for candidate -/// assets. Note: we only need the keys, since we assume full dispatch for candidates. +/// * `activity_keys_for_existing` - Iterator over activity keys from optimisation solution for +/// existing assets +/// * `activity_keys_for_candidates` - Iterator over activity keys from optimisation solution for +/// candidate assets /// * `annual_activities` - Map of annual activities for each asset computed by /// `calculate_annual_activities`. This only needs to include existing assets. -/// * `shadow_prices` - Shadow prices for all commodities +/// * `upstream_prices` - Prices for commodities upstream of the ones we are calculating prices for /// * `year` - The year for which prices are being calculated /// * `markets_to_price` - Set of markets to calculate full cost prices for /// @@ -524,30 +520,31 @@ where /// /// A map of full cost prices for the specified markets in all time slices fn calculate_full_cost_prices<'a, I, J>( - activity_for_existing: I, - activity_for_candidates: J, + activity_keys_for_existing: I, + activity_keys_for_candidates: J, annual_activities: &HashMap, - shadow_prices: &CommodityPrices, + upstream_prices: &CommodityPrices, year: u32, markets_to_price: &HashSet<(CommodityID, RegionID)>, ) -> HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> where - I: Iterator>, - J: Iterator>, + I: Iterator, + J: Iterator, { let mut prices: HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = HashMap::new(); // Start by looking at existing assets // Calculate highest full cost for each commodity/region/time slice // Keep track of keys with prices - missing keys will be handled by candidates later - let mut annual_capital_costs_cache = HashMap::new(); + let mut annual_fixed_costs_cache = HashMap::new(); let mut priced_by_existing = HashSet::new(); - for (asset, time_slice, activity) in activity_for_existing { + for (asset, time_slice) in activity_keys_for_existing { let annual_activity = annual_activities[asset]; let region_id = asset.region_id(); - // Only proceed if the asset has non-zero activity in this time slice - if activity < Activity::EPSILON { + // If annual activity is zero, we can't calculate a capital cost per flow, so skip this + // asset. + if annual_activity < Activity::EPSILON { continue; } @@ -559,20 +556,20 @@ where continue; } - // Calculate/cache annual capital cost for this asset - let annual_capital_cost_per_flow = *annual_capital_costs_cache + // Calculate/cache annual fixed costs for this asset + let annual_fixed_costs_per_flow = *annual_fixed_costs_cache .entry(asset.clone()) - .or_insert_with(|| asset.get_annual_capital_cost_per_flow(annual_activity)); + .or_insert_with(|| asset.get_annual_fixed_costs_per_flow(annual_activity)); // Iterate over all the SED/SVD marginal costs for commodities we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - shadow_prices, + upstream_prices, year, time_slice, |cid: &CommodityID| markets_to_price.contains(&(cid.clone(), region_id.clone())), ) { - // Add capital cost per flow to marginal cost to get full cost - let marginal_cost = marginal_cost + annual_capital_cost_per_flow; + // Add annual fixed costs per flow to marginal cost to get full cost + let marginal_cost = marginal_cost + annual_fixed_costs_per_flow; // Update the highest cost for this commodity/region/time slice let key = (commodity_id.clone(), region_id.clone(), time_slice.clone()); @@ -586,7 +583,7 @@ where // Next, look at candidate assets for any markets not covered by existing assets // For these we assume full utilisation, and take the _lowest_ full cost - for (asset, time_slice, _activity) in activity_for_candidates { + for (asset, time_slice) in activity_keys_for_candidates { let region_id = asset.region_id(); // Only consider markets not already priced by existing assets @@ -607,12 +604,12 @@ where continue; } - // Calculate/cache annual capital cost per flow for this asset assuming full dispatch + // Calculate/cache annual fixed cost per flow for this asset assuming full dispatch // (bound by the activity limits of the asset) - let annual_capital_cost_per_flow = *annual_capital_costs_cache + let annual_fixed_costs_per_flow = *annual_fixed_costs_cache .entry(asset.clone()) .or_insert_with(|| { - asset.get_annual_capital_cost_per_flow( + asset.get_annual_fixed_costs_per_flow( *asset .get_activity_limits_for_selection(&TimeSliceSelection::Annual) .end(), @@ -621,13 +618,13 @@ where // Iterate over all the SED/SVD marginal costs for markets we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - shadow_prices, + upstream_prices, year, time_slice, |cid: &CommodityID| should_process(cid), ) { - // Add capital cost per flow to marginal cost to get full cost - let full_cost = marginal_cost + annual_capital_cost_per_flow; + // Add annual fixed costs per flow to marginal cost to get full cost + let full_cost = marginal_cost + annual_fixed_costs_per_flow; // Update the _lowest_ cost for this commodity/region/time slice let key = (commodity_id.clone(), region_id.clone(), time_slice.clone()); @@ -680,6 +677,7 @@ mod tests { year: u32, time_slice_info: &TimeSliceInfo, variable_operating_cost: MoneyPerActivity, + fixed_operating_cost: MoneyPerCapacityPerYear, capital_cost: MoneyPerCapacity, lifetime: u32, discount_rate: Dimensionless, @@ -690,7 +688,7 @@ mod tests { let mut process_parameter_map = HashMap::new(); let proc_param = ProcessParameter { capital_cost, - fixed_operating_cost: MoneyPerCapacityPerYear(0.0), + fixed_operating_cost, variable_operating_cost, lifetime, discount_rate, @@ -815,10 +813,11 @@ mod tests { ®ion_id, 2015u32, &time_slice_info, - MoneyPerActivity(5.0), // variable operating cost - MoneyPerCapacity(0.0), // capital cost - 5, // lifetime - Dimensionless(1.0), // discount rate + MoneyPerActivity(5.0), // variable operating cost + MoneyPerCapacityPerYear(0.0), // fixed operating cost + MoneyPerCapacity(0.0), // capital cost + 5, // lifetime + Dimensionless(1.0), // discount rate ); let asset = @@ -831,7 +830,7 @@ mod tests { markets.insert((b.id.clone(), region_id.clone())); markets.insert((c.id.clone(), region_id.clone())); - let existing = vec![(&asset_ref, &time_slice, Activity(1.0))]; + let existing = vec![(&asset_ref, &time_slice)]; let candidates = Vec::new(); let prices = calculate_marginal_cost_prices( @@ -890,10 +889,11 @@ mod tests { ®ion_id, 2015u32, &time_slice_info, - MoneyPerActivity(5.0), // variable operating cost - MoneyPerCapacity(2.5), // capital cost per capacity so annualised=2.5 - 1, // lifetime so annualised = capital_cost - Dimensionless(0.0), // discount rate + MoneyPerActivity(5.0), // variable operating cost + MoneyPerCapacityPerYear(1.0), // fixed operating cost + MoneyPerCapacity(1.5), // capital cost per capacity so annualised=1.5 + 1, // lifetime so annualised = capital_cost + Dimensionless(0.0), // discount rate ); let asset = @@ -906,7 +906,7 @@ mod tests { markets.insert((b.id.clone(), region_id.clone())); markets.insert((c.id.clone(), region_id.clone())); - let existing = vec![(&asset_ref, &time_slice, Activity(2.0))]; + let existing = vec![(&asset_ref, &time_slice)]; let candidates = Vec::new(); let mut annual_activities = HashMap::new(); diff --git a/tests/data/circularity/commodity_prices.csv b/tests/data/circularity/commodity_prices.csv index 763694956..d8042ea00 100644 --- a/tests/data/circularity/commodity_prices.csv +++ b/tests/data/circularity/commodity_prices.csv @@ -31,6 +31,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASPRD,GBR,autumn.day,2.20452 2020,GASPRD,GBR,autumn.peak,2.20452 2020,GASPRD,GBR,autumn.evening,2.20452 +2020,BIOPRD,GBR,winter.night,3.5869398412698414 +2020,BIOPRD,GBR,winter.day,3.5869398412698414 +2020,BIOPRD,GBR,winter.peak,3.5869398412698414 +2020,BIOPRD,GBR,winter.evening,3.5869398412698414 +2020,BIOPRD,GBR,peak.night,3.5869398412698414 +2020,BIOPRD,GBR,peak.day,3.5869398412698414 +2020,BIOPRD,GBR,peak.peak,3.5869398412698414 +2020,BIOPRD,GBR,peak.evening,3.5869398412698414 +2020,BIOPRD,GBR,summer.night,0.25 +2020,BIOPRD,GBR,summer.day,0.25 +2020,BIOPRD,GBR,summer.peak,0.25 +2020,BIOPRD,GBR,summer.evening,0.25 +2020,BIOPRD,GBR,autumn.night,3.586939841269842 +2020,BIOPRD,GBR,autumn.day,3.586939841269842 +2020,BIOPRD,GBR,autumn.peak,3.586939841269842 +2020,BIOPRD,GBR,autumn.evening,3.586939841269842 2020,GASOLI,GBR,winter.night,8.66986824186952 2020,GASOLI,GBR,winter.day,8.66986824186952 2020,GASOLI,GBR,winter.peak,8.66986824186952 @@ -79,6 +95,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASNAT,GBR,autumn.day,2.9170059999999998 2020,GASNAT,GBR,autumn.peak,2.9170059999999998 2020,GASNAT,GBR,autumn.evening,2.9170059999999998 +2020,BIOPEL,GBR,winter.night,4.7221140833333335 +2020,BIOPEL,GBR,winter.day,4.7221140833333335 +2020,BIOPEL,GBR,winter.peak,4.7221140833333335 +2020,BIOPEL,GBR,winter.evening,4.7221140833333335 +2020,BIOPEL,GBR,peak.night,4.7221140833333335 +2020,BIOPEL,GBR,peak.day,4.7221140833333335 +2020,BIOPEL,GBR,peak.peak,4.7221140833333335 +2020,BIOPEL,GBR,peak.evening,4.7221140833333335 +2020,BIOPEL,GBR,summer.night,1.21832725 +2020,BIOPEL,GBR,summer.day,1.21832725 +2020,BIOPEL,GBR,summer.peak,1.21832725 +2020,BIOPEL,GBR,summer.evening,1.21832725 +2020,BIOPEL,GBR,autumn.night,4.7221140833333335 +2020,BIOPEL,GBR,autumn.day,4.7221140833333335 +2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 +2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2020,ELCTRI,GBR,winter.night,7.993308999999999 2020,ELCTRI,GBR,winter.day,17.26223303030303 2020,ELCTRI,GBR,winter.peak,17.482621345499997 @@ -143,38 +175,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,RSHEAT,GBR,autumn.day,5.8665369 2020,RSHEAT,GBR,autumn.peak,5.8665369 2020,RSHEAT,GBR,autumn.evening,5.8665369 -2020,BIOPRD,GBR,winter.night,3.5869398412698414 -2020,BIOPRD,GBR,winter.day,3.5869398412698414 -2020,BIOPRD,GBR,winter.peak,3.5869398412698414 -2020,BIOPRD,GBR,winter.evening,3.5869398412698414 -2020,BIOPRD,GBR,peak.night,3.5869398412698414 -2020,BIOPRD,GBR,peak.day,3.5869398412698414 -2020,BIOPRD,GBR,peak.peak,3.5869398412698414 -2020,BIOPRD,GBR,peak.evening,3.5869398412698414 -2020,BIOPRD,GBR,summer.night,0.25 -2020,BIOPRD,GBR,summer.day,0.25 -2020,BIOPRD,GBR,summer.peak,0.25 -2020,BIOPRD,GBR,summer.evening,0.25 -2020,BIOPRD,GBR,autumn.night,3.586939841269842 -2020,BIOPRD,GBR,autumn.day,3.586939841269842 -2020,BIOPRD,GBR,autumn.peak,3.586939841269842 -2020,BIOPRD,GBR,autumn.evening,3.586939841269842 -2020,BIOPEL,GBR,winter.night,4.7221140833333335 -2020,BIOPEL,GBR,winter.day,4.7221140833333335 -2020,BIOPEL,GBR,winter.peak,4.7221140833333335 -2020,BIOPEL,GBR,winter.evening,4.7221140833333335 -2020,BIOPEL,GBR,peak.night,4.7221140833333335 -2020,BIOPEL,GBR,peak.day,4.7221140833333335 -2020,BIOPEL,GBR,peak.peak,4.7221140833333335 -2020,BIOPEL,GBR,peak.evening,4.7221140833333335 -2020,BIOPEL,GBR,summer.night,1.21832725 -2020,BIOPEL,GBR,summer.day,1.21832725 -2020,BIOPEL,GBR,summer.peak,1.21832725 -2020,BIOPEL,GBR,summer.evening,1.21832725 -2020,BIOPEL,GBR,autumn.night,4.7221140833333335 -2020,BIOPEL,GBR,autumn.day,4.7221140833333335 -2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 -2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2030,OILCRD,GBR,winter.night,3.072868 2030,OILCRD,GBR,winter.day,3.072868 2030,OILCRD,GBR,winter.peak,3.072868 @@ -207,6 +207,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASPRD,GBR,autumn.day,2.20452 2030,GASPRD,GBR,autumn.peak,2.20452 2030,GASPRD,GBR,autumn.evening,2.20452 +2030,BIOPRD,GBR,winter.night,4.249632460317461 +2030,BIOPRD,GBR,winter.day,4.249632460317461 +2030,BIOPRD,GBR,winter.peak,4.249632460317461 +2030,BIOPRD,GBR,winter.evening,4.249632460317461 +2030,BIOPRD,GBR,peak.night,1.822057119047619 +2030,BIOPRD,GBR,peak.day,1.822057119047619 +2030,BIOPRD,GBR,peak.peak,1.822057119047619 +2030,BIOPRD,GBR,peak.evening,1.822057119047619 +2030,BIOPRD,GBR,summer.night,0.25 +2030,BIOPRD,GBR,summer.day,0.25 +2030,BIOPRD,GBR,summer.peak,0.25 +2030,BIOPRD,GBR,summer.evening,0.25 +2030,BIOPRD,GBR,autumn.night,1.822057119047619 +2030,BIOPRD,GBR,autumn.day,1.822057119047619 +2030,BIOPRD,GBR,autumn.peak,1.822057119047619 +2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,GASOLI,GBR,winter.night,5.585457080000001 2030,GASOLI,GBR,winter.day,5.585457080000001 2030,GASOLI,GBR,winter.peak,5.585457080000001 @@ -255,6 +271,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASNAT,GBR,autumn.day,2.9170059999999998 2030,GASNAT,GBR,autumn.peak,2.9170059999999998 2030,GASNAT,GBR,autumn.evening,2.9170059999999998 +2030,BIOPEL,GBR,winter.night,4.7221140833333335 +2030,BIOPEL,GBR,winter.day,4.7221140833333335 +2030,BIOPEL,GBR,winter.peak,4.7221140833333335 +2030,BIOPEL,GBR,winter.evening,4.7221140833333335 +2030,BIOPEL,GBR,peak.night,2.173159975 +2030,BIOPEL,GBR,peak.day,2.173159975 +2030,BIOPEL,GBR,peak.peak,2.173159975 +2030,BIOPEL,GBR,peak.evening,2.173159975 +2030,BIOPEL,GBR,summer.night,0.5225 +2030,BIOPEL,GBR,summer.day,0.5225 +2030,BIOPEL,GBR,summer.peak,0.5225 +2030,BIOPEL,GBR,summer.evening,0.5225 +2030,BIOPEL,GBR,autumn.night,2.173159975 +2030,BIOPEL,GBR,autumn.day,2.173159975 +2030,BIOPEL,GBR,autumn.peak,2.173159975 +2030,BIOPEL,GBR,autumn.evening,2.173159975 2030,ELCTRI,GBR,winter.night,7.993308999999999 2030,ELCTRI,GBR,winter.day,17.26223303030303 2030,ELCTRI,GBR,winter.peak,17.482621345499997 @@ -319,38 +351,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,RSHEAT,GBR,autumn.day,5.8665369 2030,RSHEAT,GBR,autumn.peak,5.8665369 2030,RSHEAT,GBR,autumn.evening,5.8665369 -2030,BIOPRD,GBR,winter.night,4.249632460317461 -2030,BIOPRD,GBR,winter.day,4.249632460317461 -2030,BIOPRD,GBR,winter.peak,4.249632460317461 -2030,BIOPRD,GBR,winter.evening,4.249632460317461 -2030,BIOPRD,GBR,peak.night,1.822057119047619 -2030,BIOPRD,GBR,peak.day,1.822057119047619 -2030,BIOPRD,GBR,peak.peak,1.822057119047619 -2030,BIOPRD,GBR,peak.evening,1.822057119047619 -2030,BIOPRD,GBR,summer.night,0.25 -2030,BIOPRD,GBR,summer.day,0.25 -2030,BIOPRD,GBR,summer.peak,0.25 -2030,BIOPRD,GBR,summer.evening,0.25 -2030,BIOPRD,GBR,autumn.night,1.822057119047619 -2030,BIOPRD,GBR,autumn.day,1.822057119047619 -2030,BIOPRD,GBR,autumn.peak,1.822057119047619 -2030,BIOPRD,GBR,autumn.evening,1.822057119047619 -2030,BIOPEL,GBR,winter.night,4.7221140833333335 -2030,BIOPEL,GBR,winter.day,4.7221140833333335 -2030,BIOPEL,GBR,winter.peak,4.7221140833333335 -2030,BIOPEL,GBR,winter.evening,4.7221140833333335 -2030,BIOPEL,GBR,peak.night,2.173159975 -2030,BIOPEL,GBR,peak.day,2.173159975 -2030,BIOPEL,GBR,peak.peak,2.173159975 -2030,BIOPEL,GBR,peak.evening,2.173159975 -2030,BIOPEL,GBR,summer.night,0.5225 -2030,BIOPEL,GBR,summer.day,0.5225 -2030,BIOPEL,GBR,summer.peak,0.5225 -2030,BIOPEL,GBR,summer.evening,0.5225 -2030,BIOPEL,GBR,autumn.night,2.173159975 -2030,BIOPEL,GBR,autumn.day,2.173159975 -2030,BIOPEL,GBR,autumn.peak,2.173159975 -2030,BIOPEL,GBR,autumn.evening,2.173159975 2040,OILCRD,GBR,winter.night,3.072868 2040,OILCRD,GBR,winter.day,3.072868 2040,OILCRD,GBR,winter.peak,3.072868 @@ -383,6 +383,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASPRD,GBR,autumn.day,2.20452 2040,GASPRD,GBR,autumn.peak,2.20452 2040,GASPRD,GBR,autumn.evening,2.20452 +2040,BIOPRD,GBR,winter.night,0.25 +2040,BIOPRD,GBR,winter.day,0.25 +2040,BIOPRD,GBR,winter.peak,0.25 +2040,BIOPRD,GBR,winter.evening,0.25 +2040,BIOPRD,GBR,peak.night,0.25 +2040,BIOPRD,GBR,peak.day,0.25 +2040,BIOPRD,GBR,peak.peak,0.25 +2040,BIOPRD,GBR,peak.evening,0.25 +2040,BIOPRD,GBR,summer.night,0.25 +2040,BIOPRD,GBR,summer.day,0.25 +2040,BIOPRD,GBR,summer.peak,0.25 +2040,BIOPRD,GBR,summer.evening,0.25 +2040,BIOPRD,GBR,autumn.night,0.25 +2040,BIOPRD,GBR,autumn.day,0.25 +2040,BIOPRD,GBR,autumn.peak,0.25 +2040,BIOPRD,GBR,autumn.evening,0.25 2040,GASOLI,GBR,winter.night,5.585457080000001 2040,GASOLI,GBR,winter.day,5.585457080000001 2040,GASOLI,GBR,winter.peak,5.585457080000001 @@ -415,6 +431,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASNAT,GBR,autumn.day,2.9170059999999998 2040,GASNAT,GBR,autumn.peak,2.9170059999999998 2040,GASNAT,GBR,autumn.evening,2.9170059999999998 +2040,BIOPEL,GBR,winter.night,0.5225 +2040,BIOPEL,GBR,winter.day,0.5225 +2040,BIOPEL,GBR,winter.peak,0.5225 +2040,BIOPEL,GBR,winter.evening,0.5225 +2040,BIOPEL,GBR,peak.night,0.5225 +2040,BIOPEL,GBR,peak.day,0.5225 +2040,BIOPEL,GBR,peak.peak,0.5225 +2040,BIOPEL,GBR,peak.evening,0.5225 +2040,BIOPEL,GBR,summer.night,0.5225 +2040,BIOPEL,GBR,summer.day,0.5225 +2040,BIOPEL,GBR,summer.peak,0.5225 +2040,BIOPEL,GBR,summer.evening,0.5225 +2040,BIOPEL,GBR,autumn.night,0.5225 +2040,BIOPEL,GBR,autumn.day,0.5225 +2040,BIOPEL,GBR,autumn.peak,0.5225 +2040,BIOPEL,GBR,autumn.evening,0.5225 2040,ELCTRI,GBR,winter.night,7.993308999999999 2040,ELCTRI,GBR,winter.day,7.993308999999999 2040,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -479,35 +511,3 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,RSHEAT,GBR,autumn.day,0.827 2040,RSHEAT,GBR,autumn.peak,0.827 2040,RSHEAT,GBR,autumn.evening,0.827 -2040,BIOPRD,GBR,winter.night,0.25 -2040,BIOPRD,GBR,winter.day,0.25 -2040,BIOPRD,GBR,winter.peak,0.25 -2040,BIOPRD,GBR,winter.evening,0.25 -2040,BIOPRD,GBR,peak.night,0.25 -2040,BIOPRD,GBR,peak.day,0.25 -2040,BIOPRD,GBR,peak.peak,0.25 -2040,BIOPRD,GBR,peak.evening,0.25 -2040,BIOPRD,GBR,summer.night,0.25 -2040,BIOPRD,GBR,summer.day,0.25 -2040,BIOPRD,GBR,summer.peak,0.25 -2040,BIOPRD,GBR,summer.evening,0.25 -2040,BIOPRD,GBR,autumn.night,0.25 -2040,BIOPRD,GBR,autumn.day,0.25 -2040,BIOPRD,GBR,autumn.peak,0.25 -2040,BIOPRD,GBR,autumn.evening,0.25 -2040,BIOPEL,GBR,winter.night,0.5225 -2040,BIOPEL,GBR,winter.day,0.5225 -2040,BIOPEL,GBR,winter.peak,0.5225 -2040,BIOPEL,GBR,winter.evening,0.5225 -2040,BIOPEL,GBR,peak.night,0.5225 -2040,BIOPEL,GBR,peak.day,0.5225 -2040,BIOPEL,GBR,peak.peak,0.5225 -2040,BIOPEL,GBR,peak.evening,0.5225 -2040,BIOPEL,GBR,summer.night,0.5225 -2040,BIOPEL,GBR,summer.day,0.5225 -2040,BIOPEL,GBR,summer.peak,0.5225 -2040,BIOPEL,GBR,summer.evening,0.5225 -2040,BIOPEL,GBR,autumn.night,0.5225 -2040,BIOPEL,GBR,autumn.day,0.5225 -2040,BIOPEL,GBR,autumn.peak,0.5225 -2040,BIOPEL,GBR,autumn.evening,0.5225 diff --git a/tests/data/missing_commodity/commodity_prices.csv b/tests/data/missing_commodity/commodity_prices.csv index 8bafd7e4b..55a52dd42 100644 --- a/tests/data/missing_commodity/commodity_prices.csv +++ b/tests/data/missing_commodity/commodity_prices.csv @@ -15,22 +15,6 @@ milestone_year,commodity_id,region_id,time_slice,price 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,BIOPRD,GBR,winter.night,4.249632460317461 2020,BIOPRD,GBR,winter.day,4.249632460317461 2020,BIOPRD,GBR,winter.peak,4.249632460317461 @@ -47,6 +31,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,BIOPRD,GBR,autumn.day,4.249632460317461 2020,BIOPRD,GBR,autumn.peak,4.249632460317461 2020,BIOPRD,GBR,autumn.evening,4.249632460317461 +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,BIOPEL,GBR,winter.night,4.7221140833333335 2020,BIOPEL,GBR,winter.day,4.7221140833333335 2020,BIOPEL,GBR,winter.peak,4.7221140833333335 @@ -111,22 +111,6 @@ milestone_year,commodity_id,region_id,time_slice,price 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,-0.0 -2030,GASNAT,GBR,summer.day,-0.0 -2030,GASNAT,GBR,summer.peak,-0.0 -2030,GASNAT,GBR,summer.evening,-0.0 -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,BIOPRD,GBR,winter.night,4.249632460317461 2030,BIOPRD,GBR,winter.day,4.249632460317461 2030,BIOPRD,GBR,winter.peak,4.249632460317461 @@ -143,6 +127,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,BIOPRD,GBR,autumn.day,1.822057119047619 2030,BIOPRD,GBR,autumn.peak,1.822057119047619 2030,BIOPRD,GBR,autumn.evening,1.822057119047619 +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,-0.0 +2030,GASNAT,GBR,summer.day,-0.0 +2030,GASNAT,GBR,summer.peak,-0.0 +2030,GASNAT,GBR,summer.evening,-0.0 +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,BIOPEL,GBR,winter.night,4.7221140833333335 2030,BIOPEL,GBR,winter.day,4.7221140833333335 2030,BIOPEL,GBR,winter.peak,4.7221140833333335 diff --git a/tests/data/muse1_default/commodity_prices.csv b/tests/data/muse1_default/commodity_prices.csv index 097e21a2d..c476f1f02 100644 --- a/tests/data/muse1_default/commodity_prices.csv +++ b/tests/data/muse1_default/commodity_prices.csv @@ -1,106 +1,106 @@ milestone_year,commodity_id,region_id,time_slice,price -2020,electricity,R1,all-year.night,-0.0 -2020,electricity,R1,all-year.morning,-0.0 -2020,electricity,R1,all-year.afternoon,-0.0 -2020,electricity,R1,all-year.early-peak,-0.0 -2020,electricity,R1,all-year.late-peak,-0.0 -2020,electricity,R1,all-year.evening,-0.0 2020,gas,R1,all-year.night,2.55 2020,gas,R1,all-year.morning,2.55 2020,gas,R1,all-year.afternoon,2.55 2020,gas,R1,all-year.early-peak,2.55 2020,gas,R1,all-year.late-peak,2.55 2020,gas,R1,all-year.evening,2.55 +2020,electricity,R1,all-year.night,-0.0 +2020,electricity,R1,all-year.morning,-0.0 +2020,electricity,R1,all-year.afternoon,-0.0 +2020,electricity,R1,all-year.early-peak,-0.0 +2020,electricity,R1,all-year.late-peak,-0.0 +2020,electricity,R1,all-year.evening,-0.0 2020,heat,R1,all-year.night,8.3380664049 2020,heat,R1,all-year.morning,8.3380664049 2020,heat,R1,all-year.afternoon,8.3380664049 2020,heat,R1,all-year.early-peak,8.3380664049 2020,heat,R1,all-year.late-peak,8.3380664049 2020,heat,R1,all-year.evening,8.3380664049 -2025,electricity,R1,all-year.night,15.26529810765 -2025,electricity,R1,all-year.morning,15.26529810765 -2025,electricity,R1,all-year.afternoon,15.26529810765 -2025,electricity,R1,all-year.early-peak,15.26529810765 -2025,electricity,R1,all-year.late-peak,15.26529810765 -2025,electricity,R1,all-year.evening,15.26529810765 2025,gas,R1,all-year.night,2.55 2025,gas,R1,all-year.morning,2.55 2025,gas,R1,all-year.afternoon,2.55 2025,gas,R1,all-year.early-peak,2.55 2025,gas,R1,all-year.late-peak,2.55 2025,gas,R1,all-year.evening,2.55 +2025,electricity,R1,all-year.night,15.26529810765 +2025,electricity,R1,all-year.morning,15.26529810765 +2025,electricity,R1,all-year.afternoon,15.26529810765 +2025,electricity,R1,all-year.early-peak,15.26529810765 +2025,electricity,R1,all-year.late-peak,15.26529810765 +2025,electricity,R1,all-year.evening,15.26529810765 2025,heat,R1,all-year.night,6.10611924306 2025,heat,R1,all-year.morning,6.10611924306 2025,heat,R1,all-year.afternoon,6.10611924306 2025,heat,R1,all-year.early-peak,6.10611924306 2025,heat,R1,all-year.late-peak,10.727716434449999 2025,heat,R1,all-year.evening,6.10611924306 -2030,electricity,R1,all-year.night,-0.0 -2030,electricity,R1,all-year.morning,-0.0 -2030,electricity,R1,all-year.afternoon,-0.0 -2030,electricity,R1,all-year.early-peak,-0.0 -2030,electricity,R1,all-year.late-peak,-0.0 -2030,electricity,R1,all-year.evening,-0.0 2030,gas,R1,all-year.night,-0.0 2030,gas,R1,all-year.morning,-0.0 2030,gas,R1,all-year.afternoon,-0.0 2030,gas,R1,all-year.early-peak,-0.0 2030,gas,R1,all-year.late-peak,-0.0 2030,gas,R1,all-year.evening,-0.0 +2030,electricity,R1,all-year.night,-0.0 +2030,electricity,R1,all-year.morning,-0.0 +2030,electricity,R1,all-year.afternoon,-0.0 +2030,electricity,R1,all-year.early-peak,-0.0 +2030,electricity,R1,all-year.late-peak,-0.0 +2030,electricity,R1,all-year.evening,-0.0 2030,heat,R1,all-year.night,-0.0 2030,heat,R1,all-year.morning,-0.0 2030,heat,R1,all-year.afternoon,-0.0 2030,heat,R1,all-year.early-peak,-0.0 2030,heat,R1,all-year.late-peak,-0.0 2030,heat,R1,all-year.evening,-0.0 -2035,electricity,R1,all-year.night,-0.0 -2035,electricity,R1,all-year.morning,-0.0 -2035,electricity,R1,all-year.afternoon,-0.0 -2035,electricity,R1,all-year.early-peak,-0.0 -2035,electricity,R1,all-year.late-peak,-0.0 -2035,electricity,R1,all-year.evening,-0.0 2035,gas,R1,all-year.night,-0.0 2035,gas,R1,all-year.morning,-0.0 2035,gas,R1,all-year.afternoon,-0.0 2035,gas,R1,all-year.early-peak,-0.0 2035,gas,R1,all-year.late-peak,-0.0 2035,gas,R1,all-year.evening,-0.0 +2035,electricity,R1,all-year.night,-0.0 +2035,electricity,R1,all-year.morning,-0.0 +2035,electricity,R1,all-year.afternoon,-0.0 +2035,electricity,R1,all-year.early-peak,-0.0 +2035,electricity,R1,all-year.late-peak,-0.0 +2035,electricity,R1,all-year.evening,-0.0 2035,heat,R1,all-year.night,-0.0 2035,heat,R1,all-year.morning,-0.0 2035,heat,R1,all-year.afternoon,-0.0 2035,heat,R1,all-year.early-peak,-0.0 2035,heat,R1,all-year.late-peak,-0.0 2035,heat,R1,all-year.evening,-0.0 -2040,electricity,R1,all-year.night,-0.0 -2040,electricity,R1,all-year.morning,-0.0 -2040,electricity,R1,all-year.afternoon,-0.0 -2040,electricity,R1,all-year.early-peak,-0.0 -2040,electricity,R1,all-year.late-peak,-0.0 -2040,electricity,R1,all-year.evening,-0.0 2040,gas,R1,all-year.night,-0.0 2040,gas,R1,all-year.morning,-0.0 2040,gas,R1,all-year.afternoon,-0.0 2040,gas,R1,all-year.early-peak,-0.0 2040,gas,R1,all-year.late-peak,-0.0 2040,gas,R1,all-year.evening,-0.0 +2040,electricity,R1,all-year.night,-0.0 +2040,electricity,R1,all-year.morning,-0.0 +2040,electricity,R1,all-year.afternoon,-0.0 +2040,electricity,R1,all-year.early-peak,-0.0 +2040,electricity,R1,all-year.late-peak,-0.0 +2040,electricity,R1,all-year.evening,-0.0 2040,heat,R1,all-year.night,-0.0 2040,heat,R1,all-year.morning,-0.0 2040,heat,R1,all-year.afternoon,-0.0 2040,heat,R1,all-year.early-peak,-0.0 2040,heat,R1,all-year.late-peak,-0.0 2040,heat,R1,all-year.evening,-0.0 -2045,electricity,R1,all-year.night,-0.0 -2045,electricity,R1,all-year.morning,-0.0 -2045,electricity,R1,all-year.afternoon,-0.0 -2045,electricity,R1,all-year.early-peak,-0.0 -2045,electricity,R1,all-year.late-peak,-0.0 -2045,electricity,R1,all-year.evening,-0.0 2045,gas,R1,all-year.night,-0.0 2045,gas,R1,all-year.morning,-0.0 2045,gas,R1,all-year.afternoon,-0.0 2045,gas,R1,all-year.early-peak,-0.0 2045,gas,R1,all-year.late-peak,-0.0 2045,gas,R1,all-year.evening,-0.0 +2045,electricity,R1,all-year.night,-0.0 +2045,electricity,R1,all-year.morning,-0.0 +2045,electricity,R1,all-year.afternoon,-0.0 +2045,electricity,R1,all-year.early-peak,-0.0 +2045,electricity,R1,all-year.late-peak,-0.0 +2045,electricity,R1,all-year.evening,-0.0 2045,heat,R1,all-year.night,-0.0 2045,heat,R1,all-year.morning,-0.0 2045,heat,R1,all-year.afternoon,-0.0 diff --git a/tests/data/two_outputs/commodity_prices.csv b/tests/data/two_outputs/commodity_prices.csv index 90b7e851e..dd04d0b45 100644 --- a/tests/data/two_outputs/commodity_prices.csv +++ b/tests/data/two_outputs/commodity_prices.csv @@ -31,6 +31,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASPRD,GBR,autumn.day,2.20452 2020,GASPRD,GBR,autumn.peak,2.20452 2020,GASPRD,GBR,autumn.evening,2.20452 +2020,BIOPRD,GBR,winter.night,3.5869398412698414 +2020,BIOPRD,GBR,winter.day,3.5869398412698414 +2020,BIOPRD,GBR,winter.peak,3.5869398412698414 +2020,BIOPRD,GBR,winter.evening,3.5869398412698414 +2020,BIOPRD,GBR,peak.night,3.5869398412698414 +2020,BIOPRD,GBR,peak.day,3.5869398412698414 +2020,BIOPRD,GBR,peak.peak,3.5869398412698414 +2020,BIOPRD,GBR,peak.evening,3.5869398412698414 +2020,BIOPRD,GBR,summer.night,0.25 +2020,BIOPRD,GBR,summer.day,0.25 +2020,BIOPRD,GBR,summer.peak,0.25 +2020,BIOPRD,GBR,summer.evening,0.25 +2020,BIOPRD,GBR,autumn.night,3.586939841269842 +2020,BIOPRD,GBR,autumn.day,3.586939841269842 +2020,BIOPRD,GBR,autumn.peak,3.586939841269842 +2020,BIOPRD,GBR,autumn.evening,3.586939841269842 2020,GASOLI,GBR,winter.night,10.570299353027398 2020,GASOLI,GBR,winter.day,10.570299353027398 2020,GASOLI,GBR,winter.peak,10.570299353027398 @@ -79,6 +95,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASNAT,GBR,autumn.day,2.9170059999999998 2020,GASNAT,GBR,autumn.peak,2.9170059999999998 2020,GASNAT,GBR,autumn.evening,2.9170059999999998 +2020,BIOPEL,GBR,winter.night,4.7221140833333335 +2020,BIOPEL,GBR,winter.day,4.7221140833333335 +2020,BIOPEL,GBR,winter.peak,4.7221140833333335 +2020,BIOPEL,GBR,winter.evening,4.7221140833333335 +2020,BIOPEL,GBR,peak.night,4.7221140833333335 +2020,BIOPEL,GBR,peak.day,4.7221140833333335 +2020,BIOPEL,GBR,peak.peak,4.7221140833333335 +2020,BIOPEL,GBR,peak.evening,4.7221140833333335 +2020,BIOPEL,GBR,summer.night,1.21832725 +2020,BIOPEL,GBR,summer.day,1.21832725 +2020,BIOPEL,GBR,summer.peak,1.21832725 +2020,BIOPEL,GBR,summer.evening,1.21832725 +2020,BIOPEL,GBR,autumn.night,4.7221140833333335 +2020,BIOPEL,GBR,autumn.day,4.7221140833333335 +2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 +2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2020,ELCTRI,GBR,winter.night,7.993308999999999 2020,ELCTRI,GBR,winter.day,17.26223303030303 2020,ELCTRI,GBR,winter.peak,20.410312516918875 @@ -127,38 +159,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,RSHEAT,GBR,autumn.day,5.8665369 2020,RSHEAT,GBR,autumn.peak,5.8665369 2020,RSHEAT,GBR,autumn.evening,5.8665369 -2020,BIOPRD,GBR,winter.night,3.5869398412698414 -2020,BIOPRD,GBR,winter.day,3.5869398412698414 -2020,BIOPRD,GBR,winter.peak,3.5869398412698414 -2020,BIOPRD,GBR,winter.evening,3.5869398412698414 -2020,BIOPRD,GBR,peak.night,3.5869398412698414 -2020,BIOPRD,GBR,peak.day,3.5869398412698414 -2020,BIOPRD,GBR,peak.peak,3.5869398412698414 -2020,BIOPRD,GBR,peak.evening,3.5869398412698414 -2020,BIOPRD,GBR,summer.night,0.25 -2020,BIOPRD,GBR,summer.day,0.25 -2020,BIOPRD,GBR,summer.peak,0.25 -2020,BIOPRD,GBR,summer.evening,0.25 -2020,BIOPRD,GBR,autumn.night,3.586939841269842 -2020,BIOPRD,GBR,autumn.day,3.586939841269842 -2020,BIOPRD,GBR,autumn.peak,3.586939841269842 -2020,BIOPRD,GBR,autumn.evening,3.586939841269842 -2020,BIOPEL,GBR,winter.night,4.7221140833333335 -2020,BIOPEL,GBR,winter.day,4.7221140833333335 -2020,BIOPEL,GBR,winter.peak,4.7221140833333335 -2020,BIOPEL,GBR,winter.evening,4.7221140833333335 -2020,BIOPEL,GBR,peak.night,4.7221140833333335 -2020,BIOPEL,GBR,peak.day,4.7221140833333335 -2020,BIOPEL,GBR,peak.peak,4.7221140833333335 -2020,BIOPEL,GBR,peak.evening,4.7221140833333335 -2020,BIOPEL,GBR,summer.night,1.21832725 -2020,BIOPEL,GBR,summer.day,1.21832725 -2020,BIOPEL,GBR,summer.peak,1.21832725 -2020,BIOPEL,GBR,summer.evening,1.21832725 -2020,BIOPEL,GBR,autumn.night,4.7221140833333335 -2020,BIOPEL,GBR,autumn.day,4.7221140833333335 -2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 -2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2030,OILCRD,GBR,winter.night,3.072868 2030,OILCRD,GBR,winter.day,3.072868 2030,OILCRD,GBR,winter.peak,3.072868 @@ -191,6 +191,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASPRD,GBR,autumn.day,2.20452 2030,GASPRD,GBR,autumn.peak,2.20452 2030,GASPRD,GBR,autumn.evening,2.20452 +2030,BIOPRD,GBR,winter.night,4.249632460317461 +2030,BIOPRD,GBR,winter.day,4.249632460317461 +2030,BIOPRD,GBR,winter.peak,4.249632460317461 +2030,BIOPRD,GBR,winter.evening,4.249632460317461 +2030,BIOPRD,GBR,peak.night,1.822057119047619 +2030,BIOPRD,GBR,peak.day,1.822057119047619 +2030,BIOPRD,GBR,peak.peak,1.822057119047619 +2030,BIOPRD,GBR,peak.evening,1.822057119047619 +2030,BIOPRD,GBR,summer.night,0.25 +2030,BIOPRD,GBR,summer.day,0.25 +2030,BIOPRD,GBR,summer.peak,0.25 +2030,BIOPRD,GBR,summer.evening,0.25 +2030,BIOPRD,GBR,autumn.night,1.822057119047619 +2030,BIOPRD,GBR,autumn.day,1.822057119047619 +2030,BIOPRD,GBR,autumn.peak,1.822057119047619 +2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,GASOLI,GBR,winter.night,5.585457080000001 2030,GASOLI,GBR,winter.day,5.585457080000001 2030,GASOLI,GBR,winter.peak,5.585457080000001 @@ -239,6 +255,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASNAT,GBR,autumn.day,2.9170059999999998 2030,GASNAT,GBR,autumn.peak,2.9170059999999998 2030,GASNAT,GBR,autumn.evening,2.9170059999999998 +2030,BIOPEL,GBR,winter.night,4.7221140833333335 +2030,BIOPEL,GBR,winter.day,4.7221140833333335 +2030,BIOPEL,GBR,winter.peak,4.7221140833333335 +2030,BIOPEL,GBR,winter.evening,4.7221140833333335 +2030,BIOPEL,GBR,peak.night,2.173159975 +2030,BIOPEL,GBR,peak.day,2.173159975 +2030,BIOPEL,GBR,peak.peak,2.173159975 +2030,BIOPEL,GBR,peak.evening,2.173159975 +2030,BIOPEL,GBR,summer.night,0.5225 +2030,BIOPEL,GBR,summer.day,0.5225 +2030,BIOPEL,GBR,summer.peak,0.5225 +2030,BIOPEL,GBR,summer.evening,0.5225 +2030,BIOPEL,GBR,autumn.night,2.173159975 +2030,BIOPEL,GBR,autumn.day,2.173159975 +2030,BIOPEL,GBR,autumn.peak,2.173159975 +2030,BIOPEL,GBR,autumn.evening,2.173159975 2030,ELCTRI,GBR,winter.night,7.993308999999999 2030,ELCTRI,GBR,winter.day,7.993308999999999 2030,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -287,38 +319,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,RSHEAT,GBR,autumn.day,5.8665369 2030,RSHEAT,GBR,autumn.peak,5.8665369 2030,RSHEAT,GBR,autumn.evening,5.8665369 -2030,BIOPRD,GBR,winter.night,4.249632460317461 -2030,BIOPRD,GBR,winter.day,4.249632460317461 -2030,BIOPRD,GBR,winter.peak,4.249632460317461 -2030,BIOPRD,GBR,winter.evening,4.249632460317461 -2030,BIOPRD,GBR,peak.night,1.822057119047619 -2030,BIOPRD,GBR,peak.day,1.822057119047619 -2030,BIOPRD,GBR,peak.peak,1.822057119047619 -2030,BIOPRD,GBR,peak.evening,1.822057119047619 -2030,BIOPRD,GBR,summer.night,0.25 -2030,BIOPRD,GBR,summer.day,0.25 -2030,BIOPRD,GBR,summer.peak,0.25 -2030,BIOPRD,GBR,summer.evening,0.25 -2030,BIOPRD,GBR,autumn.night,1.822057119047619 -2030,BIOPRD,GBR,autumn.day,1.822057119047619 -2030,BIOPRD,GBR,autumn.peak,1.822057119047619 -2030,BIOPRD,GBR,autumn.evening,1.822057119047619 -2030,BIOPEL,GBR,winter.night,4.7221140833333335 -2030,BIOPEL,GBR,winter.day,4.7221140833333335 -2030,BIOPEL,GBR,winter.peak,4.7221140833333335 -2030,BIOPEL,GBR,winter.evening,4.7221140833333335 -2030,BIOPEL,GBR,peak.night,2.173159975 -2030,BIOPEL,GBR,peak.day,2.173159975 -2030,BIOPEL,GBR,peak.peak,2.173159975 -2030,BIOPEL,GBR,peak.evening,2.173159975 -2030,BIOPEL,GBR,summer.night,0.5225 -2030,BIOPEL,GBR,summer.day,0.5225 -2030,BIOPEL,GBR,summer.peak,0.5225 -2030,BIOPEL,GBR,summer.evening,0.5225 -2030,BIOPEL,GBR,autumn.night,2.173159975 -2030,BIOPEL,GBR,autumn.day,2.173159975 -2030,BIOPEL,GBR,autumn.peak,2.173159975 -2030,BIOPEL,GBR,autumn.evening,2.173159975 2040,OILCRD,GBR,winter.night,3.072868 2040,OILCRD,GBR,winter.day,3.072868 2040,OILCRD,GBR,winter.peak,3.072868 @@ -351,6 +351,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASPRD,GBR,autumn.day,2.20452 2040,GASPRD,GBR,autumn.peak,2.20452 2040,GASPRD,GBR,autumn.evening,2.20452 +2040,BIOPRD,GBR,winter.night,0.25 +2040,BIOPRD,GBR,winter.day,0.25 +2040,BIOPRD,GBR,winter.peak,0.25 +2040,BIOPRD,GBR,winter.evening,0.25 +2040,BIOPRD,GBR,peak.night,0.25 +2040,BIOPRD,GBR,peak.day,0.25 +2040,BIOPRD,GBR,peak.peak,0.25 +2040,BIOPRD,GBR,peak.evening,0.25 +2040,BIOPRD,GBR,summer.night,0.25 +2040,BIOPRD,GBR,summer.day,0.25 +2040,BIOPRD,GBR,summer.peak,0.25 +2040,BIOPRD,GBR,summer.evening,0.25 +2040,BIOPRD,GBR,autumn.night,0.25 +2040,BIOPRD,GBR,autumn.day,0.25 +2040,BIOPRD,GBR,autumn.peak,0.25 +2040,BIOPRD,GBR,autumn.evening,0.25 2040,GASOLI,GBR,winter.night,5.585457080000001 2040,GASOLI,GBR,winter.day,5.585457080000001 2040,GASOLI,GBR,winter.peak,5.585457080000001 @@ -383,6 +399,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASNAT,GBR,autumn.day,2.9170059999999998 2040,GASNAT,GBR,autumn.peak,2.9170059999999998 2040,GASNAT,GBR,autumn.evening,2.9170059999999998 +2040,BIOPEL,GBR,winter.night,0.5225 +2040,BIOPEL,GBR,winter.day,0.5225 +2040,BIOPEL,GBR,winter.peak,0.5225 +2040,BIOPEL,GBR,winter.evening,0.5225 +2040,BIOPEL,GBR,peak.night,0.5225 +2040,BIOPEL,GBR,peak.day,0.5225 +2040,BIOPEL,GBR,peak.peak,0.5225 +2040,BIOPEL,GBR,peak.evening,0.5225 +2040,BIOPEL,GBR,summer.night,0.5225 +2040,BIOPEL,GBR,summer.day,0.5225 +2040,BIOPEL,GBR,summer.peak,0.5225 +2040,BIOPEL,GBR,summer.evening,0.5225 +2040,BIOPEL,GBR,autumn.night,0.5225 +2040,BIOPEL,GBR,autumn.day,0.5225 +2040,BIOPEL,GBR,autumn.peak,0.5225 +2040,BIOPEL,GBR,autumn.evening,0.5225 2040,ELCTRI,GBR,winter.night,7.993308999999999 2040,ELCTRI,GBR,winter.day,7.993308999999999 2040,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -431,35 +463,3 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,RSHEAT,GBR,autumn.day,0.827 2040,RSHEAT,GBR,autumn.peak,0.827 2040,RSHEAT,GBR,autumn.evening,0.827 -2040,BIOPRD,GBR,winter.night,0.25 -2040,BIOPRD,GBR,winter.day,0.25 -2040,BIOPRD,GBR,winter.peak,0.25 -2040,BIOPRD,GBR,winter.evening,0.25 -2040,BIOPRD,GBR,peak.night,0.25 -2040,BIOPRD,GBR,peak.day,0.25 -2040,BIOPRD,GBR,peak.peak,0.25 -2040,BIOPRD,GBR,peak.evening,0.25 -2040,BIOPRD,GBR,summer.night,0.25 -2040,BIOPRD,GBR,summer.day,0.25 -2040,BIOPRD,GBR,summer.peak,0.25 -2040,BIOPRD,GBR,summer.evening,0.25 -2040,BIOPRD,GBR,autumn.night,0.25 -2040,BIOPRD,GBR,autumn.day,0.25 -2040,BIOPRD,GBR,autumn.peak,0.25 -2040,BIOPRD,GBR,autumn.evening,0.25 -2040,BIOPEL,GBR,winter.night,0.5225 -2040,BIOPEL,GBR,winter.day,0.5225 -2040,BIOPEL,GBR,winter.peak,0.5225 -2040,BIOPEL,GBR,winter.evening,0.5225 -2040,BIOPEL,GBR,peak.night,0.5225 -2040,BIOPEL,GBR,peak.day,0.5225 -2040,BIOPEL,GBR,peak.peak,0.5225 -2040,BIOPEL,GBR,peak.evening,0.5225 -2040,BIOPEL,GBR,summer.night,0.5225 -2040,BIOPEL,GBR,summer.day,0.5225 -2040,BIOPEL,GBR,summer.peak,0.5225 -2040,BIOPEL,GBR,summer.evening,0.5225 -2040,BIOPEL,GBR,autumn.night,0.5225 -2040,BIOPEL,GBR,autumn.day,0.5225 -2040,BIOPEL,GBR,autumn.peak,0.5225 -2040,BIOPEL,GBR,autumn.evening,0.5225 diff --git a/tests/data/two_regions/commodity_prices.csv b/tests/data/two_regions/commodity_prices.csv index 11a49d2bf..267136d1f 100644 --- a/tests/data/two_regions/commodity_prices.csv +++ b/tests/data/two_regions/commodity_prices.csv @@ -1,16 +1,4 @@ milestone_year,commodity_id,region_id,time_slice,price -2020,electricity,R1,all-year.night,-0.0 -2020,electricity,R1,all-year.morning,-0.0 -2020,electricity,R1,all-year.afternoon,-0.0 -2020,electricity,R1,all-year.early-peak,-0.0 -2020,electricity,R1,all-year.late-peak,-0.0 -2020,electricity,R1,all-year.evening,-0.0 -2020,electricity,R2,all-year.night,-0.0 -2020,electricity,R2,all-year.morning,-0.0 -2020,electricity,R2,all-year.afternoon,-0.0 -2020,electricity,R2,all-year.early-peak,-0.0 -2020,electricity,R2,all-year.late-peak,-0.0 -2020,electricity,R2,all-year.evening,-0.0 2020,gas,R1,all-year.night,2.55 2020,gas,R1,all-year.morning,2.55 2020,gas,R1,all-year.afternoon,2.55 @@ -23,6 +11,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,gas,R2,all-year.early-peak,2.55 2020,gas,R2,all-year.late-peak,2.55 2020,gas,R2,all-year.evening,2.55 +2020,electricity,R1,all-year.night,-0.0 +2020,electricity,R1,all-year.morning,-0.0 +2020,electricity,R1,all-year.afternoon,-0.0 +2020,electricity,R1,all-year.early-peak,-0.0 +2020,electricity,R1,all-year.late-peak,-0.0 +2020,electricity,R1,all-year.evening,-0.0 +2020,electricity,R2,all-year.night,-0.0 +2020,electricity,R2,all-year.morning,-0.0 +2020,electricity,R2,all-year.afternoon,-0.0 +2020,electricity,R2,all-year.early-peak,-0.0 +2020,electricity,R2,all-year.late-peak,-0.0 +2020,electricity,R2,all-year.evening,-0.0 2020,heat,R1,all-year.night,8.3380664049 2020,heat,R1,all-year.morning,8.3380664049 2020,heat,R1,all-year.afternoon,8.3380664049 @@ -35,18 +35,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,heat,R2,all-year.early-peak,2.9579999999999997 2020,heat,R2,all-year.late-peak,2.9579999999999997 2020,heat,R2,all-year.evening,2.9579999999999997 -2025,electricity,R1,all-year.night,15.26529810765 -2025,electricity,R1,all-year.morning,15.26529810765 -2025,electricity,R1,all-year.afternoon,15.26529810765 -2025,electricity,R1,all-year.early-peak,15.26529810765 -2025,electricity,R1,all-year.late-peak,15.26529810765 -2025,electricity,R1,all-year.evening,15.26529810765 -2025,electricity,R2,all-year.night,4.2585 -2025,electricity,R2,all-year.morning,4.2585 -2025,electricity,R2,all-year.afternoon,4.2585 -2025,electricity,R2,all-year.early-peak,4.2585 -2025,electricity,R2,all-year.late-peak,4.2585 -2025,electricity,R2,all-year.evening,4.2585 2025,gas,R1,all-year.night,2.5500000000000007 2025,gas,R1,all-year.morning,2.55 2025,gas,R1,all-year.afternoon,2.55 @@ -59,6 +47,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2025,gas,R2,all-year.early-peak,2.55 2025,gas,R2,all-year.late-peak,2.55 2025,gas,R2,all-year.evening,2.55 +2025,electricity,R1,all-year.night,15.26529810765 +2025,electricity,R1,all-year.morning,15.26529810765 +2025,electricity,R1,all-year.afternoon,15.26529810765 +2025,electricity,R1,all-year.early-peak,15.26529810765 +2025,electricity,R1,all-year.late-peak,15.26529810765 +2025,electricity,R1,all-year.evening,15.26529810765 +2025,electricity,R2,all-year.night,4.2585 +2025,electricity,R2,all-year.morning,4.2585 +2025,electricity,R2,all-year.afternoon,4.2585 +2025,electricity,R2,all-year.early-peak,4.2585 +2025,electricity,R2,all-year.late-peak,4.2585 +2025,electricity,R2,all-year.evening,4.2585 2025,heat,R1,all-year.night,6.10611924306 2025,heat,R1,all-year.morning,6.10611924306 2025,heat,R1,all-year.afternoon,6.10611924306 @@ -71,18 +71,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2025,heat,R2,all-year.early-peak,2.9579999999999997 2025,heat,R2,all-year.late-peak,2.9579999999999997 2025,heat,R2,all-year.evening,2.9579999999999997 -2030,electricity,R1,all-year.night,-0.0 -2030,electricity,R1,all-year.morning,-0.0 -2030,electricity,R1,all-year.afternoon,-0.0 -2030,electricity,R1,all-year.early-peak,-0.0 -2030,electricity,R1,all-year.late-peak,-0.0 -2030,electricity,R1,all-year.evening,-0.0 -2030,electricity,R2,all-year.night,4.2585 -2030,electricity,R2,all-year.morning,4.2585 -2030,electricity,R2,all-year.afternoon,4.2585 -2030,electricity,R2,all-year.early-peak,4.2585 -2030,electricity,R2,all-year.late-peak,4.2585 -2030,electricity,R2,all-year.evening,4.2585 2030,gas,R1,all-year.night,-0.0 2030,gas,R1,all-year.morning,-0.0 2030,gas,R1,all-year.afternoon,-0.0 @@ -95,6 +83,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,gas,R2,all-year.early-peak,2.55 2030,gas,R2,all-year.late-peak,2.5500000000000003 2030,gas,R2,all-year.evening,2.55 +2030,electricity,R1,all-year.night,-0.0 +2030,electricity,R1,all-year.morning,-0.0 +2030,electricity,R1,all-year.afternoon,-0.0 +2030,electricity,R1,all-year.early-peak,-0.0 +2030,electricity,R1,all-year.late-peak,-0.0 +2030,electricity,R1,all-year.evening,-0.0 +2030,electricity,R2,all-year.night,4.2585 +2030,electricity,R2,all-year.morning,4.2585 +2030,electricity,R2,all-year.afternoon,4.2585 +2030,electricity,R2,all-year.early-peak,4.2585 +2030,electricity,R2,all-year.late-peak,4.2585 +2030,electricity,R2,all-year.evening,4.2585 2030,heat,R1,all-year.night,-0.0 2030,heat,R1,all-year.morning,-0.0 2030,heat,R1,all-year.afternoon,-0.0 @@ -107,18 +107,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,heat,R2,all-year.early-peak,2.9579999999999997 2030,heat,R2,all-year.late-peak,2.958 2030,heat,R2,all-year.evening,2.9579999999999997 -2035,electricity,R1,all-year.night,-0.0 -2035,electricity,R1,all-year.morning,-0.0 -2035,electricity,R1,all-year.afternoon,-0.0 -2035,electricity,R1,all-year.early-peak,-0.0 -2035,electricity,R1,all-year.late-peak,-0.0 -2035,electricity,R1,all-year.evening,-0.0 -2035,electricity,R2,all-year.night,4.2585 -2035,electricity,R2,all-year.morning,4.2585 -2035,electricity,R2,all-year.afternoon,4.2585 -2035,electricity,R2,all-year.early-peak,4.2585 -2035,electricity,R2,all-year.late-peak,4.2585 -2035,electricity,R2,all-year.evening,4.2585 2035,gas,R1,all-year.night,-0.0 2035,gas,R1,all-year.morning,-0.0 2035,gas,R1,all-year.afternoon,-0.0 @@ -131,6 +119,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2035,gas,R2,all-year.early-peak,2.55 2035,gas,R2,all-year.late-peak,2.55 2035,gas,R2,all-year.evening,2.55 +2035,electricity,R1,all-year.night,-0.0 +2035,electricity,R1,all-year.morning,-0.0 +2035,electricity,R1,all-year.afternoon,-0.0 +2035,electricity,R1,all-year.early-peak,-0.0 +2035,electricity,R1,all-year.late-peak,-0.0 +2035,electricity,R1,all-year.evening,-0.0 +2035,electricity,R2,all-year.night,4.2585 +2035,electricity,R2,all-year.morning,4.2585 +2035,electricity,R2,all-year.afternoon,4.2585 +2035,electricity,R2,all-year.early-peak,4.2585 +2035,electricity,R2,all-year.late-peak,4.2585 +2035,electricity,R2,all-year.evening,4.2585 2035,heat,R1,all-year.night,-0.0 2035,heat,R1,all-year.morning,-0.0 2035,heat,R1,all-year.afternoon,-0.0 @@ -143,18 +143,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2035,heat,R2,all-year.early-peak,2.9579999999999997 2035,heat,R2,all-year.late-peak,2.9579999999999997 2035,heat,R2,all-year.evening,2.9579999999999997 -2040,electricity,R1,all-year.night,-0.0 -2040,electricity,R1,all-year.morning,-0.0 -2040,electricity,R1,all-year.afternoon,-0.0 -2040,electricity,R1,all-year.early-peak,-0.0 -2040,electricity,R1,all-year.late-peak,-0.0 -2040,electricity,R1,all-year.evening,-0.0 -2040,electricity,R2,all-year.night,4.2585 -2040,electricity,R2,all-year.morning,4.2585 -2040,electricity,R2,all-year.afternoon,4.2585 -2040,electricity,R2,all-year.early-peak,4.2585 -2040,electricity,R2,all-year.late-peak,4.2585 -2040,electricity,R2,all-year.evening,4.2585 2040,gas,R1,all-year.night,-0.0 2040,gas,R1,all-year.morning,-0.0 2040,gas,R1,all-year.afternoon,-0.0 @@ -167,6 +155,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,gas,R2,all-year.early-peak,2.55 2040,gas,R2,all-year.late-peak,2.55 2040,gas,R2,all-year.evening,2.55 +2040,electricity,R1,all-year.night,-0.0 +2040,electricity,R1,all-year.morning,-0.0 +2040,electricity,R1,all-year.afternoon,-0.0 +2040,electricity,R1,all-year.early-peak,-0.0 +2040,electricity,R1,all-year.late-peak,-0.0 +2040,electricity,R1,all-year.evening,-0.0 +2040,electricity,R2,all-year.night,4.2585 +2040,electricity,R2,all-year.morning,4.2585 +2040,electricity,R2,all-year.afternoon,4.2585 +2040,electricity,R2,all-year.early-peak,4.2585 +2040,electricity,R2,all-year.late-peak,4.2585 +2040,electricity,R2,all-year.evening,4.2585 2040,heat,R1,all-year.night,-0.0 2040,heat,R1,all-year.morning,-0.0 2040,heat,R1,all-year.afternoon,-0.0 @@ -179,18 +179,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,heat,R2,all-year.early-peak,2.9579999999999997 2040,heat,R2,all-year.late-peak,2.9579999999999997 2040,heat,R2,all-year.evening,2.9579999999999997 -2045,electricity,R1,all-year.night,-0.0 -2045,electricity,R1,all-year.morning,-0.0 -2045,electricity,R1,all-year.afternoon,-0.0 -2045,electricity,R1,all-year.early-peak,-0.0 -2045,electricity,R1,all-year.late-peak,-0.0 -2045,electricity,R1,all-year.evening,-0.0 -2045,electricity,R2,all-year.night,4.2585 -2045,electricity,R2,all-year.morning,4.2585 -2045,electricity,R2,all-year.afternoon,4.2585 -2045,electricity,R2,all-year.early-peak,4.2585 -2045,electricity,R2,all-year.late-peak,4.2585 -2045,electricity,R2,all-year.evening,4.2585 2045,gas,R1,all-year.night,-0.0 2045,gas,R1,all-year.morning,-0.0 2045,gas,R1,all-year.afternoon,-0.0 @@ -203,6 +191,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2045,gas,R2,all-year.early-peak,2.5500000000000003 2045,gas,R2,all-year.late-peak,2.55 2045,gas,R2,all-year.evening,2.55 +2045,electricity,R1,all-year.night,-0.0 +2045,electricity,R1,all-year.morning,-0.0 +2045,electricity,R1,all-year.afternoon,-0.0 +2045,electricity,R1,all-year.early-peak,-0.0 +2045,electricity,R1,all-year.late-peak,-0.0 +2045,electricity,R1,all-year.evening,-0.0 +2045,electricity,R2,all-year.night,4.2585 +2045,electricity,R2,all-year.morning,4.2585 +2045,electricity,R2,all-year.afternoon,4.2585 +2045,electricity,R2,all-year.early-peak,4.2585 +2045,electricity,R2,all-year.late-peak,4.2585 +2045,electricity,R2,all-year.evening,4.2585 2045,heat,R1,all-year.night,-0.0 2045,heat,R1,all-year.morning,-0.0 2045,heat,R1,all-year.afternoon,-0.0 @@ -215,6 +215,12 @@ milestone_year,commodity_id,region_id,time_slice,price 2045,heat,R2,all-year.early-peak,2.958 2045,heat,R2,all-year.late-peak,2.9579999999999997 2045,heat,R2,all-year.evening,2.9579999999999997 +2050,gas,R2,all-year.night,2.55 +2050,gas,R2,all-year.morning,2.55 +2050,gas,R2,all-year.afternoon,2.55 +2050,gas,R2,all-year.early-peak,2.55 +2050,gas,R2,all-year.late-peak,2.55 +2050,gas,R2,all-year.evening,2.55 2050,electricity,R1,all-year.night,-0.0 2050,electricity,R1,all-year.morning,-0.0 2050,electricity,R1,all-year.afternoon,-0.0 @@ -227,12 +233,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2050,electricity,R2,all-year.early-peak,4.2585 2050,electricity,R2,all-year.late-peak,4.2585 2050,electricity,R2,all-year.evening,4.2585 -2050,gas,R2,all-year.night,2.55 -2050,gas,R2,all-year.morning,2.55 -2050,gas,R2,all-year.afternoon,2.55 -2050,gas,R2,all-year.early-peak,2.55 -2050,gas,R2,all-year.late-peak,2.55 -2050,gas,R2,all-year.evening,2.55 2050,heat,R1,all-year.night,-0.0 2050,heat,R1,all-year.morning,-0.0 2050,heat,R1,all-year.afternoon,-0.0