Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/simple/process_parameters.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
process_id,start_year,end_year,capital_cost,fixed_operating_cost,variable_operating_cost,lifetime,discount_rate,cap2act
process_id,start_year,end_year,capital_cost,fixed_operating_cost,variable_operating_cost,lifetime,discount_rate,capacity_to_activity
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cap2act is used in other energy systems models so we might consider keeping this. Maybe @ahawkes can comment?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, interesting. I assumed it was a MUSE-ism. If spelling it out sounds silly to economists, then let's leave it as is.

We could always spell it out in the code and leave it abbreviated in the CSV column names if we wanted to.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahawkes do you have an opinion on this? It'd be good to get this PR merged in some form soonish so that we don't get merge conflicts.

GASDRV,2020,2030,10.0,0.3,2.0,25,0.1,1.0
GASPRC,2020,2030,7.0,0.21,0.5,25,0.1,1.0
WNDFRM,2020,2030,1000.0,30.0,0.4,25,0.1,31.54
Expand Down
23 changes: 14 additions & 9 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,16 @@ impl Asset {

/// Get the activity limits for this asset in a particular time slice
pub fn get_activity_limits(&self, time_slice: &TimeSliceID) -> RangeInclusive<f64> {
let limits = self.process.capacity_fractions.get(time_slice).unwrap();
let capacity_a = self.capacity * self.process.parameter.cap2act;
let limits = self.process.activity_limits.get(time_slice).unwrap();
let max_act = self.maximum_activity();

// Multiply the fractional capacity in self.process by this asset's actual capacity
(capacity_a * limits.start())..=(capacity_a * limits.end())
(max_act * limits.start())..=(max_act * limits.end())
}

/// Maximum activity for this asset in a year
pub fn maximum_activity(&self) -> f64 {
self.capacity * self.process.parameter.capacity_to_activity
}
}

Expand Down Expand Up @@ -276,7 +281,7 @@ impl AssetPool {
mod tests {
use super::*;
use crate::commodity::{CommodityCostMap, CommodityType, DemandMap};
use crate::process::{FlowType, Process, ProcessCapacityMap, ProcessFlow, ProcessParameter};
use crate::process::{ActivityLimitsMap, FlowType, Process, ProcessFlow, ProcessParameter};
use crate::time_slice::TimeSliceLevel;
use itertools::{assert_equal, Itertools};
use std::iter;
Expand All @@ -295,7 +300,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 5,
discount_rate: 0.9,
cap2act: 3.0,
capacity_to_activity: 3.0,
};
let commodity = Rc::new(Commodity {
id: "commodity1".into(),
Expand All @@ -314,11 +319,11 @@ mod tests {
is_pac: true,
};
let fraction_limits = 1.0..=f64::INFINITY;
let capacity_fractions = iter::once((time_slice.clone(), fraction_limits)).collect();
let activity_limits = iter::once((time_slice.clone(), fraction_limits)).collect();
let process = Rc::new(Process {
id: "process1".into(),
description: "Description".into(),
capacity_fractions,
activity_limits,
flows: vec![flow.clone()],
parameter: process_param.clone(),
regions: RegionSelection::All,
Expand All @@ -344,12 +349,12 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 5,
discount_rate: 0.9,
cap2act: 1.0,
capacity_to_activity: 1.0,
};
let process = Rc::new(Process {
id: "process1".into(),
description: "Description".into(),
capacity_fractions: ProcessCapacityMap::new(),
activity_limits: ActivityLimitsMap::new(),
flows: vec![],
parameter: process_param.clone(),
regions: RegionSelection::All,
Expand Down
8 changes: 4 additions & 4 deletions src/input/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::process::{Process, ProcessCapacityMap, ProcessParameter};
use crate::process::{ActivityLimitsMap, Process, ProcessParameter};
use crate::region::RegionSelection;
use itertools::assert_equal;
use std::iter;
Expand All @@ -107,12 +107,12 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 5,
discount_rate: 0.9,
cap2act: 1.0,
capacity_to_activity: 1.0,
};
let process = Rc::new(Process {
id: "process1".into(),
description: "Description".into(),
capacity_fractions: ProcessCapacityMap::new(),
activity_limits: ActivityLimitsMap::new(),
flows: vec![],
parameter: process_param.clone(),
regions: RegionSelection::All,
Expand Down Expand Up @@ -187,7 +187,7 @@ mod tests {
let process = Rc::new(Process {
id: "process1".into(),
description: "Description".into(),
capacity_fractions: ProcessCapacityMap::new(),
activity_limits: ActivityLimitsMap::new(),
flows: vec![],
parameter: process_param,
regions: RegionSelection::Some(["GBR".into()].into_iter().collect()),
Expand Down
16 changes: 8 additions & 8 deletions src/input/process.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Code for reading process-related information from CSV files.
use crate::commodity::{Commodity, CommodityMap, CommodityType};
use crate::input::*;
use crate::process::{Process, ProcessCapacityMap, ProcessFlow, ProcessMap, ProcessParameter};
use crate::process::{ActivityLimitsMap, Process, ProcessFlow, ProcessMap, ProcessParameter};
use crate::region::RegionSelection;
use crate::time_slice::TimeSliceInfo;
use anyhow::Result;
Expand Down Expand Up @@ -95,7 +95,7 @@ struct ValidationParams<'a> {
milestone_years: &'a [u32],
time_slice_info: &'a TimeSliceInfo,
parameters: &'a HashMap<Rc<str>, ProcessParameter>,
availabilities: &'a HashMap<Rc<str>, ProcessCapacityMap>,
availabilities: &'a HashMap<Rc<str>, ActivityLimitsMap>,
}

/// Perform consistency checks for commodity flows.
Expand All @@ -106,7 +106,7 @@ fn validate_commodities(
milestone_years: &[u32],
time_slice_info: &TimeSliceInfo,
parameters: &HashMap<Rc<str>, ProcessParameter>,
availabilities: &HashMap<Rc<str>, ProcessCapacityMap>,
availabilities: &HashMap<Rc<str>, ActivityLimitsMap>,
) -> anyhow::Result<()> {
let params = ValidationParams {
flows,
Expand Down Expand Up @@ -213,7 +213,7 @@ fn validate_svd_commodity(

fn create_process_map<I>(
descriptions: I,
mut availabilities: HashMap<Rc<str>, ProcessCapacityMap>,
mut availabilities: HashMap<Rc<str>, ActivityLimitsMap>,
mut flows: HashMap<Rc<str>, Vec<ProcessFlow>>,
mut parameters: HashMap<Rc<str>, ProcessParameter>,
mut regions: HashMap<Rc<str>, RegionSelection>,
Expand All @@ -240,7 +240,7 @@ where
let process = Process {
id: Rc::clone(id),
description: description.description,
capacity_fractions: availabilities,
activity_limits: availabilities,
flows,
parameter,
regions,
Expand All @@ -263,7 +263,7 @@ mod tests {

struct ProcessData {
descriptions: Vec<ProcessDescription>,
availabilities: HashMap<Rc<str>, ProcessCapacityMap>,
availabilities: HashMap<Rc<str>, ActivityLimitsMap>,
flows: HashMap<Rc<str>, Vec<ProcessFlow>>,
parameters: HashMap<Rc<str>, ProcessParameter>,
regions: HashMap<Rc<str>, RegionSelection>,
Expand All @@ -286,7 +286,7 @@ mod tests {
let availabilities = ["process1", "process2"]
.into_iter()
.map(|id| {
let mut map = ProcessCapacityMap::new();
let mut map = ActivityLimitsMap::new();
map.insert(
TimeSliceID {
season: "winter".into(),
Expand Down Expand Up @@ -314,7 +314,7 @@ mod tests {
variable_operating_cost: 0.0,
lifetime: 1,
discount_rate: 1.0,
cap2act: 0.0,
capacity_to_activity: 0.0,
};

(id.into(), parameter)
Expand Down
16 changes: 7 additions & 9 deletions src/input/process/availability.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Code for reading process availabilities CSV file
use crate::input::*;
use crate::process::ProcessCapacityMap;
use crate::process::ActivityLimitsMap;
use crate::time_slice::TimeSliceInfo;
use anyhow::{Context, Result};
use serde::Deserialize;
Expand Down Expand Up @@ -44,25 +44,25 @@ enum LimitType {
///
/// # Returns
///
/// A [`HashMap`] with process IDs as the keys and [`ProcessCapacityMap`]s as the values or an
/// A [`HashMap`] with process IDs as the keys and [`ActivityLimitsMap`]s as the values or an
/// error.
pub fn read_process_availabilities(
model_dir: &Path,
process_ids: &HashSet<Rc<str>>,
time_slice_info: &TimeSliceInfo,
) -> Result<HashMap<Rc<str>, ProcessCapacityMap>> {
) -> Result<HashMap<Rc<str>, ActivityLimitsMap>> {
let file_path = model_dir.join(PROCESS_AVAILABILITIES_FILE_NAME);
let process_availabilities_csv = read_csv(&file_path)?;
read_process_availabilities_from_iter(process_availabilities_csv, process_ids, time_slice_info)
.with_context(|| input_err_msg(&file_path))
}

/// Process raw process availabilities input data into [`ProcessCapacityMap`]s
/// Process raw process availabilities input data into [`ActivityLimitsMap`]s
fn read_process_availabilities_from_iter<I>(
iter: I,
process_ids: &HashSet<Rc<str>>,
time_slice_info: &TimeSliceInfo,
) -> Result<HashMap<Rc<str>, ProcessCapacityMap>>
) -> Result<HashMap<Rc<str>, ActivityLimitsMap>>
where
I: Iterator<Item = ProcessAvailabilityRaw>,
{
Expand All @@ -78,9 +78,7 @@ where

let ts_selection = time_slice_info.get_selection(&record.time_slice)?;

let map = map
.entry(process_id)
.or_insert_with(ProcessCapacityMap::new);
let map = map.entry(process_id).or_insert_with(ActivityLimitsMap::new);

for (time_slice, ts_length) in time_slice_info.iter_selection(&ts_selection) {
// Calculate fraction of annual capacity as availability multiplied by time slice length
Expand Down Expand Up @@ -109,7 +107,7 @@ where

/// Check that every capacity map has an entry for every time slice
fn validate_capacity_maps(
map: &HashMap<Rc<str>, ProcessCapacityMap>,
map: &HashMap<Rc<str>, ActivityLimitsMap>,
time_slice_info: &TimeSliceInfo,
) -> Result<()> {
for (process_id, map) in map.iter() {
Expand Down
32 changes: 16 additions & 16 deletions src/input/process/parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct ProcessParameterRaw {
pub variable_operating_cost: f64,
pub lifetime: u32,
pub discount_rate: Option<f64>,
pub cap2act: Option<f64>,
pub capacity_to_activity: Option<f64>,
}
define_process_id_getter! {ProcessParameterRaw}

Expand All @@ -48,7 +48,7 @@ impl ProcessParameterRaw {
variable_operating_cost: self.variable_operating_cost,
lifetime: self.lifetime,
discount_rate: self.discount_rate.unwrap_or(0.0),
cap2act: self.cap2act.unwrap_or(1.0),
capacity_to_activity: self.capacity_to_activity.unwrap_or(1.0),
})
}
}
Expand All @@ -61,7 +61,7 @@ impl ProcessParameterRaw {
/// Returns an error if:
/// - `lifetime` is 0.
/// - `discount_rate` is present and less than 0.0.
/// - `cap2act` is present and less than 0.0.
/// - `capacity_to_activity` is present and less than 0.0.
///
/// # Warnings
///
Expand Down Expand Up @@ -93,7 +93,7 @@ impl ProcessParameterRaw {
}
}

if let Some(c2a) = self.cap2act {
if let Some(c2a) = self.capacity_to_activity {
ensure!(
c2a >= 0.0,
"Error in parameter for process {}: Cap2act must be positive",
Expand Down Expand Up @@ -146,7 +146,7 @@ mod tests {
end_year: Option<u32>,
lifetime: u32,
discount_rate: Option<f64>,
cap2act: Option<f64>,
capacity_to_activity: Option<f64>,
) -> ProcessParameterRaw {
ProcessParameterRaw {
process_id: "id".to_string(),
Expand All @@ -157,14 +157,14 @@ mod tests {
variable_operating_cost: 0.0,
lifetime,
discount_rate,
cap2act,
capacity_to_activity,
}
}

fn create_param(
years: RangeInclusive<u32>,
discount_rate: f64,
cap2act: f64,
capacity_to_activity: f64,
) -> ProcessParameter {
ProcessParameter {
process_id: "id".to_string(),
Expand All @@ -174,7 +174,7 @@ mod tests {
variable_operating_cost: 0.0,
lifetime: 1,
discount_rate,
cap2act,
capacity_to_activity,
}
}

Expand Down Expand Up @@ -203,7 +203,7 @@ mod tests {
create_param(2010..=2020, 0.0, 0.0)
);

// Missing cap2act
// Missing capacity_to_activity
let raw = create_param_raw(Some(2010), Some(2020), 1, Some(1.0), None);
assert_eq!(
raw.into_parameter(&year_range).unwrap(),
Expand Down Expand Up @@ -295,7 +295,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: Some(1.0),
cap2act: Some(1.0),
capacity_to_activity: Some(1.0),
},
ProcessParameterRaw {
process_id: "B".into(),
Expand All @@ -306,7 +306,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: Some(1.0),
cap2act: Some(1.0),
capacity_to_activity: Some(1.0),
},
];

Expand All @@ -321,7 +321,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: 1.0,
cap2act: 1.0,
capacity_to_activity: 1.0,
},
),
(
Expand All @@ -334,7 +334,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: 1.0,
cap2act: 1.0,
capacity_to_activity: 1.0,
},
),
]
Expand All @@ -361,7 +361,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: Some(1.0),
cap2act: Some(1.0),
capacity_to_activity: Some(1.0),
},
ProcessParameterRaw {
process_id: "B".into(),
Expand All @@ -372,7 +372,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: Some(1.0),
cap2act: Some(1.0),
capacity_to_activity: Some(1.0),
},
ProcessParameterRaw {
process_id: "A".into(),
Expand All @@ -383,7 +383,7 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 10,
discount_rate: Some(1.0),
cap2act: Some(1.0),
capacity_to_activity: Some(1.0),
},
];

Expand Down
4 changes: 2 additions & 2 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ mod tests {
variable_operating_cost: 1.0,
lifetime: 5,
discount_rate: 0.9,
cap2act: 3.0,
capacity_to_activity: 3.0,
};
let process = Rc::new(Process {
id: Rc::clone(&process_id),
description: "Description".into(),
capacity_fractions: HashMap::new(),
activity_limits: HashMap::new(),
flows: vec![],
parameter: process_param.clone(),
regions: RegionSelection::All,
Expand Down
Loading