Skip to content

Commit 36eefc3

Browse files
committed
Add commodity prices
Closes #589.
1 parent 4473c5d commit 36eefc3

2 files changed

Lines changed: 36 additions & 14 deletions

File tree

src/simulation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn run(
5252
// Dispatch optimisation
5353
let solution = perform_dispatch_optimisation(&model, &assets, year)?;
5454
let flow_map = solution.create_flow_map();
55-
let prices = CommodityPrices::from_model_and_solution(&model, &solution, &assets);
55+
let prices = CommodityPrices::from_model_and_solution(&model, &solution);
5656

5757
// Write result of dispatch optimisation to file
5858
writer.write_debug_info(year, &solution)?;

src/simulation/prices.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! Code for updating the simulation state.
22
use super::optimisation::Solution;
3-
use crate::asset::AssetPool;
43
use crate::commodity::CommodityID;
54
use crate::model::Model;
65
use crate::region::RegionID;
76
use crate::time_slice::{TimeSliceID, TimeSliceInfo};
87
use log::warn;
9-
use std::collections::{BTreeMap, HashSet};
8+
use std::collections::{BTreeMap, HashMap, HashSet};
109

1110
/// A map relating commodity ID + region + time slice to current price (endogenous)
1211
#[derive(Default)]
@@ -16,9 +15,9 @@ impl CommodityPrices {
1615
/// Calculate commodity prices based on the result of the dispatch optimisation.
1716
///
1817
/// Missing prices will be calculated directly from the input data
19-
pub fn from_model_and_solution(model: &Model, solution: &Solution, assets: &AssetPool) -> Self {
18+
pub fn from_model_and_solution(model: &Model, solution: &Solution) -> Self {
2019
let mut prices = CommodityPrices::default();
21-
let commodity_regions_updated = prices.add_from_solution(solution, assets);
20+
let commodity_regions_updated = prices.add_from_solution(solution);
2221

2322
// Find commodity/region combinations not updated in last step
2423
let mut remaining_commodity_regions = HashSet::new();
@@ -44,20 +43,43 @@ impl CommodityPrices {
4443
/// # Arguments
4544
///
4645
/// * `solution` - The solution to the dispatch optimisation
47-
/// * `assets` - The asset pool
4846
///
4947
/// # Returns
5048
///
5149
/// The set of commodities for which prices were added.
52-
fn add_from_solution(
53-
&mut self,
54-
_solution: &Solution,
55-
_assets: &AssetPool,
56-
) -> HashSet<(CommodityID, RegionID)> {
57-
// **TODO:** Calculate commodity prices here:
58-
// https://github.com/EnergySystemsModellingLab/MUSE_2.0/issues/589
50+
fn add_from_solution(&mut self, solution: &Solution) -> HashSet<(CommodityID, RegionID)> {
51+
let mut commodity_regions_updated = HashSet::new();
52+
53+
// Calculate highest activity dual for each commodity/region/timeslice
54+
let mut highest_duals = HashMap::new();
55+
for (asset, time_slice, dual) in solution.iter_activity_duals() {
56+
// Iterate over all output flows
57+
for flow in asset.iter_flows().filter(|flow| flow.coeff > 0.0) {
58+
// Update the highest dual for this commodity/timeslice
59+
highest_duals
60+
.entry((
61+
flow.commodity.id.clone(),
62+
asset.region_id.clone(),
63+
time_slice.clone(),
64+
))
65+
.and_modify(|current_dual| {
66+
if dual > *current_dual {
67+
*current_dual = dual;
68+
}
69+
})
70+
.or_insert(dual);
71+
}
72+
}
73+
74+
// Add the highest capacity dual for each commodity/timeslice to each commodity balance dual
75+
for (commodity_id, region_id, time_slice, dual) in solution.iter_commodity_balance_duals() {
76+
let key = (commodity_id.clone(), region_id.clone(), time_slice.clone());
77+
let price = dual + highest_duals.get(&key).unwrap_or(&0.0);
78+
self.insert(commodity_id, region_id, time_slice, price);
79+
commodity_regions_updated.insert((commodity_id.clone(), region_id.clone()));
80+
}
5981

60-
HashSet::new()
82+
commodity_regions_updated
6183
}
6284

6385
/// Add prices for any commodity not updated by the dispatch step.

0 commit comments

Comments
 (0)