muse2/simulation/investment/appraisal/
costs.rs

1//! Costs for the optimisation problem.
2use crate::asset::{AssetRef, AssetState};
3use crate::finance::annual_capital_cost;
4use crate::units::{MoneyPerCapacity, Year};
5
6/// Calculates the annual fixed costs per unit of capacity for an asset.
7///
8/// The behaviour depends on whether the asset is commissioned or a candidate:
9/// - For a commissioned asset, this only includes operating costs.
10/// - For a candidate asset, this includes both operating and capital costs.
11pub fn annual_fixed_cost(asset: &AssetRef) -> MoneyPerCapacity {
12    match asset.state() {
13        AssetState::Commissioned { .. } => annual_fixed_cost_for_existing(asset),
14        AssetState::Candidate => annual_fixed_cost_for_candidate(asset),
15        _ => {
16            panic!("annual_fixed_cost should only be called with Commissioned or Candidate assets")
17        }
18    }
19}
20
21fn annual_fixed_cost_for_existing(asset: &AssetRef) -> MoneyPerCapacity {
22    let fixed_operating_cost = asset.process_parameter().fixed_operating_cost;
23    fixed_operating_cost * Year(1.0)
24}
25
26fn annual_capital_cost_for_candidate(asset: &AssetRef) -> MoneyPerCapacity {
27    let capital_cost = asset.process_parameter().capital_cost;
28    let lifetime = asset.process_parameter().lifetime;
29    let discount_rate = asset.process_parameter().discount_rate;
30    annual_capital_cost(capital_cost, lifetime, discount_rate)
31}
32
33fn annual_fixed_cost_for_candidate(asset: &AssetRef) -> MoneyPerCapacity {
34    let fixed_operating_cost = asset.process_parameter().fixed_operating_cost;
35    let annual_fixed_operating_cost = fixed_operating_cost * Year(1.0);
36    let capital_costs = annual_capital_cost_for_candidate(asset);
37    annual_fixed_operating_cost + capital_costs
38}