muse2/simulation/investment/appraisal/
constraints.rs1use super::DemandMap;
3use super::optimisation::Variable;
4use crate::asset::AssetRef;
5use crate::commodity::Commodity;
6use crate::time_slice::{TimeSliceID, TimeSliceInfo};
7use crate::units::Flow;
8use highs::RowProblem as Problem;
9use indexmap::IndexMap;
10
11pub fn add_activity_constraints(
19 problem: &mut Problem,
20 asset: &AssetRef,
21 activity_vars: &IndexMap<TimeSliceID, Variable>,
22 time_slice_info: &TimeSliceInfo,
23) {
24 let capacity = asset.capacity().total_capacity();
25 for (ts_selection, limits) in asset.iter_activity_per_capacity_limits() {
26 let limits = (capacity * *limits.start()).value()..=(capacity * *limits.end()).value();
27
28 let terms = ts_selection
30 .iter(time_slice_info)
31 .map(|(time_slice, _)| (*activity_vars.get(time_slice).unwrap(), 1.0))
32 .collect::<Vec<_>>();
33
34 problem.add_row(limits, &terms);
36 }
37}
38
39pub fn add_demand_constraints(
45 problem: &mut Problem,
46 asset: &AssetRef,
47 commodity: &Commodity,
48 time_slice_info: &TimeSliceInfo,
49 demand: &DemandMap,
50 activity_vars: &IndexMap<TimeSliceID, Variable>,
51) {
52 for ts_selection in time_slice_info.iter_selections_at_level(commodity.time_slice_level) {
53 let mut demand_for_ts_selection = Flow(0.0);
54 let mut terms = Vec::new();
55 for (time_slice, _) in ts_selection.iter(time_slice_info) {
56 demand_for_ts_selection += demand[time_slice];
57 let flow_coeff = asset.get_flow(&commodity.id).unwrap().coeff;
58 terms.push((activity_vars[time_slice], flow_coeff.value()));
59 }
60 problem.add_row(0.0..=demand_for_ts_selection.value(), terms);
61 }
62}