Skip to content

Commit 68b306d

Browse files
committed
Fix issue with prices
1 parent d3e7801 commit 68b306d

1 file changed

Lines changed: 49 additions & 20 deletions

File tree

src/simulation/investment.rs

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ impl InvestmentSet {
4343
InvestmentSet::Cycle(ids) => ids.iter(),
4444
}
4545
}
46+
47+
/// Converts the investment set to a vector of commodity IDs
48+
pub fn to_vec(&self) -> Vec<CommodityID> {
49+
match self {
50+
InvestmentSet::Single(id) => vec![id.clone()],
51+
InvestmentSet::Cycle(ids) => ids.clone(),
52+
}
53+
}
4654
}
4755

4856
impl Display for InvestmentSet {
@@ -78,35 +86,39 @@ pub fn perform_agent_investment(
7886
// This includes Commissioned assets that are selected for retention, and new Selected assets
7987
let mut all_selected_assets = Vec::new();
8088

81-
// External prices to be used in dispatch optimisation
82-
// Once investments are performed for a commodity, the dispatch system will be able to produce
83-
// endogenous prices for that commodity, so we'll gradually remove these external prices.
84-
let mut external_prices = prices.clone();
85-
8689
for region_id in model.iter_regions() {
90+
let investment_order = &model.investment_order[&(region_id.clone(), year)];
91+
92+
// External prices to be used in dispatch optimisation
93+
// Once investments are performed for a commodity, the dispatch system will be able to produce
94+
// endogenous prices for that commodity, so we'll gradually remove these external prices.
95+
let cur_commodities: &Vec<_> = &investment_order
96+
.iter()
97+
.flat_map(InvestmentSet::iter)
98+
.cloned()
99+
.collect();
100+
let mut external_prices =
101+
get_prices_for_commodities(prices, &model.time_slice_info, region_id, cur_commodities);
102+
87103
// Keep track of the commodities that have been seen so far. This will be used to apply
88104
// balance constraints in the dispatch optimisation - we only apply balance constraints for
89105
// commodities that have been seen so far.
90106
let mut seen_commodities = Vec::new();
91107

92108
// Iterate over investment sets in the investment order for this region/year
93-
let investment_order = &model.investment_order[&(region_id.clone(), year)];
94109
for investment_set in investment_order {
95110
// Select assets for the commodity(/ies) of interest
96111
let selected_assets = match investment_set {
97-
InvestmentSet::Single(commodity_id) => {
98-
let commodity = &model.commodities[commodity_id];
99-
select_assets_for_commodity(
100-
model,
101-
commodity,
102-
region_id,
103-
year,
104-
&demand,
105-
existing_assets,
106-
prices,
107-
writer,
108-
)?
109-
}
112+
InvestmentSet::Single(commodity_id) => select_assets_for_commodity(
113+
model,
114+
commodity_id,
115+
region_id,
116+
year,
117+
&demand,
118+
existing_assets,
119+
prices,
120+
writer,
121+
)?,
110122
InvestmentSet::Cycle(_) => {
111123
bail!(
112124
"Investment cycles are not yet supported. Found cycle for commodities: {investment_set}"
@@ -172,14 +184,16 @@ pub fn perform_agent_investment(
172184
#[allow(clippy::too_many_arguments)]
173185
fn select_assets_for_commodity(
174186
model: &Model,
175-
commodity: &Commodity,
187+
commodity_id: &CommodityID,
176188
region_id: &RegionID,
177189
year: u32,
178190
demand: &AllDemandMap,
179191
existing_assets: &[AssetRef],
180192
prices: &CommodityPrices,
181193
writer: &mut DataWriter,
182194
) -> Result<Vec<AssetRef>> {
195+
let commodity = &model.commodities[commodity_id];
196+
183197
let mut selected_assets = Vec::new();
184198
for (agent, commodity_portion) in
185199
get_responsible_agents(model.agents.values(), &commodity.id, region_id, year)
@@ -429,6 +443,21 @@ fn get_candidate_assets<'a>(
429443
})
430444
}
431445

446+
/// Get a map of prices for a subset of commodities
447+
fn get_prices_for_commodities(
448+
prices: &CommodityPrices,
449+
time_slice_info: &TimeSliceInfo,
450+
region_id: &RegionID,
451+
commodities: &[CommodityID],
452+
) -> CommodityPrices {
453+
iproduct!(commodities.iter(), time_slice_info.iter_ids())
454+
.map(|(commodity_id, time_slice)| {
455+
let price = prices.get(commodity_id, region_id, time_slice).unwrap();
456+
(commodity_id, region_id, time_slice, price)
457+
})
458+
.collect()
459+
}
460+
432461
/// Get the best assets for meeting demand for the given commodity
433462
#[allow(clippy::too_many_arguments)]
434463
fn select_best_assets(

0 commit comments

Comments
 (0)