From a9e25feaeb636db7c5fb3812fd494fbeb66e082f Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Tue, 28 Nov 2023 10:05:39 +0000 Subject: [PATCH] build based on 34f2b9d --- dev/.documenter-siteinfo.json | 2 +- dev/advanced_concepts/Lossless_DC_power_flow/index.html | 2 +- .../cumulated_flow_restrictions/index.html | 2 +- dev/advanced_concepts/decomposition/index.html | 2 +- dev/advanced_concepts/investment_optimization/index.html | 2 +- dev/advanced_concepts/mga/index.html | 2 +- dev/advanced_concepts/powerflow/index.html | 2 +- .../pressure_driven_gas_transfer/index.html | 2 +- dev/advanced_concepts/ramping/index.html | 2 +- .../representative_days_w_seasonal_storage/index.html | 2 +- dev/advanced_concepts/reserves/index.html | 2 +- dev/advanced_concepts/stochastic_framework/index.html | 2 +- dev/advanced_concepts/temporal_framework/index.html | 2 +- dev/advanced_concepts/unit_commitment/index.html | 2 +- dev/advanced_concepts/user_constraints/index.html | 2 +- dev/concept_reference/Object Classes/index.html | 2 +- dev/concept_reference/Parameter Value Lists/index.html | 2 +- dev/concept_reference/Parameters/index.html | 2 +- dev/concept_reference/Relationship Classes/index.html | 2 +- dev/concept_reference/_example/index.html | 2 +- dev/concept_reference/balance_type/index.html | 2 +- dev/concept_reference/balance_type_list/index.html | 2 +- dev/concept_reference/big_m/index.html | 2 +- dev/concept_reference/block_end/index.html | 2 +- dev/concept_reference/block_start/index.html | 2 +- dev/concept_reference/boolean_value_list/index.html | 2 +- dev/concept_reference/candidate_connections/index.html | 2 +- dev/concept_reference/candidate_storages/index.html | 2 +- dev/concept_reference/candidate_units/index.html | 2 +- dev/concept_reference/commodity/index.html | 2 +- dev/concept_reference/commodity_lodf_tolerance/index.html | 2 +- dev/concept_reference/commodity_physics/index.html | 2 +- dev/concept_reference/commodity_physics_duration/index.html | 2 +- dev/concept_reference/commodity_physics_list/index.html | 2 +- dev/concept_reference/commodity_ptdf_threshold/index.html | 2 +- dev/concept_reference/compression_factor/index.html | 2 +- dev/concept_reference/connection/index.html | 2 +- dev/concept_reference/connection__from_node/index.html | 2 +- .../connection__from_node__unit_constraint/index.html | 2 +- .../connection__investment_stochastic_structure/index.html | 2 +- .../connection__investment_temporal_block/index.html | 2 +- dev/concept_reference/connection__node__node/index.html | 2 +- dev/concept_reference/connection__to_node/index.html | 2 +- .../connection__to_node__unit_constraint/index.html | 2 +- .../connection_availability_factor/index.html | 2 +- dev/concept_reference/connection_capacity/index.html | 2 +- dev/concept_reference/connection_contingency/index.html | 2 +- .../connection_conv_cap_to_flow/index.html | 2 +- .../connection_emergency_capacity/index.html | 2 +- .../connection_flow_coefficient/index.html | 2 +- dev/concept_reference/connection_flow_cost/index.html | 2 +- dev/concept_reference/connection_flow_delay/index.html | 2 +- dev/concept_reference/connection_investment_cost/index.html | 2 +- .../connection_investment_lifetime/index.html | 2 +- .../connection_investment_variable_type/index.html | 2 +- .../connection_investment_variable_type_list/index.html | 2 +- .../connection_linepack_constant/index.html | 2 +- dev/concept_reference/connection_monitored/index.html | 2 +- dev/concept_reference/connection_reactance/index.html | 2 +- dev/concept_reference/connection_reactance_base/index.html | 2 +- dev/concept_reference/connection_resistance/index.html | 2 +- dev/concept_reference/connection_type/index.html | 2 +- dev/concept_reference/connection_type_list/index.html | 2 +- .../connections_invested_avaiable_coefficient/index.html | 2 +- .../connections_invested_big_m_mga/index.html | 2 +- .../connections_invested_coefficient/index.html | 2 +- dev/concept_reference/connections_invested_mga/index.html | 2 +- dev/concept_reference/constraint_sense/index.html | 2 +- dev/concept_reference/constraint_sense_list/index.html | 2 +- dev/concept_reference/curtailment_cost/index.html | 2 +- dev/concept_reference/cyclic_condition/index.html | 2 +- dev/concept_reference/db_lp_solver/index.html | 2 +- dev/concept_reference/db_lp_solver_list/index.html | 2 +- dev/concept_reference/db_lp_solver_options/index.html | 2 +- dev/concept_reference/db_mip_solver/index.html | 2 +- dev/concept_reference/db_mip_solver_list/index.html | 2 +- dev/concept_reference/db_mip_solver_options/index.html | 2 +- dev/concept_reference/demand/index.html | 2 +- dev/concept_reference/demand_coefficient/index.html | 2 +- dev/concept_reference/diff_coeff/index.html | 2 +- dev/concept_reference/downward_reserve/index.html | 2 +- dev/concept_reference/duration_unit/index.html | 2 +- dev/concept_reference/duration_unit_list/index.html | 2 +- .../fix_binary_gas_connection_flow/index.html | 2 +- dev/concept_reference/fix_connection_flow/index.html | 2 +- dev/concept_reference/fix_connection_intact_flow/index.html | 2 +- dev/concept_reference/fix_connections_invested/index.html | 2 +- .../fix_connections_invested_available/index.html | 2 +- dev/concept_reference/fix_node_pressure/index.html | 2 +- dev/concept_reference/fix_node_state/index.html | 2 +- dev/concept_reference/fix_node_voltage_angle/index.html | 2 +- .../fix_nonspin_units_shut_down/index.html | 2 +- .../fix_nonspin_units_started_up/index.html | 2 +- dev/concept_reference/fix_ratio_in_in_unit_flow/index.html | 2 +- dev/concept_reference/fix_ratio_in_out_unit_flow/index.html | 2 +- .../fix_ratio_out_in_connection_flow/index.html | 2 +- dev/concept_reference/fix_ratio_out_in_unit_flow/index.html | 2 +- .../fix_ratio_out_out_unit_flow/index.html | 2 +- dev/concept_reference/fix_storages_invested/index.html | 2 +- .../fix_storages_invested_available/index.html | 2 +- dev/concept_reference/fix_unit_flow/index.html | 2 +- dev/concept_reference/fix_unit_flow_op/index.html | 2 +- dev/concept_reference/fix_units_invested/index.html | 2 +- .../fix_units_invested_available/index.html | 2 +- dev/concept_reference/fix_units_on/index.html | 2 +- .../fix_units_on_coefficient_in_in/index.html | 2 +- .../fix_units_on_coefficient_in_out/index.html | 2 +- .../fix_units_on_coefficient_out_in/index.html | 2 +- .../fix_units_on_coefficient_out_out/index.html | 2 +- dev/concept_reference/fixed_pressure_constant_0/index.html | 2 +- dev/concept_reference/fixed_pressure_constant_1/index.html | 2 +- dev/concept_reference/fom_cost/index.html | 2 +- dev/concept_reference/frac_state_loss/index.html | 2 +- dev/concept_reference/fractional_demand/index.html | 2 +- dev/concept_reference/fuel_cost/index.html | 2 +- dev/concept_reference/graph_view_position/index.html | 2 +- dev/concept_reference/has_binary_gas_flow/index.html | 2 +- dev/concept_reference/has_pressure/index.html | 2 +- dev/concept_reference/has_state/index.html | 2 +- dev/concept_reference/has_voltage_angle/index.html | 2 +- dev/concept_reference/investment_group/index.html | 2 +- dev/concept_reference/is_active/index.html | 2 +- dev/concept_reference/is_non_spinning/index.html | 2 +- dev/concept_reference/is_renewable/index.html | 2 +- dev/concept_reference/is_reserve_node/index.html | 2 +- dev/concept_reference/max_cum_in_unit_flow_bound/index.html | 2 +- dev/concept_reference/max_gap/index.html | 2 +- dev/concept_reference/max_iterations/index.html | 2 +- dev/concept_reference/max_mga_iterations/index.html | 2 +- dev/concept_reference/max_mga_slack/index.html | 2 +- dev/concept_reference/max_node_pressure/index.html | 2 +- dev/concept_reference/max_ratio_in_in_unit_flow/index.html | 2 +- dev/concept_reference/max_ratio_in_out_unit_flow/index.html | 2 +- .../max_ratio_out_in_connection_flow/index.html | 2 +- dev/concept_reference/max_ratio_out_in_unit_flow/index.html | 2 +- .../max_ratio_out_out_unit_flow/index.html | 2 +- .../max_total_cumulated_unit_flow_from_node/index.html | 2 +- .../max_total_cumulated_unit_flow_to_node/index.html | 2 +- .../max_units_on_coefficient_in_in/index.html | 2 +- .../max_units_on_coefficient_in_out/index.html | 2 +- .../max_units_on_coefficient_out_in/index.html | 2 +- .../max_units_on_coefficient_out_out/index.html | 2 +- dev/concept_reference/max_voltage_angle/index.html | 2 +- dev/concept_reference/mga_diff_relative/index.html | 2 +- dev/concept_reference/min_down_time/index.html | 2 +- dev/concept_reference/min_node_pressure/index.html | 2 +- dev/concept_reference/min_ratio_in_in_unit_flow/index.html | 2 +- dev/concept_reference/min_ratio_in_out_unit_flow/index.html | 2 +- .../min_ratio_out_in_connection_flow/index.html | 2 +- dev/concept_reference/min_ratio_out_in_unit_flow/index.html | 2 +- .../min_ratio_out_out_unit_flow/index.html | 2 +- .../min_total_cumulated_unit_flow_from_node/index.html | 2 +- .../min_total_cumulated_unit_flow_to_node/index.html | 2 +- .../min_units_on_coefficient_in_in/index.html | 2 +- .../min_units_on_coefficient_in_out/index.html | 2 +- .../min_units_on_coefficient_out_in/index.html | 2 +- .../min_units_on_coefficient_out_out/index.html | 2 +- dev/concept_reference/min_up_time/index.html | 2 +- dev/concept_reference/min_voltage_angle/index.html | 2 +- dev/concept_reference/minimum_operating_point/index.html | 2 +- .../minimum_reserve_activation_time/index.html | 2 +- dev/concept_reference/model/index.html | 2 +- .../index.html | 2 +- .../model__default_investment_temporal_block/index.html | 2 +- .../model__default_stochastic_structure/index.html | 2 +- .../model__default_temporal_block/index.html | 2 +- dev/concept_reference/model__report/index.html | 2 +- .../model__stochastic_structure/index.html | 2 +- dev/concept_reference/model__temporal_block/index.html | 2 +- dev/concept_reference/model_end/index.html | 2 +- dev/concept_reference/model_start/index.html | 2 +- dev/concept_reference/model_type/index.html | 2 +- dev/concept_reference/model_type_list/index.html | 2 +- .../mp_min_res_gen_to_demand_ratio/index.html | 2 +- .../mp_min_res_gen_to_demand_ratio_slack_penalty/index.html | 2 +- dev/concept_reference/nodal_balance_sense/index.html | 2 +- dev/concept_reference/node/index.html | 2 +- dev/concept_reference/node__commodity/index.html | 2 +- .../node__investment_stochastic_structure/index.html | 2 +- .../node__investment_temporal_block/index.html | 2 +- dev/concept_reference/node__node/index.html | 2 +- dev/concept_reference/node__stochastic_structure/index.html | 2 +- dev/concept_reference/node__temporal_block/index.html | 2 +- dev/concept_reference/node__unit_constraint/index.html | 2 +- dev/concept_reference/node_opf_type/index.html | 2 +- dev/concept_reference/node_opf_type_list/index.html | 2 +- dev/concept_reference/node_slack_penalty/index.html | 2 +- dev/concept_reference/node_state_cap/index.html | 2 +- dev/concept_reference/node_state_coefficient/index.html | 2 +- dev/concept_reference/node_state_min/index.html | 2 +- dev/concept_reference/number_of_units/index.html | 2 +- dev/concept_reference/online_variable_type/index.html | 2 +- dev/concept_reference/operating_cost/index.html | 2 +- dev/concept_reference/operating_points/index.html | 2 +- dev/concept_reference/ordered_unit_flow_op/index.html | 2 +- dev/concept_reference/output/index.html | 2 +- dev/concept_reference/output_db_url/index.html | 2 +- dev/concept_reference/output_resolution/index.html | 2 +- .../overwrite_results_on_rolling/index.html | 2 +- .../index.html | 2 +- dev/concept_reference/ramp_down_limit/index.html | 2 +- dev/concept_reference/ramp_up_limit/index.html | 2 +- dev/concept_reference/report/index.html | 2 +- dev/concept_reference/report__output/index.html | 2 +- .../representative_periods_mapping/index.html | 2 +- dev/concept_reference/reserve_procurement_cost/index.html | 2 +- dev/concept_reference/resolution/index.html | 2 +- dev/concept_reference/right_hand_side/index.html | 2 +- dev/concept_reference/roll_forward/index.html | 2 +- dev/concept_reference/shut_down_cost/index.html | 2 +- dev/concept_reference/shut_down_limit/index.html | 2 +- dev/concept_reference/start_up_cost/index.html | 2 +- dev/concept_reference/start_up_limit/index.html | 2 +- dev/concept_reference/state_coeff/index.html | 2 +- dev/concept_reference/stochastic_scenario/index.html | 2 +- dev/concept_reference/stochastic_scenario_end/index.html | 2 +- dev/concept_reference/stochastic_structure/index.html | 2 +- .../stochastic_structure__stochastic_scenario/index.html | 2 +- dev/concept_reference/storage_investment_cost/index.html | 2 +- .../storage_investment_lifetime/index.html | 2 +- .../storage_investment_variable_type/index.html | 2 +- .../storages_invested_avaiable_coefficient/index.html | 2 +- .../storages_invested_big_m_mga/index.html | 2 +- .../storages_invested_coefficient/index.html | 2 +- dev/concept_reference/storages_invested_mga/index.html | 2 +- dev/concept_reference/tax_in_unit_flow/index.html | 2 +- dev/concept_reference/tax_net_unit_flow/index.html | 2 +- dev/concept_reference/tax_out_unit_flow/index.html | 2 +- dev/concept_reference/temporal_block/index.html | 2 +- dev/concept_reference/the_basics/index.html | 2 +- dev/concept_reference/unit/index.html | 2 +- dev/concept_reference/unit__commodity/index.html | 2 +- dev/concept_reference/unit__from_node/index.html | 2 +- .../unit__from_node__unit_constraint/index.html | 2 +- .../unit__investment_stochastic_structure/index.html | 2 +- .../unit__investment_temporal_block/index.html | 2 +- dev/concept_reference/unit__node__node/index.html | 2 +- dev/concept_reference/unit__to_node/index.html | 2 +- .../unit__to_node__unit_constraint/index.html | 2 +- dev/concept_reference/unit__unit_constraint/index.html | 2 +- dev/concept_reference/unit_availability_factor/index.html | 2 +- dev/concept_reference/unit_capacity/index.html | 2 +- dev/concept_reference/unit_conv_cap_to_flow/index.html | 2 +- dev/concept_reference/unit_flow_coefficient/index.html | 2 +- dev/concept_reference/unit_idle_heat_rate/index.html | 2 +- dev/concept_reference/unit_incremental_heat_rate/index.html | 2 +- dev/concept_reference/unit_investment_cost/index.html | 2 +- dev/concept_reference/unit_investment_lifetime/index.html | 2 +- .../unit_investment_variable_type/index.html | 2 +- .../unit_investment_variable_type_list/index.html | 2 +- .../unit_online_variable_type_list/index.html | 2 +- dev/concept_reference/unit_start_flow/index.html | 2 +- .../units_invested_avaiable_coefficient/index.html | 2 +- dev/concept_reference/units_invested_big_m_mga/index.html | 2 +- dev/concept_reference/units_invested_coefficient/index.html | 2 +- dev/concept_reference/units_invested_mga/index.html | 2 +- .../units_on__stochastic_structure/index.html | 2 +- dev/concept_reference/units_on__temporal_block/index.html | 2 +- dev/concept_reference/units_on_coefficient/index.html | 2 +- dev/concept_reference/units_on_cost/index.html | 2 +- .../units_on_non_anticipativity_time/index.html | 2 +- .../units_started_up_coefficient/index.html | 2 +- dev/concept_reference/upward_reserve/index.html | 2 +- dev/concept_reference/user_constraint/index.html | 2 +- dev/concept_reference/variable_type_list/index.html | 2 +- dev/concept_reference/vom_cost/index.html | 2 +- dev/concept_reference/weight/index.html | 2 +- dev/concept_reference/weight_relative_to_parents/index.html | 2 +- dev/concept_reference/window_weight/index.html | 2 +- dev/concept_reference/write_lodf_file/index.html | 2 +- dev/concept_reference/write_mps_file/index.html | 2 +- dev/concept_reference/write_mps_file_list/index.html | 2 +- dev/concept_reference/write_ptdf_file/index.html | 2 +- dev/getting_started/archetypes/index.html | 2 +- dev/getting_started/creating_your_own_model/index.html | 2 +- dev/getting_started/installation/index.html | 2 +- dev/getting_started/output_data/index.html | 2 +- dev/getting_started/setup_workflow/index.html | 2 +- dev/how_to/change_the_solver/index.html | 2 +- dev/how_to/define_an_efficiency/index.html | 2 +- dev/how_to/print_the_model/index.html | 2 +- dev/implementation_details/documentation/index.html | 2 +- .../how_does_the_model_update_itself/index.html | 2 +- dev/index.html | 2 +- dev/library/index.html | 6 +++--- dev/mathematical_formulation/constraints/index.html | 2 +- .../constraints_automatically_generated/index.html | 4 ++-- dev/mathematical_formulation/objective_function/index.html | 2 +- dev/mathematical_formulation/sets/index.html | 2 +- dev/mathematical_formulation/variables/index.html | 2 +- dev/search_index.js | 2 +- dev/tutorial/case_study_a5/index.html | 2 +- dev/tutorial/reserves/index.html | 2 +- dev/tutorial/simple_system/index.html | 2 +- dev/tutorial/tutorialTwoHydro/index.html | 2 +- dev/tutorial/unit_commitment/index.html | 2 +- dev/tutorial/webinars/index.html | 2 +- 297 files changed, 300 insertions(+), 300 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index b28c5e8cbe..6c50f99259 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2023-11-21T10:12:47","documenter_version":"1.1.2"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2023-11-28T10:05:23","documenter_version":"1.1.2"}} \ No newline at end of file diff --git a/dev/advanced_concepts/Lossless_DC_power_flow/index.html b/dev/advanced_concepts/Lossless_DC_power_flow/index.html index 2d20338a5a..62762dc0bb 100644 --- a/dev/advanced_concepts/Lossless_DC_power_flow/index.html +++ b/dev/advanced_concepts/Lossless_DC_power_flow/index.html @@ -1,2 +1,2 @@ -Lossless nodal DC power flows · SpineOpt.jl

Lossless nodal DC power flows

Currently, there are two different methods to represent lossless DC power flows. In the following the implementation of the nodal model is presented, based of node voltage angles.

Key concepts

In the following, it is described how to set up a connection in order to represent a nodal lossless DC power flow network. Therefore, key object - and relationship classes as well as parameters are introduced.

  1. connection: A connection represents the electricity line being modelled. A physical property of a connection is its connection_reactance, which is defined on the connection object. Furthermore, if the reactance is given in a p.u. different from the standard unit used (e.g. p.u. = 100MVA), the parameter connection_reactance_base can be used to perform this conversion.
  2. node: In a lossless DC power flow model, nodes correspond to buses. To use voltage angles for the representation of a lossless DC model, the has_voltage_angle needs to be true for these nodes (which will trigger the generation of the node_voltage_angle variable). Limits on the voltage angle can be enforced through the max_voltage_angle and min_voltage_angle parameters. The reference node of the system should have a voltage angle equal to zero, assigned through the parameter fix_node_voltage_angle.
  3. connection__to_node and connection__from_node : These relationships need to be introduced between the connection and each node, in order to allow power flows (i.e. connection_flow). Furthermore, a capacity limit on the connection line can be introduced on these relationships through the parameter connection_capacity.
  4. connection__node__node: To ensure energy conservation across the power line, a fixed ratio between incoming and outgoing flows should be given. The fix_ratio_out_in_connection_flow parameter enforces a fixed ratio between outgoing flows (i.e. to_node) and incoming flows (i.e. from_node). This parameter should be defined for both flow direction.

The mathematical formulation of the lossless DC power flow model using voltage angles is fully described here.

+Lossless nodal DC power flows · SpineOpt.jl

Lossless nodal DC power flows

Currently, there are two different methods to represent lossless DC power flows. In the following the implementation of the nodal model is presented, based of node voltage angles.

Key concepts

In the following, it is described how to set up a connection in order to represent a nodal lossless DC power flow network. Therefore, key object - and relationship classes as well as parameters are introduced.

  1. connection: A connection represents the electricity line being modelled. A physical property of a connection is its connection_reactance, which is defined on the connection object. Furthermore, if the reactance is given in a p.u. different from the standard unit used (e.g. p.u. = 100MVA), the parameter connection_reactance_base can be used to perform this conversion.
  2. node: In a lossless DC power flow model, nodes correspond to buses. To use voltage angles for the representation of a lossless DC model, the has_voltage_angle needs to be true for these nodes (which will trigger the generation of the node_voltage_angle variable). Limits on the voltage angle can be enforced through the max_voltage_angle and min_voltage_angle parameters. The reference node of the system should have a voltage angle equal to zero, assigned through the parameter fix_node_voltage_angle.
  3. connection__to_node and connection__from_node : These relationships need to be introduced between the connection and each node, in order to allow power flows (i.e. connection_flow). Furthermore, a capacity limit on the connection line can be introduced on these relationships through the parameter connection_capacity.
  4. connection__node__node: To ensure energy conservation across the power line, a fixed ratio between incoming and outgoing flows should be given. The fix_ratio_out_in_connection_flow parameter enforces a fixed ratio between outgoing flows (i.e. to_node) and incoming flows (i.e. from_node). This parameter should be defined for both flow direction.

The mathematical formulation of the lossless DC power flow model using voltage angles is fully described here.

diff --git a/dev/advanced_concepts/cumulated_flow_restrictions/index.html b/dev/advanced_concepts/cumulated_flow_restrictions/index.html index aa477942f2..efb10f1099 100644 --- a/dev/advanced_concepts/cumulated_flow_restrictions/index.html +++ b/dev/advanced_concepts/cumulated_flow_restrictions/index.html @@ -1,2 +1,2 @@ -Imposing renewable energy targets · SpineOpt.jl

Imposing renewable energy targets

This advanced concept illustrates how renewable targets can be realized in SpineOpt.

Imposing lower limits on renewable production

Imposing a lower bound on the cumulated flow of a unit group by an absolute value

In the current landscape of energy systems modeling, especially in investment models, it is a common idea to implement a lower limit on the amount of electricity that is generated by renewable sources. SpineOpt allows the user to implement such restrictions by means of the min_total_cumulated_unit_flow_to_node parameter. Which will trigger the creation of the constraint_total_cumulated_unit_flow.

To impose a limit on overall renewable generation over the entire optimization horizon, the following objects, relationships, and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. electricity generation from wind), where one

or multiple unit_flows are associated with renewable generation

  1. node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing electricity demand. (Note: To distinguish e.g. between regions there can also be more than one electricity node)
  2. unit__to_node: To associate electricity flows with a unit, the relationship between the unit and the electricity node needs to be imposed, to trigger the generation of a electricity-unit_flow variable.
  3. min_total_cumulated_unit_flow_to_node: This parameter triggers a lower bound on all cumulated flows from a unit (or a group of units), e.g. the group of all renewable generators, to a node (or node group).

Let's take a look at a simple example to see how this works. Suppose that we have a system with only one node, which represents the demand for electricity, and two units: a wind farm, and a conventional gas unit. To connect the wind farm to the electricity node, the unit__to_node relationship has to be defined.

One can then simply define the min_total_cumulated_unit_flow_to_node parameter for the 'windfarm__toelectricity_node' relationship to impose a lower bound on the total generation origination from the wind farm.

Note that the value of this parameter is expected to be given as an absolute value, thus care has to be taken to make sure that the units match with the ones used for the unit_flow variable.

The main source of flexibility in the use of this constraint lies in the possibility to define the parameter for relationships that link 'nodegroups' and/or 'unitgroups'. For example, by grouping multiple units that are considered renewable sources (e.g. PV, and wind), targets can be implemented across multiple renewable sources. Similarly, by defining multiple electricity nodes, generation targets can be spatially disagreggated.

Limiting the cumulated flow of a unit group by a share of the demand

For convenience, we want to be able to define the min_total_cumulated_unit_flow_to_node, when used to set a renewable target, as a share of the demand. At the moment an absolute lower bound needs to be provided by the user, but we want to automate this preprocessing in SpineOpt. (to be implemented)

Imposing an upper limit on carbon emissions

Imposing an upper limit on carbon emissions over the entire optimization horizon

To impose a limit on overall carbon emissions over the entire optimization horizon, the following objects, relationships and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one

or multiple unit_flows are associated with carbon emissions

  1. node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. (Note: To distinguish e.g. between regions there can also be more than one carbon node)
  2. unit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.
  3. unit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)
  4. max_total_cumulated_unit_flow_to_node (and unit__to_node): This parameter triggers a limit on all flows from a unit (or a group of units), e.g. the group of all conventional generators, to a node (or node groups), e.g. considering the atmosphere as a fictive CO2 node, over the entire modelling horizon (e.g. a carbon budget). For example this could be defined on a relationship between a gasplant and a Carbon node, but can also be defined a unit group of all conventional generators and a carbon node. See also: constraint_total_cumulated_unit_flow

Imposing an upper bound on the cumulated flows of a unit group for a specific period of time (advanced method)

If the desired functionality is not to cap emissions over the entire modelling horizon, but rather for specific periods of time (e.g., to impose decreasing carbon caps over time), an alternative method can be used, which will be described in the following.

To illustrate this functionality, we will assume that there is a ficticious cap of 100 for a period of time 2025-2030, and a cap of 50 for the period of time 2030-2035. In this simple example, we will assume that one carbon-emitting unit carbon_unit is present with two outgoing commodity flows, e.g. here electricity and carbon.

Three nodes are required to represent this system: an electricity node, a carbon_cap_1 node (with has_state=true and node_state_cap=100), and a carbon_cap_2 node (with has_state=true and node_state_cap=50).

Further we introduce the unit__node__node relationships between carbon_unit__carbon_cap1__electricity and carbon_unit__carbon_cap2__electricity. On these relationships, we will define the ratio between emissions and electricity production. In this fictious example, we will assume 0.5 units of emissions per unit of electricity.

The fix_ratio_out_out parameter will now be defined as a time varying parameter in the following way (simplified representation of TimeSeries parameter):

fix_ratio_out_out(carbon_unit__carbon_cap1__electricity) = [2025: 0.5; 2030: 0] fix_ratio_out_out(carbon_unit__carbon_cap2__electricity) = [2025: 0; 2030: 0.5]

This way the first emission-cap node carbon_cap1 can only be "filled" during the 2025-2030, while carbon_cap2 can only be "filled" during the second period 2030-2035.

Note that it would also be possible to have, e.g., one node with time-varying node_state_cap. However, in this case, "unused" carbon emissions in the first period of time would be availble for the second period of time.

Imposing a carbon tax

To include carbon pricing in a model, the following objects, relationships and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one

or multiple unit_flows are associated with carbon emissions

  1. node and tax_in_unit_flow: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. To associate a carbon-tax with all incoming unit_flows, the tax_in_unit_flow parameter can be defined on this node (Note: To distinguish e.g. between regions there can also be more than one carbon node)
  2. unit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.
  3. unit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (Gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)
+Imposing renewable energy targets · SpineOpt.jl

Imposing renewable energy targets

This advanced concept illustrates how renewable targets can be realized in SpineOpt.

Imposing lower limits on renewable production

Imposing a lower bound on the cumulated flow of a unit group by an absolute value

In the current landscape of energy systems modeling, especially in investment models, it is a common idea to implement a lower limit on the amount of electricity that is generated by renewable sources. SpineOpt allows the user to implement such restrictions by means of the min_total_cumulated_unit_flow_to_node parameter. Which will trigger the creation of the constraint_total_cumulated_unit_flow.

To impose a limit on overall renewable generation over the entire optimization horizon, the following objects, relationships, and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. electricity generation from wind), where one

or multiple unit_flows are associated with renewable generation

  1. node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing electricity demand. (Note: To distinguish e.g. between regions there can also be more than one electricity node)
  2. unit__to_node: To associate electricity flows with a unit, the relationship between the unit and the electricity node needs to be imposed, to trigger the generation of a electricity-unit_flow variable.
  3. min_total_cumulated_unit_flow_to_node: This parameter triggers a lower bound on all cumulated flows from a unit (or a group of units), e.g. the group of all renewable generators, to a node (or node group).

Let's take a look at a simple example to see how this works. Suppose that we have a system with only one node, which represents the demand for electricity, and two units: a wind farm, and a conventional gas unit. To connect the wind farm to the electricity node, the unit__to_node relationship has to be defined.

One can then simply define the min_total_cumulated_unit_flow_to_node parameter for the 'windfarm__toelectricity_node' relationship to impose a lower bound on the total generation origination from the wind farm.

Note that the value of this parameter is expected to be given as an absolute value, thus care has to be taken to make sure that the units match with the ones used for the unit_flow variable.

The main source of flexibility in the use of this constraint lies in the possibility to define the parameter for relationships that link 'nodegroups' and/or 'unitgroups'. For example, by grouping multiple units that are considered renewable sources (e.g. PV, and wind), targets can be implemented across multiple renewable sources. Similarly, by defining multiple electricity nodes, generation targets can be spatially disagreggated.

Limiting the cumulated flow of a unit group by a share of the demand

For convenience, we want to be able to define the min_total_cumulated_unit_flow_to_node, when used to set a renewable target, as a share of the demand. At the moment an absolute lower bound needs to be provided by the user, but we want to automate this preprocessing in SpineOpt. (to be implemented)

Imposing an upper limit on carbon emissions

Imposing an upper limit on carbon emissions over the entire optimization horizon

To impose a limit on overall carbon emissions over the entire optimization horizon, the following objects, relationships and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one

or multiple unit_flows are associated with carbon emissions

  1. node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. (Note: To distinguish e.g. between regions there can also be more than one carbon node)
  2. unit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.
  3. unit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)
  4. max_total_cumulated_unit_flow_to_node (and unit__to_node): This parameter triggers a limit on all flows from a unit (or a group of units), e.g. the group of all conventional generators, to a node (or node groups), e.g. considering the atmosphere as a fictive CO2 node, over the entire modelling horizon (e.g. a carbon budget). For example this could be defined on a relationship between a gasplant and a Carbon node, but can also be defined a unit group of all conventional generators and a carbon node. See also: constraint_total_cumulated_unit_flow

Imposing an upper bound on the cumulated flows of a unit group for a specific period of time (advanced method)

If the desired functionality is not to cap emissions over the entire modelling horizon, but rather for specific periods of time (e.g., to impose decreasing carbon caps over time), an alternative method can be used, which will be described in the following.

To illustrate this functionality, we will assume that there is a ficticious cap of 100 for a period of time 2025-2030, and a cap of 50 for the period of time 2030-2035. In this simple example, we will assume that one carbon-emitting unit carbon_unit is present with two outgoing commodity flows, e.g. here electricity and carbon.

Three nodes are required to represent this system: an electricity node, a carbon_cap_1 node (with has_state=true and node_state_cap=100), and a carbon_cap_2 node (with has_state=true and node_state_cap=50).

Further we introduce the unit__node__node relationships between carbon_unit__carbon_cap1__electricity and carbon_unit__carbon_cap2__electricity. On these relationships, we will define the ratio between emissions and electricity production. In this fictious example, we will assume 0.5 units of emissions per unit of electricity.

The fix_ratio_out_out parameter will now be defined as a time varying parameter in the following way (simplified representation of TimeSeries parameter):

fix_ratio_out_out(carbon_unit__carbon_cap1__electricity) = [2025: 0.5; 2030: 0] fix_ratio_out_out(carbon_unit__carbon_cap2__electricity) = [2025: 0; 2030: 0.5]

This way the first emission-cap node carbon_cap1 can only be "filled" during the 2025-2030, while carbon_cap2 can only be "filled" during the second period 2030-2035.

Note that it would also be possible to have, e.g., one node with time-varying node_state_cap. However, in this case, "unused" carbon emissions in the first period of time would be availble for the second period of time.

Imposing a carbon tax

To include carbon pricing in a model, the following objects, relationships and parameters are relevant:

  1. unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one

or multiple unit_flows are associated with carbon emissions

  1. node and tax_in_unit_flow: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. To associate a carbon-tax with all incoming unit_flows, the tax_in_unit_flow parameter can be defined on this node (Note: To distinguish e.g. between regions there can also be more than one carbon node)
  2. unit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.
  3. unit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (Gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)
diff --git a/dev/advanced_concepts/decomposition/index.html b/dev/advanced_concepts/decomposition/index.html index db57ad5323..1e28930251 100644 --- a/dev/advanced_concepts/decomposition/index.html +++ b/dev/advanced_concepts/decomposition/index.html @@ -1,2 +1,2 @@ -Decomposition · SpineOpt.jl

Decomposition

Decomposition approaches take advantage of certain problem structures to separate them into multiple related problems which are each more easily solved. Decomposition also allows us to do the inverse, which is to combine independent problems into a single problem, where each can be solved separately but with communication between them (e.g. investments and operations problems)

Decomposition thus allows us to do a number of things

  • Solve larger problems which are otherwise intractable
  • Include more detail in problems which otherwise need to be simplified
  • Combine related problems (e.g. investments/operations) in a more scientific way (rather than ad-hoc).
  • Employ parallel computing methods to solve multiple problems simultaneously.

High-level Decomposition Algorithm

The high-level algorithm is described below. For a more detailed description please see Benders decomposition

  • Model initialisation (preprocessdatastructure, generate temporal structures etc.)
  • For each benders_iteration
    • Solve master problem
    • Process master-problem solution:
      • set units_invested_bi(unit=u) equal to the investment variables solution from the master problem
    • Solve operations problem loop
    • Process operations sub-problem
      • set units_on_mv(unit=u) equal to the marginal value of the units_on bound constraint
    • Test for convergence
    • Update master problem
    • Rewind operations problem
    • Next benders iteration

Duals and reduced costs calculation for decomposition

The marginal values above are computed as the reduced costs of relevant optimisation variables. However, the dual solution to a MIP problem is not well defined. The standard approach to obtaining marginal values from a MIP model is to relax the integer variables, fix them to their last solution value and re-solve the problem as an LP. This is the standard approach in energy system modelling to obtain energy prices. However, although this is the standard approach, it does need to be used with caution. The main hazard associated with inferring duals in this way is that the impact on costs of an investment may be overstated. However, since these duals are used in Benders decomposition to obtain a lower bound on costs (i.e. the maximum potential value from an investment), this is ok and can be "corrected" in the next iteration. And finally, the benders gap will tell us how close our decomposed problem is to the optimal global solution.

Reporting dual values and reduced costs

To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's relaxed problem marginal value will be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.

To report the reduced cost for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of units_on in the final fixed LP to be written to the output db.

Using Decomposition

Assuming one has set up a conventional investments problem as described in Investment Optimization the following additional steps are required to utilise the decomposition framework:

  • Set the model_type parameter for your model to spineopt_benders.
  • Specify max_gap parameter for your model - This determines the master problem convergence criterion for the relative benders gap. A value of 0.05 will represent a relative benders gap of 5%.
  • Specify the max_iterations parameter for your model - This determines the master problem convergence criterion for the number of iterations. A value of 10 could be appropriate but this is highly dependent on the size and nature of the problem.

Once the above is set, all investment decisions in the model are automatically decomposed and optimised in a Benders master problem. This behaviour may change in the future to allow some investment decisions to be optimised in the operations problem and some optimised in the master problem as desired.

+Decomposition · SpineOpt.jl

Decomposition

Decomposition approaches take advantage of certain problem structures to separate them into multiple related problems which are each more easily solved. Decomposition also allows us to do the inverse, which is to combine independent problems into a single problem, where each can be solved separately but with communication between them (e.g. investments and operations problems)

Decomposition thus allows us to do a number of things

  • Solve larger problems which are otherwise intractable
  • Include more detail in problems which otherwise need to be simplified
  • Combine related problems (e.g. investments/operations) in a more scientific way (rather than ad-hoc).
  • Employ parallel computing methods to solve multiple problems simultaneously.

High-level Decomposition Algorithm

The high-level algorithm is described below. For a more detailed description please see Benders decomposition

  • Model initialisation (preprocessdatastructure, generate temporal structures etc.)
  • For each benders_iteration
    • Solve master problem
    • Process master-problem solution:
      • set units_invested_bi(unit=u) equal to the investment variables solution from the master problem
    • Solve operations problem loop
    • Process operations sub-problem
      • set units_on_mv(unit=u) equal to the marginal value of the units_on bound constraint
    • Test for convergence
    • Update master problem
    • Rewind operations problem
    • Next benders iteration

Duals and reduced costs calculation for decomposition

The marginal values above are computed as the reduced costs of relevant optimisation variables. However, the dual solution to a MIP problem is not well defined. The standard approach to obtaining marginal values from a MIP model is to relax the integer variables, fix them to their last solution value and re-solve the problem as an LP. This is the standard approach in energy system modelling to obtain energy prices. However, although this is the standard approach, it does need to be used with caution. The main hazard associated with inferring duals in this way is that the impact on costs of an investment may be overstated. However, since these duals are used in Benders decomposition to obtain a lower bound on costs (i.e. the maximum potential value from an investment), this is ok and can be "corrected" in the next iteration. And finally, the benders gap will tell us how close our decomposed problem is to the optimal global solution.

Reporting dual values and reduced costs

To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's relaxed problem marginal value will be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.

To report the reduced cost for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of units_on in the final fixed LP to be written to the output db.

Using Decomposition

Assuming one has set up a conventional investments problem as described in Investment Optimization the following additional steps are required to utilise the decomposition framework:

  • Set the model_type parameter for your model to spineopt_benders.
  • Specify max_gap parameter for your model - This determines the master problem convergence criterion for the relative benders gap. A value of 0.05 will represent a relative benders gap of 5%.
  • Specify the max_iterations parameter for your model - This determines the master problem convergence criterion for the number of iterations. A value of 10 could be appropriate but this is highly dependent on the size and nature of the problem.

Once the above is set, all investment decisions in the model are automatically decomposed and optimised in a Benders master problem. This behaviour may change in the future to allow some investment decisions to be optimised in the operations problem and some optimised in the master problem as desired.

diff --git a/dev/advanced_concepts/investment_optimization/index.html b/dev/advanced_concepts/investment_optimization/index.html index fd261e3bad..9133ef26e0 100644 --- a/dev/advanced_concepts/investment_optimization/index.html +++ b/dev/advanced_concepts/investment_optimization/index.html @@ -1,2 +1,2 @@ -Investment Optimization · SpineOpt.jl

Investment Optimization

SpineOpt offers numerous ways to optimise investment decisions energy system models and in particular, offers a number of methologogies for capturing increased detail in investment models while containing the impact on run time. The basic principles of investments will be discussed first and this will be followed by more advanced approaches.

Key concepts for investments

Investment Decisions These are the investment decisions that SpineOpt currently supports. At a high level, this means that the activity of the entities in question is controlled by an investment decision variable. The current implementation supports investments in :

  • unit
  • connection
  • Storage - Note: while the above investment decisions correspond to an object class (i.e.) an investment in a unit or a connection, Storages are not an object class in themselves and are rather a property of a node. As such, a storage investment controls whether a particular node has a state variable or not.

Investment Variable Types In all cases the capacity of the unit or connection or the maximum node state of a node is multiplied by the investment variable which may either be continuous, binary or integer. This is determined, for units, by setting the unit_investment_variable_type parameter accordingly. Similary, for connections and node storages the connection_investment_variable_type and storage_investment_variable_type are specified.

Identiying Investment Candidate Units, Connections and Storages The parameter candidate_units represents the number of units of this type that may be invested in. candidate_units determines the upper bound of the investment variable and setting this to a value greater than 0 identifies the unit as an investment candidate unit in the optimisation. If the unit_investment_variable_type is set to :variable_type_integer, the investment variable can be interpreted as the number of discrete units that may be invested in. However, if unit_investment_variable_type is :variable_type_continuous and the unit_capacity is set to unity, the investment decision variable can then be interpreted as the capacity of the unit rather than the number of units with candidate_units being the maximum capacity that can be invested in. Finally, we can invest in discrete blocks of capacity by setting unit_capacity to the size of the investment capacity blocks and have unit_investment_variable_type set to :variable_type_integer with candidate_units representing the maximum number of capacity blocks that may be invested in. The key points here are:

Investment Costs Investment costs are specified by setting the appropriate *_investment\_cost parameter. The investment cost for units are specified by setting the unit_investment_cost parameter. This is currently interpreted as the full cost over the investment period for the unit. See the section below on investment temporal structure for setting the investment period. If the investment period is 1 year, then the corresponding unit_investment_cost is the annualised investment cost. For connections and storages, the investment cost parameters are connection_investment_cost and storage_investment_cost, respectively.

Temporal and Stochastic Structure of Investment Decisions SpineOpt's flexible stochastic and temporal structure extend to investments where individual investment decisions can have their own temporal and stochastic structure independent of other investment decisions and other model variables. A global temporal resolution for all investment decisions can be defined by specifying the relationship model__default_investment_temporal_block. If a specific temporal resolution is required for specific investment decisions, then one can specify the following relationships:

Specifying any of the above relationships will override the corresponding model__default_investment_temporal_block.

Similarly, a global stochastic structure can be defined for all investment decisions by specifying the relationship model__default_investment_stochastic_structure. If a specific stochastic structure is required for specific investment decisions, then one can specifying the following relationships:

Specifying any of the above relationships will override the corresponding model__default_investment_stochastic_structure.

Creating an Investment Candidate Unit Example

If we have model that is not currently set up for investments and we wish to create an investment candidate unit, we can take the following steps.

Model Reference

Variables for investments

Variable NameIndicesDescription
units_invested_availableunit, s, tThe number of invested in units that are available at a given (s, t)
units_investedunit, s, tThe point-in-time investment decision corresponding to the number of units invested in at (s,t)
units_mothballedunit, s, t"Instantaneous" decision variable to mothball a unit
connections_invested_availableconnection, s, tThe number of invested-in connectionss that are available at a given (s, t)
connections_investedconnection, s, tThe point-in-time investment decision corresponding to the number of connectionss invested in at (s,t)
connections_decommissionedconnection, s, t"Instantaneous" decision variable to decommission a connection
storages_invested_availablenode, s, tThe number of invested-in storages that are available at a given (s, t)
storages_investednode, s, tThe point-in-time investment decision corresponding to the number of storages invested in at (s,t)
storages_decommissionednode, s, t"instantaneous" decision variable to decommission a storage

Relationships for investments

Relationship NameRelated Object Class ListDescription
model__default_investment_temporal_blockmodel, temporal_blockDefault temporal resolution for investment decisions effective if unit__investmenttemporalblock is not specified
model__default_investment_stochastic_structuremodel, stochastic_structureDefault stochastic structure for investment decisions effective if unit__investmentstochasticstructure is not specified
unit__investment_temporal_blockunit, temporal_blockSet temporal resolution of investment decisions - overrides model__defaultinvestmenttemporal_block
unit__investment_stochastic_structureunit, stochastic_structureSet stochastic structure for investment decisions - overrides model__defaultinvestmentstochastic_structure

Parameters for investments

Parameter NameObject Class ListDescription
candidate_unitsunitThe number of additional units of this type that can be invested in
unit_investment_costunitThe total overnight investment cost per candidate unit over the model horizon
unit_investment_lifetimeunitThe investment lifetime of the unit - once invested-in, a unit must exist for at least this amount of time
unit_investment_variable_typeunitWhether the units_invested_available variable is continuous, integer or binary
fix_units_investedunitFix the value of units_invested
fix_units_invested_availableunitFix the value of connections_invested_available
candidate_connectionsconnectionThe number of additional connections of this type that can be invested in
connection_investment_costconnectionThe total overnight investment cost per candidate connection over the model horizon
connection_investment_lifetimeconnectionThe investment lifetime of the connection - once invested-in, a connection must exist for at least this amount of time
connection_investment_variable_typeconnectionWhether the connections_invested_available variable is continuous, integer or binary
fix_connections_investedconnectionFix the value of connections_invested
fix_connections_invested_availableconnectionFix the value of connection_invested_available
candidate_storagesnodeThe number of additional storages of this type that can be invested in at node
storage_investment_costnodeThe total overnight investment cost per candidate storage over the model horizon
storage_investment_lifetimenodeThe investment lifetime of the storage - once invested-in, a storage must exist for at least this amount of time
storage_investment_variable_typenodeWhether the storages_invested_available variable is continuous, integer or binary
fix_storages_investednodeFix the value of storages_invested
fix_storages_invested_availablenodeFix the value of storages_invested_available
FilenameRelative PathDescription
constraintunitsinvested_available.jl\constraintsconstrains units_invested_available to be less than candidate_units
constraintunitsinvested_transition.jl\constraintsdefines the relationship between units_invested_available, units_invested and units_mothballed. Analagous to units_on, units_started and units_shutdown
constraintunitlifetime.jl\constraintsonce a unit is invested-in, it must remain in existence for at least unit_investment_lifetime - analagous to min_up_time.
constraintunitsavailable.jl\constraintsEnforces units_available is the sum of number_of_units and units_invested_available
constraintconnectionsinvested_available.jl\constraintsconstrains connections_invested_available to be less than candidate_connections
constraintconnectionsinvested_transition.jl\constraintsdefines the relationship between connections_invested_available, connections_invested and connections_decommissioned. Analagous to units_on, units_started and units_shutdown
constraintconnectionlifetime.jl\constraintsonce a connection is invested-in, it must remain in existence for at least connection_investment_lifetime - analagous to min_up_time.
constraintstoragesinvested_available.jl\constraintsconstrains storages_invested_available to be less than candidate_storages
constraintstoragesinvested_transition.jl\constraintsdefines the relationship between storages_invested_available, storages_invested and storages_decommissioned. Analagous to units_on, units_started and units_shutdown
constraintstoragelifetime.jl\constraintsonce a storage is invested-in, it must remain in existence for at least storage_investment_lifetime - analagous to min_up_time.
+Investment Optimization · SpineOpt.jl

Investment Optimization

SpineOpt offers numerous ways to optimise investment decisions energy system models and in particular, offers a number of methologogies for capturing increased detail in investment models while containing the impact on run time. The basic principles of investments will be discussed first and this will be followed by more advanced approaches.

Key concepts for investments

Investment Decisions These are the investment decisions that SpineOpt currently supports. At a high level, this means that the activity of the entities in question is controlled by an investment decision variable. The current implementation supports investments in :

  • unit
  • connection
  • Storage - Note: while the above investment decisions correspond to an object class (i.e.) an investment in a unit or a connection, Storages are not an object class in themselves and are rather a property of a node. As such, a storage investment controls whether a particular node has a state variable or not.

Investment Variable Types In all cases the capacity of the unit or connection or the maximum node state of a node is multiplied by the investment variable which may either be continuous, binary or integer. This is determined, for units, by setting the unit_investment_variable_type parameter accordingly. Similary, for connections and node storages the connection_investment_variable_type and storage_investment_variable_type are specified.

Identiying Investment Candidate Units, Connections and Storages The parameter candidate_units represents the number of units of this type that may be invested in. candidate_units determines the upper bound of the investment variable and setting this to a value greater than 0 identifies the unit as an investment candidate unit in the optimisation. If the unit_investment_variable_type is set to :variable_type_integer, the investment variable can be interpreted as the number of discrete units that may be invested in. However, if unit_investment_variable_type is :variable_type_continuous and the unit_capacity is set to unity, the investment decision variable can then be interpreted as the capacity of the unit rather than the number of units with candidate_units being the maximum capacity that can be invested in. Finally, we can invest in discrete blocks of capacity by setting unit_capacity to the size of the investment capacity blocks and have unit_investment_variable_type set to :variable_type_integer with candidate_units representing the maximum number of capacity blocks that may be invested in. The key points here are:

Investment Costs Investment costs are specified by setting the appropriate *_investment\_cost parameter. The investment cost for units are specified by setting the unit_investment_cost parameter. This is currently interpreted as the full cost over the investment period for the unit. See the section below on investment temporal structure for setting the investment period. If the investment period is 1 year, then the corresponding unit_investment_cost is the annualised investment cost. For connections and storages, the investment cost parameters are connection_investment_cost and storage_investment_cost, respectively.

Temporal and Stochastic Structure of Investment Decisions SpineOpt's flexible stochastic and temporal structure extend to investments where individual investment decisions can have their own temporal and stochastic structure independent of other investment decisions and other model variables. A global temporal resolution for all investment decisions can be defined by specifying the relationship model__default_investment_temporal_block. If a specific temporal resolution is required for specific investment decisions, then one can specify the following relationships:

Specifying any of the above relationships will override the corresponding model__default_investment_temporal_block.

Similarly, a global stochastic structure can be defined for all investment decisions by specifying the relationship model__default_investment_stochastic_structure. If a specific stochastic structure is required for specific investment decisions, then one can specifying the following relationships:

Specifying any of the above relationships will override the corresponding model__default_investment_stochastic_structure.

Creating an Investment Candidate Unit Example

If we have model that is not currently set up for investments and we wish to create an investment candidate unit, we can take the following steps.

Model Reference

Variables for investments

Variable NameIndicesDescription
units_invested_availableunit, s, tThe number of invested in units that are available at a given (s, t)
units_investedunit, s, tThe point-in-time investment decision corresponding to the number of units invested in at (s,t)
units_mothballedunit, s, t"Instantaneous" decision variable to mothball a unit
connections_invested_availableconnection, s, tThe number of invested-in connectionss that are available at a given (s, t)
connections_investedconnection, s, tThe point-in-time investment decision corresponding to the number of connectionss invested in at (s,t)
connections_decommissionedconnection, s, t"Instantaneous" decision variable to decommission a connection
storages_invested_availablenode, s, tThe number of invested-in storages that are available at a given (s, t)
storages_investednode, s, tThe point-in-time investment decision corresponding to the number of storages invested in at (s,t)
storages_decommissionednode, s, t"instantaneous" decision variable to decommission a storage

Relationships for investments

Relationship NameRelated Object Class ListDescription
model__default_investment_temporal_blockmodel, temporal_blockDefault temporal resolution for investment decisions effective if unit__investmenttemporalblock is not specified
model__default_investment_stochastic_structuremodel, stochastic_structureDefault stochastic structure for investment decisions effective if unit__investmentstochasticstructure is not specified
unit__investment_temporal_blockunit, temporal_blockSet temporal resolution of investment decisions - overrides model__defaultinvestmenttemporal_block
unit__investment_stochastic_structureunit, stochastic_structureSet stochastic structure for investment decisions - overrides model__defaultinvestmentstochastic_structure

Parameters for investments

Parameter NameObject Class ListDescription
candidate_unitsunitThe number of additional units of this type that can be invested in
unit_investment_costunitThe total overnight investment cost per candidate unit over the model horizon
unit_investment_lifetimeunitThe investment lifetime of the unit - once invested-in, a unit must exist for at least this amount of time
unit_investment_variable_typeunitWhether the units_invested_available variable is continuous, integer or binary
fix_units_investedunitFix the value of units_invested
fix_units_invested_availableunitFix the value of connections_invested_available
candidate_connectionsconnectionThe number of additional connections of this type that can be invested in
connection_investment_costconnectionThe total overnight investment cost per candidate connection over the model horizon
connection_investment_lifetimeconnectionThe investment lifetime of the connection - once invested-in, a connection must exist for at least this amount of time
connection_investment_variable_typeconnectionWhether the connections_invested_available variable is continuous, integer or binary
fix_connections_investedconnectionFix the value of connections_invested
fix_connections_invested_availableconnectionFix the value of connection_invested_available
candidate_storagesnodeThe number of additional storages of this type that can be invested in at node
storage_investment_costnodeThe total overnight investment cost per candidate storage over the model horizon
storage_investment_lifetimenodeThe investment lifetime of the storage - once invested-in, a storage must exist for at least this amount of time
storage_investment_variable_typenodeWhether the storages_invested_available variable is continuous, integer or binary
fix_storages_investednodeFix the value of storages_invested
fix_storages_invested_availablenodeFix the value of storages_invested_available
FilenameRelative PathDescription
constraintunitsinvested_available.jl\constraintsconstrains units_invested_available to be less than candidate_units
constraintunitsinvested_transition.jl\constraintsdefines the relationship between units_invested_available, units_invested and units_mothballed. Analagous to units_on, units_started and units_shutdown
constraintunitlifetime.jl\constraintsonce a unit is invested-in, it must remain in existence for at least unit_investment_lifetime - analagous to min_up_time.
constraintunitsavailable.jl\constraintsEnforces units_available is the sum of number_of_units and units_invested_available
constraintconnectionsinvested_available.jl\constraintsconstrains connections_invested_available to be less than candidate_connections
constraintconnectionsinvested_transition.jl\constraintsdefines the relationship between connections_invested_available, connections_invested and connections_decommissioned. Analagous to units_on, units_started and units_shutdown
constraintconnectionlifetime.jl\constraintsonce a connection is invested-in, it must remain in existence for at least connection_investment_lifetime - analagous to min_up_time.
constraintstoragesinvested_available.jl\constraintsconstrains storages_invested_available to be less than candidate_storages
constraintstoragesinvested_transition.jl\constraintsdefines the relationship between storages_invested_available, storages_invested and storages_decommissioned. Analagous to units_on, units_started and units_shutdown
constraintstoragelifetime.jl\constraintsonce a storage is invested-in, it must remain in existence for at least storage_investment_lifetime - analagous to min_up_time.
diff --git a/dev/advanced_concepts/mga/index.html b/dev/advanced_concepts/mga/index.html index 7a1be678a1..b8aebb1257 100644 --- a/dev/advanced_concepts/mga/index.html +++ b/dev/advanced_concepts/mga/index.html @@ -1,2 +1,2 @@ -Modelling to generate alternatives · SpineOpt.jl

Modelling to generate alternatives

Through modelling to generate alternatives (short MGA), near-optimal solutions can be explored under certain conditions. Currently, SpineOpt supports two methods for MGA are available.

Modelling to generate alternative: Maximally different portfolios

The idea is that an orginal problem is solved, and subsequently solved again under the condition that the realization of variables should be maximally different from the previous iteration(s), while keeping the objective function within a certain threshold (defined by max_mga_slack).

In SpineOpt, we choose units_invested_available, connections_invested_available, and storages_invested_available as variables that can be considered for the maximum-difference-problem. The implementation is based on Modelling to generate alternatives: A technique to explore uncertainty in energy-environment-economy models.

How to set up an MGA problem

  • model: In order to explore an MGA model, you will need one model of type spineopt_mga. You should also define the number of iterations (max_mga_iterations, and the maximum allowed deviation from the original objective function (max_mga_slack).
  • at least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.
  • To include the investment decisions in the MGA difference maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.
  • The original MGA formulation is non-convex (maximization problem of an absolute function), but has been linearized through big M method. For this purpose, one should always make sure that units_invested_big_m_mga, connections_invested_big_m_mga, or storages_invested_big_m_mga, respectively, is sufficently large to always be larger the the maximum possible difference per MGA iteration. (Typically the number of candidates could suffice.)
  • As outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.

Modelling to generate alternative: Trade-offs between technology investments

The idea of this approach is to explore near-optimal solutions that maximize/minimize investment in a certain technology (or multiple technologies simultanesously).

How to set up an MGA problem

  • model: In order to explore an MGA model, you will need one model of type spineopt_mga. The maximum allowed deviation from the original objective function should be defined via max_mga_slack. Note that for this method, we don't define an explicit number of iteration via the max_mga_iterations parameter (see also below)
  • at least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.
  • To include the investment decisions in the MGA min/maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.
  • To explore near-optimal solutions using this methodology, the units_invested_mga_weight, connections_invested_mga_weight, and storages_invested_mga_weight parameters are used to define near-optimal solutions. For this purpose, these parameters are defined as Arrays, defining the weight of the technology per iterations. Note that the length of these Arrays should be the same for all technologies, as this will correspond to the number of MGA iterations, i.e., the number of near-optimal solutions. To analyze the trade-off between two technology types, we can, e.g., define units_invested_mga_weight for unit group 1 as [-1,-0.5,0], whereas the use the weights [0,-0.5,-1] for the other technology storage group 1 in question. Note that a negative sign will correspond to a minimization of investments in the corresponding technology type, while positive signs correspond to a maximization of the respective technology. In the given example, we would hence first minimize the investments in unit group 1, then minimize the two technologies simultaneuously, and finally only minimize investments in storage group 2.
  • As outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.
+Modelling to generate alternatives · SpineOpt.jl

Modelling to generate alternatives

Through modelling to generate alternatives (short MGA), near-optimal solutions can be explored under certain conditions. Currently, SpineOpt supports two methods for MGA are available.

Modelling to generate alternative: Maximally different portfolios

The idea is that an orginal problem is solved, and subsequently solved again under the condition that the realization of variables should be maximally different from the previous iteration(s), while keeping the objective function within a certain threshold (defined by max_mga_slack).

In SpineOpt, we choose units_invested_available, connections_invested_available, and storages_invested_available as variables that can be considered for the maximum-difference-problem. The implementation is based on Modelling to generate alternatives: A technique to explore uncertainty in energy-environment-economy models.

How to set up an MGA problem

  • model: In order to explore an MGA model, you will need one model of type spineopt_mga. You should also define the number of iterations (max_mga_iterations, and the maximum allowed deviation from the original objective function (max_mga_slack).
  • at least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.
  • To include the investment decisions in the MGA difference maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.
  • The original MGA formulation is non-convex (maximization problem of an absolute function), but has been linearized through big M method. For this purpose, one should always make sure that units_invested_big_m_mga, connections_invested_big_m_mga, or storages_invested_big_m_mga, respectively, is sufficently large to always be larger the the maximum possible difference per MGA iteration. (Typically the number of candidates could suffice.)
  • As outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.

Modelling to generate alternative: Trade-offs between technology investments

The idea of this approach is to explore near-optimal solutions that maximize/minimize investment in a certain technology (or multiple technologies simultanesously).

How to set up an MGA problem

  • model: In order to explore an MGA model, you will need one model of type spineopt_mga. The maximum allowed deviation from the original objective function should be defined via max_mga_slack. Note that for this method, we don't define an explicit number of iteration via the max_mga_iterations parameter (see also below)
  • at least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.
  • To include the investment decisions in the MGA min/maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.
  • To explore near-optimal solutions using this methodology, the units_invested_mga_weight, connections_invested_mga_weight, and storages_invested_mga_weight parameters are used to define near-optimal solutions. For this purpose, these parameters are defined as Arrays, defining the weight of the technology per iterations. Note that the length of these Arrays should be the same for all technologies, as this will correspond to the number of MGA iterations, i.e., the number of near-optimal solutions. To analyze the trade-off between two technology types, we can, e.g., define units_invested_mga_weight for unit group 1 as [-1,-0.5,0], whereas the use the weights [0,-0.5,-1] for the other technology storage group 1 in question. Note that a negative sign will correspond to a minimization of investments in the corresponding technology type, while positive signs correspond to a maximization of the respective technology. In the given example, we would hence first minimize the investments in unit group 1, then minimize the two technologies simultaneuously, and finally only minimize investments in storage group 2.
  • As outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.
diff --git a/dev/advanced_concepts/powerflow/index.html b/dev/advanced_concepts/powerflow/index.html index 03a0bde978..76730ea5c6 100644 --- a/dev/advanced_concepts/powerflow/index.html +++ b/dev/advanced_concepts/powerflow/index.html @@ -1,2 +1,2 @@ -PTDF-Based Powerflow · SpineOpt.jl

Power transfer distribution factors (PTDF) based DC power flow

There are two main methodologies for directly including DC powerflow in unit commitment/energy system models. One method is to directly include the bus voltage angles as variables in the model. This method is described in Nodal lossless DC Powerflow.

Here we discuss the method of using power transfer distribution factors (PTDF) for DC power flow and line outage distribution factors (lodf) for security constrained unit commitment.

Key concepts

  1. ptdf: The power transfer distribution factors are a property of the network reactances and their derivation may be found here. ptdf(n, c) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of ptdf(n, c)*net_injection(c). The advantage of this method is that it introduces no additional variables into the problem and instead, introduces only one constraint for each connection whose flow we are interested in monitoring.
  2. lodf: Line outage distribution factors are a function of the network ptdfs and their derivation is also found here. lodf(c_contingency, c_monitored) represents the fraction of the pre-contingency flow on connection c_contingency that will flow on c_monitored if c_contingency is disconnected. Therefore, the post contingency flow on connection c_monitored is the pre_contingency flow plus lodf(c_contingency, c_monitored)\*pre_contingency_flow(c_contingency)). Therefore, consideration of N contingencies on M monitored lines introduces N x M constraints into the model. Usually one wishes to contain this number and methods are given below to achieve this.
  3. Defining your network To identify the network for which ptdfs, lodfs and connection_flows will be calculated according to the ptdf method, one does the following:
    • Create node objects for each bus in the model.
    • Create connection objects representing each line of the network: For each connection specify the connection_reactance parameter and the connection_type parameter. Setting connection_type=connection_type_lossless_bidirectional simplifies the amount of data that needs to be specified for an eletrical network. See connection_type for more details
    • Set the connection__to_node and connection__from_node relationships to define the topology of each connection along with the connection_capacity parameter on one or both of these relationships.
    • Set the connection_emergency_capacity parameter to define the post contingency rating if lodf-based N-1 security constraints are to be included
    • Create a commodity object and node__commodity relationships for all the nodes that comprise the electrical network for which PTDFs are to be calculated.
    • Specify the commodity_physics parameter for the commodity to :commodity_physics_ptdf if ptdf-based DC load flow is desired with no N-1 security constraints or to :commodity_physics_lodf if it is desired to include lodf-based N-1 security constraints
    • To identify the reference bus(node) specify the node_opf_type parameter for the appropriate node with the value node_opf_type_reference.
  4. Controlling problem size
    • The lines to be monitored are specified by setting the connection_monitored property for each connection for which a flow constraint is to be generated
    • The contingencies to be considered are specified by setting the connection_contingency property for the appropriate connections. For N contingencies and M monitored lines, N x M constraints will be generated.
    • If the lodf(c_contingency, c_monitored) is very small, it means the outage of c_contingency has a small impact on the flow on c_monitoredand there is little point in including this constraint in the model. This can be achieved by setting the commodity_lodf_tolerance commodity parameter. Contingency / Monotired line combinations with lodfs below this value will be ignored, reducing the size of the model.
    • If ptdf(n, c) is very small, it means an injection at n has a small impact on the flow on c and there is little point in considering it. This can be achieved by setting the commodity_ptdf_threshold commodity parameter. Node / Monotired line combinations with ptdfs below this value will be ignored, reducing the number of coefficients in the model.
    • To more easily identify which connections are worth being monitored or which contingencies are worth being considered, you can add the contingency_is_binding output to any of your reports (via a report__output relationship). This will run the model without the security constraints, and instead write a parameter called contingency_is_binding to the output database for each pair of contingency and monitored connection. The value of the parameter will be a (possibly stochastic) time-series where a value of one will indicate that the corresponding security constraint is binding, and zero otherwise.
+PTDF-Based Powerflow · SpineOpt.jl

Power transfer distribution factors (PTDF) based DC power flow

There are two main methodologies for directly including DC powerflow in unit commitment/energy system models. One method is to directly include the bus voltage angles as variables in the model. This method is described in Nodal lossless DC Powerflow.

Here we discuss the method of using power transfer distribution factors (PTDF) for DC power flow and line outage distribution factors (lodf) for security constrained unit commitment.

Key concepts

  1. ptdf: The power transfer distribution factors are a property of the network reactances and their derivation may be found here. ptdf(n, c) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of ptdf(n, c)*net_injection(c). The advantage of this method is that it introduces no additional variables into the problem and instead, introduces only one constraint for each connection whose flow we are interested in monitoring.
  2. lodf: Line outage distribution factors are a function of the network ptdfs and their derivation is also found here. lodf(c_contingency, c_monitored) represents the fraction of the pre-contingency flow on connection c_contingency that will flow on c_monitored if c_contingency is disconnected. Therefore, the post contingency flow on connection c_monitored is the pre_contingency flow plus lodf(c_contingency, c_monitored)\*pre_contingency_flow(c_contingency)). Therefore, consideration of N contingencies on M monitored lines introduces N x M constraints into the model. Usually one wishes to contain this number and methods are given below to achieve this.
  3. Defining your network To identify the network for which ptdfs, lodfs and connection_flows will be calculated according to the ptdf method, one does the following:
    • Create node objects for each bus in the model.
    • Create connection objects representing each line of the network: For each connection specify the connection_reactance parameter and the connection_type parameter. Setting connection_type=connection_type_lossless_bidirectional simplifies the amount of data that needs to be specified for an eletrical network. See connection_type for more details
    • Set the connection__to_node and connection__from_node relationships to define the topology of each connection along with the connection_capacity parameter on one or both of these relationships.
    • Set the connection_emergency_capacity parameter to define the post contingency rating if lodf-based N-1 security constraints are to be included
    • Create a commodity object and node__commodity relationships for all the nodes that comprise the electrical network for which PTDFs are to be calculated.
    • Specify the commodity_physics parameter for the commodity to :commodity_physics_ptdf if ptdf-based DC load flow is desired with no N-1 security constraints or to :commodity_physics_lodf if it is desired to include lodf-based N-1 security constraints
    • To identify the reference bus(node) specify the node_opf_type parameter for the appropriate node with the value node_opf_type_reference.
  4. Controlling problem size
    • The lines to be monitored are specified by setting the connection_monitored property for each connection for which a flow constraint is to be generated
    • The contingencies to be considered are specified by setting the connection_contingency property for the appropriate connections. For N contingencies and M monitored lines, N x M constraints will be generated.
    • If the lodf(c_contingency, c_monitored) is very small, it means the outage of c_contingency has a small impact on the flow on c_monitoredand there is little point in including this constraint in the model. This can be achieved by setting the commodity_lodf_tolerance commodity parameter. Contingency / Monotired line combinations with lodfs below this value will be ignored, reducing the size of the model.
    • If ptdf(n, c) is very small, it means an injection at n has a small impact on the flow on c and there is little point in considering it. This can be achieved by setting the commodity_ptdf_threshold commodity parameter. Node / Monotired line combinations with ptdfs below this value will be ignored, reducing the number of coefficients in the model.
    • To more easily identify which connections are worth being monitored or which contingencies are worth being considered, you can add the contingency_is_binding output to any of your reports (via a report__output relationship). This will run the model without the security constraints, and instead write a parameter called contingency_is_binding to the output database for each pair of contingency and monitored connection. The value of the parameter will be a (possibly stochastic) time-series where a value of one will indicate that the corresponding security constraint is binding, and zero otherwise.
diff --git a/dev/advanced_concepts/pressure_driven_gas_transfer/index.html b/dev/advanced_concepts/pressure_driven_gas_transfer/index.html index 29160718ab..ed58241186 100644 --- a/dev/advanced_concepts/pressure_driven_gas_transfer/index.html +++ b/dev/advanced_concepts/pressure_driven_gas_transfer/index.html @@ -1,2 +1,2 @@ -Pressure driven gas transfer · SpineOpt.jl

Pressure driven gas transfer

The generic formulation of SpineOpt is based on a trade based model. However, network physics can be different depending on the traded commodity. This chapter specifically addresses the use of pressure driven gas transfer models and enabling linepack flexibility in SpineOpt. To this date, investments in pressure driven pipelines are not yet supported within SpineOpt. The use of multiple feed-in nodes, e.g. to represent multiple commodity flows through a pipeline is not yet supported.

For the representation of pressure driven gas transfer, we use the MILP formulation, as described in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. Here, the non-linearities associated with the Weymouth equation are convexified through an outer approximation of the Weymouth equation through fixed pressure points.

Key concept

Here, we briefly describe the key objects and relationships required to model pressure driven gas transfers in SpineOpt.

  1. connection: A connection represents the gas pipeline being modelled. Usually the direction of flow is not known a priory. To ensure that the flow through the gas pipeline is unidirectional, the parameter has_binary_gas_flow needs to be set to true.
  2. node: Nodes with different characteristics are used for the representation of pressure driven gas transfer.
    • For each connection, there will be two nodes representing the start and end point of the pipeline. Associated with these nodes are the following parameters: the has_pressure parameter, which needs to be set to true, in order to create the variable node_pressure; the max_node_pressure and min_node_pressure to constrain the pressure variable.
    • To leverage linepack flexibility, a third node is introduced representing the linepack storage of the pipeline. To trigger the storage linepack and hence, node_state variables, the has_state parameter needs to be set to true.
  3. connection__to_node and connection__from_node To enable flows through the pipeline and into the linepack storage, each node has to have both these relationships in common with the connection pipeline. These relationships will trigger the generation of connection_flow variables in all possible directions.
  4. connection__node__node This relationship is key to the pressure driven gas transfer, holding the information about the pipeline characteristics and bringing the elements into interaction.
    • The parameter connection_linepack_constant holds the linepack constant and triggers the generation of the line pack storage constraint. Note that the first node should be the linepack storage node, while the second node should be a node_group of both, the start and the end node of the pipeline.
    • The linearization of the Weymouth equation through outer approximation relies on the use of fixed pressure points. For this purpose, the two parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 hold the fixed pressure constants and trigger the generation of the constraint_fix_node_pressure_point. The constraint introduces the relationship between pressure and gas flows. Note, that the pressure constants should be entered in a way, that the first node represents the origin node, the second node the destination node. Each connection should have a connection__node__node to each combination of its start and end nodes (and associated parameters). (See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling)
    • By default, pipelines are considered to be passive. However, a compression station between two pipeline pressure nodes can be represented by defining a compression_factor. The relationship should be defined in such a manner, that the first node represents the sending node, the second node represents the receiving node, which pressure is equal or smaller to the pressure at the sending node times the compression factor.
    • Lastly, to ensure the balance between incoming/outgoing flows and flows into the linepack, the ratio between the flows need to be fixed. The average incoming flows of the node group (of the pressure start and end nodes) have to equal the flows into the linepack storage, and vice versa. Therefore, the fix_ratio_out_in_connection_flow needs to be set to a value (typically 1) for the (pressure group, linepack storage) node pair, and for the (linepack storage, pressure group) node pair.

A gas pipeline and its connected nodes are illustrated below. A complete mathematical formulation can be found here.

Illustration of gas pipeline

+Pressure driven gas transfer · SpineOpt.jl

Pressure driven gas transfer

The generic formulation of SpineOpt is based on a trade based model. However, network physics can be different depending on the traded commodity. This chapter specifically addresses the use of pressure driven gas transfer models and enabling linepack flexibility in SpineOpt. To this date, investments in pressure driven pipelines are not yet supported within SpineOpt. The use of multiple feed-in nodes, e.g. to represent multiple commodity flows through a pipeline is not yet supported.

For the representation of pressure driven gas transfer, we use the MILP formulation, as described in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. Here, the non-linearities associated with the Weymouth equation are convexified through an outer approximation of the Weymouth equation through fixed pressure points.

Key concept

Here, we briefly describe the key objects and relationships required to model pressure driven gas transfers in SpineOpt.

  1. connection: A connection represents the gas pipeline being modelled. Usually the direction of flow is not known a priory. To ensure that the flow through the gas pipeline is unidirectional, the parameter has_binary_gas_flow needs to be set to true.
  2. node: Nodes with different characteristics are used for the representation of pressure driven gas transfer.
    • For each connection, there will be two nodes representing the start and end point of the pipeline. Associated with these nodes are the following parameters: the has_pressure parameter, which needs to be set to true, in order to create the variable node_pressure; the max_node_pressure and min_node_pressure to constrain the pressure variable.
    • To leverage linepack flexibility, a third node is introduced representing the linepack storage of the pipeline. To trigger the storage linepack and hence, node_state variables, the has_state parameter needs to be set to true.
  3. connection__to_node and connection__from_node To enable flows through the pipeline and into the linepack storage, each node has to have both these relationships in common with the connection pipeline. These relationships will trigger the generation of connection_flow variables in all possible directions.
  4. connection__node__node This relationship is key to the pressure driven gas transfer, holding the information about the pipeline characteristics and bringing the elements into interaction.
    • The parameter connection_linepack_constant holds the linepack constant and triggers the generation of the line pack storage constraint. Note that the first node should be the linepack storage node, while the second node should be a node_group of both, the start and the end node of the pipeline.
    • The linearization of the Weymouth equation through outer approximation relies on the use of fixed pressure points. For this purpose, the two parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 hold the fixed pressure constants and trigger the generation of the constraint_fix_node_pressure_point. The constraint introduces the relationship between pressure and gas flows. Note, that the pressure constants should be entered in a way, that the first node represents the origin node, the second node the destination node. Each connection should have a connection__node__node to each combination of its start and end nodes (and associated parameters). (See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling)
    • By default, pipelines are considered to be passive. However, a compression station between two pipeline pressure nodes can be represented by defining a compression_factor. The relationship should be defined in such a manner, that the first node represents the sending node, the second node represents the receiving node, which pressure is equal or smaller to the pressure at the sending node times the compression factor.
    • Lastly, to ensure the balance between incoming/outgoing flows and flows into the linepack, the ratio between the flows need to be fixed. The average incoming flows of the node group (of the pressure start and end nodes) have to equal the flows into the linepack storage, and vice versa. Therefore, the fix_ratio_out_in_connection_flow needs to be set to a value (typically 1) for the (pressure group, linepack storage) node pair, and for the (linepack storage, pressure group) node pair.

A gas pipeline and its connected nodes are illustrated below. A complete mathematical formulation can be found here.

Illustration of gas pipeline

diff --git a/dev/advanced_concepts/ramping/index.html b/dev/advanced_concepts/ramping/index.html index 7e01c41100..01c964fc22 100644 --- a/dev/advanced_concepts/ramping/index.html +++ b/dev/advanced_concepts/ramping/index.html @@ -1,2 +1,2 @@ -Ramping · SpineOpt.jl

Ramping

To enable the representation of units with a high level of technical detail, the ramping capability of units can be constrained in SpineOpt. This means that the user has the freedom to impose restrictions on the change in the output (or input) of units over time, for online (spinning) units, units starting up and units shutting down. In this section, the concept of ramps in SpineOpt will be introduced.

Relevant objects, relationships and parameters

Everything that is related to ramping is defined in parameters of either the unit__to_node or unit__from_node relationship (where the node can be a group). Generally speaking, the ramping constraints will impose restrictions on the change in the unit_flow variable between two consecutive timesteps.

All parameters that limit the ramping abilities of a unit are expressed as a fraction of the unit capacity. This means that a value of 1 indicates the full capacity of a unit.

The discussion here will be conceptual. For the mathematical formulation the reader is referred to the Ramping constraints

Constraining spinning up and down ramps

Constraining start up and shut down ramps

General principle and example use cases

The general principle of the Spine modelling ramping constraints is that all of these parameters can be defined separately for each unit. This allows the user to incorporate different units (which can either represent a single unit or a technology type) with different flexibility characteristics.

It should be noted that it is perfectly possible to omit all of the ramp constraining parameters mentioned above, or to specify only some of them. Anything that is omitted is interpreted as if it shouldn't be constrained. For example, if you only specify start_up_limit and ramp_down_limit, then only the flow increase during start up and the flow decrease during online operation will be constrained (but not any other flow increase or decrease).

Illustrative examples

Step 1: Simple case of unrestricted unit

When none of the ramping parameters mentioned above are specified, the unit is considered to have full ramping flexibility. This means that over any period of time, its flow can be any value between 0 and its capacity, regardless of what the flow of the unit was in previous timesteps, and regardless of the on- or offline status of the unit in previous timesteps (while still respecting, of course, the Unit commitment restrictions that are defined for this unit). This is equivalent to specifying the following:

  • shut_down_limit : 1
  • start_up_limit : 1
  • ramp_up_limit : 1
  • ramp_down_limit : 1

Step 2: Spinning ramp restriction

A unit which is only restricted in spinning ramping can be created by changing the ramp_up/down_limit parameters:

  • ramp_up_limit : 0.2
  • ramp_down_limit : 0.4

This parameter choice implies that the unit flow cannot increase more than $0.2 * 200$ and cannot decrease more than $0.4 * 200$ over a period of time equal to 'one' duration_unit. For example, when the unit is running at an output of $100$ in some timestep $t$, its output for the next 'one' duration_unit must be somewhere in the interval $[20, 140]$ - unless it shuts down completely.

Step 3: Shutdown restrictions

By specifying the parameter shut_down_limit, an additional restriction is imposed on the maximum flow of the unit at the moment it goes offline:

  • shut_down_limit : 0.5
  • minimum_operating_point : 0.3

When the unit goes offline in a given timestep $t$, the output of the unit must be below $0.5 * 200 = 100$ in the timestep right before that $t$ (and of course, above $0.3 * 200 = 60$ - the minimum operating point).

Step 4: Startup restrictions

The start up restrictions are very similar to the shut down restrictions, but of course apply to units that are starting up. THey are activated by specifying start_up_limit:

  • start_up_limit : 0.4
  • minimum_operating_point : 0.2

When the unit goes online in a given timestep $t$, its output will be restricted to the interval $[40, 80]$.

Using node groups to constraint aggregated flow ramps

SpineOpt allows the user to constrain ramping abilities of units that are linked to multiple nodes by defining node groups. When a node group is defined, ramping restrictions can be imposed both on the group level (thus for the unit as a whole) as well as for the individual nodes. For example, let's assume that we have one unit and two nodes in a model. The unit is linked via unit__to_node relationships to each node individually, and on top of that, it is linked to a node group containing both nodes.

If, for example a ramp_up_limit is defined for the node group, the sum of upward ramping of the two nodes will be restricted by this parameter. However, it is still possible to limit the individual flows to the nodes as well. Let's say that our unit is capable of ramping up by 20% of its capacity and down by 40%. We might want to impose tighter restrictions for the flows towards one of the nodes (e.g. because the energy has to be provided in a shorter time than the duration_unit). One can then simply define an additional parameter for that unit__to_node relationship as follows.

  • ramp_up_limit : 0.15

Which now restricts the flow of the unit into that node to 15% of its capacity.

Please note that by default, node groups are balanced in the same way as individual nodes. So if you're using node groups for the sole purpose of constraining flow ramps, you should set the balance type of the group to balance_type_none.

Ramping with reserves

If a unit is set to provide reserves, then it should be able to provide that reserve within one duration_unit. For this reason, reserve provision must be accounted for within ramp constraints. Please see Reserves for details on how to setup a node as a reserve.

Examples

Let's assume that we have one unit and two nodes in a model, one for reserves and one for regular demand. The unit is then linked by the unit__to_node relationships to both the reserves and regular demand node.

Spinning ramp restriction

The unit can be restricted in spinning ramping by defining the ramp_up/down_limit parameters in the unit__to_node relationship for the regular demand node:

  • ramp_up_limit : 0.2
  • ramp_down_limit : 0.4

This parameter choice implies that the unit's flow to the regular demand node cannot increase more than $0.2 * 200 - upward\_reserve\_demand$ or decrease more than $0.4 * 200 - downward\_reserve\_demand$ over one duration_unit. For example, when the unit is running at an output of $100$ and there is an upward reserve demand of $10$, then its output over the next duration_unit must be somewhere in the interval $[20, 130]$.

It can be seen in this example that the demand for reserves is subtracted from the ramping capacity of the unit that is available for regular operation. This stems from the fact that in providing reserve capacity, the unit is expected to be able to provide the demanded reserve within one duration_unit as stated above.

+Ramping · SpineOpt.jl

Ramping

To enable the representation of units with a high level of technical detail, the ramping capability of units can be constrained in SpineOpt. This means that the user has the freedom to impose restrictions on the change in the output (or input) of units over time, for online (spinning) units, units starting up and units shutting down. In this section, the concept of ramps in SpineOpt will be introduced.

Relevant objects, relationships and parameters

Everything that is related to ramping is defined in parameters of either the unit__to_node or unit__from_node relationship (where the node can be a group). Generally speaking, the ramping constraints will impose restrictions on the change in the unit_flow variable between two consecutive timesteps.

All parameters that limit the ramping abilities of a unit are expressed as a fraction of the unit capacity. This means that a value of 1 indicates the full capacity of a unit.

The discussion here will be conceptual. For the mathematical formulation the reader is referred to the Ramping constraints

Constraining spinning up and down ramps

Constraining start up and shut down ramps

General principle and example use cases

The general principle of the Spine modelling ramping constraints is that all of these parameters can be defined separately for each unit. This allows the user to incorporate different units (which can either represent a single unit or a technology type) with different flexibility characteristics.

It should be noted that it is perfectly possible to omit all of the ramp constraining parameters mentioned above, or to specify only some of them. Anything that is omitted is interpreted as if it shouldn't be constrained. For example, if you only specify start_up_limit and ramp_down_limit, then only the flow increase during start up and the flow decrease during online operation will be constrained (but not any other flow increase or decrease).

Illustrative examples

Step 1: Simple case of unrestricted unit

When none of the ramping parameters mentioned above are specified, the unit is considered to have full ramping flexibility. This means that over any period of time, its flow can be any value between 0 and its capacity, regardless of what the flow of the unit was in previous timesteps, and regardless of the on- or offline status of the unit in previous timesteps (while still respecting, of course, the Unit commitment restrictions that are defined for this unit). This is equivalent to specifying the following:

  • shut_down_limit : 1
  • start_up_limit : 1
  • ramp_up_limit : 1
  • ramp_down_limit : 1

Step 2: Spinning ramp restriction

A unit which is only restricted in spinning ramping can be created by changing the ramp_up/down_limit parameters:

  • ramp_up_limit : 0.2
  • ramp_down_limit : 0.4

This parameter choice implies that the unit flow cannot increase more than $0.2 * 200$ and cannot decrease more than $0.4 * 200$ over a period of time equal to 'one' duration_unit. For example, when the unit is running at an output of $100$ in some timestep $t$, its output for the next 'one' duration_unit must be somewhere in the interval $[20, 140]$ - unless it shuts down completely.

Step 3: Shutdown restrictions

By specifying the parameter shut_down_limit, an additional restriction is imposed on the maximum flow of the unit at the moment it goes offline:

  • shut_down_limit : 0.5
  • minimum_operating_point : 0.3

When the unit goes offline in a given timestep $t$, the output of the unit must be below $0.5 * 200 = 100$ in the timestep right before that $t$ (and of course, above $0.3 * 200 = 60$ - the minimum operating point).

Step 4: Startup restrictions

The start up restrictions are very similar to the shut down restrictions, but of course apply to units that are starting up. THey are activated by specifying start_up_limit:

  • start_up_limit : 0.4
  • minimum_operating_point : 0.2

When the unit goes online in a given timestep $t$, its output will be restricted to the interval $[40, 80]$.

Using node groups to constraint aggregated flow ramps

SpineOpt allows the user to constrain ramping abilities of units that are linked to multiple nodes by defining node groups. When a node group is defined, ramping restrictions can be imposed both on the group level (thus for the unit as a whole) as well as for the individual nodes. For example, let's assume that we have one unit and two nodes in a model. The unit is linked via unit__to_node relationships to each node individually, and on top of that, it is linked to a node group containing both nodes.

If, for example a ramp_up_limit is defined for the node group, the sum of upward ramping of the two nodes will be restricted by this parameter. However, it is still possible to limit the individual flows to the nodes as well. Let's say that our unit is capable of ramping up by 20% of its capacity and down by 40%. We might want to impose tighter restrictions for the flows towards one of the nodes (e.g. because the energy has to be provided in a shorter time than the duration_unit). One can then simply define an additional parameter for that unit__to_node relationship as follows.

  • ramp_up_limit : 0.15

Which now restricts the flow of the unit into that node to 15% of its capacity.

Please note that by default, node groups are balanced in the same way as individual nodes. So if you're using node groups for the sole purpose of constraining flow ramps, you should set the balance type of the group to balance_type_none.

Ramping with reserves

If a unit is set to provide reserves, then it should be able to provide that reserve within one duration_unit. For this reason, reserve provision must be accounted for within ramp constraints. Please see Reserves for details on how to setup a node as a reserve.

Examples

Let's assume that we have one unit and two nodes in a model, one for reserves and one for regular demand. The unit is then linked by the unit__to_node relationships to both the reserves and regular demand node.

Spinning ramp restriction

The unit can be restricted in spinning ramping by defining the ramp_up/down_limit parameters in the unit__to_node relationship for the regular demand node:

  • ramp_up_limit : 0.2
  • ramp_down_limit : 0.4

This parameter choice implies that the unit's flow to the regular demand node cannot increase more than $0.2 * 200 - upward\_reserve\_demand$ or decrease more than $0.4 * 200 - downward\_reserve\_demand$ over one duration_unit. For example, when the unit is running at an output of $100$ and there is an upward reserve demand of $10$, then its output over the next duration_unit must be somewhere in the interval $[20, 130]$.

It can be seen in this example that the demand for reserves is subtracted from the ramping capacity of the unit that is available for regular operation. This stems from the fact that in providing reserve capacity, the unit is expected to be able to provide the demanded reserve within one duration_unit as stated above.

diff --git a/dev/advanced_concepts/representative_days_w_seasonal_storage/index.html b/dev/advanced_concepts/representative_days_w_seasonal_storage/index.html index e4879dd332..51968e2ee6 100644 --- a/dev/advanced_concepts/representative_days_w_seasonal_storage/index.html +++ b/dev/advanced_concepts/representative_days_w_seasonal_storage/index.html @@ -1,2 +1,2 @@ -Representative days with seasonal storages · SpineOpt.jl

Representative days with seasonal storages

In order to reduce the problem size, representative periods are often used in optimization models. However, this often limits the ability to properly account for seasonal storages.

In SpineOpt, we provide functionality to use representative days with seasonal storages.

General idea

The general idea is to mimick the seasonal effects throughout a non-representative period, e.g. a year of optimization, by introducing a specific sequence of the representative periods.

Usage of representative days and seasonal storages for investment problems

Assuming you already have an investment model with a certain temporal structure that works, you can turn it into a representative periods model with the following steps.

  1. Identify the nodes and units whose flows and statuses you want to model using representative periods, as well as their associated temporal_blocks.
  2. Select the representative periods. For example if you are modelling a year, you can select a few weeks (one in summer, one in winder, and one in mid season).
  3. For each representative period, create a temporal_block specifying block_start, block_end and resolution.
  4. Associate these temporal_blocks to the nodes and units identified in step 1, via node__temporal_block and units_on__temporal_block relationships.
  5. Finally, for each original temporal_block associated to these nodes and units (those identified in step 1), specify the value of the representative_periods_mapping parameter. This should be a map where each entry associates a date-time to the name of one of the representative period temporal_blocks created in step 3. More specifically, an entry with t as the key and b as the value means that time slices from the original block starting at t, are 'represented' by time slices from the b block. In other words, time slices between t and t plus the duration of b are represented by b.

In SpineOpt, this will be interpreted in the following way:

  • All operational variables, with the exception of the node_state variable, will be created only for the representative periods. For the non-representative periods, SpineOpt will use the variable of the corresponding representative period according to the value of the representative_periods_mapping parameter.
  • The node_state variable and the investment variables will be created for all periods, representative and non-representative.

The SpinePeriods.jl package provides an alternative, perhaps simpler way to setup a representative periods model based on the automatic selection and ordering of periods.

+Representative days with seasonal storages · SpineOpt.jl

Representative days with seasonal storages

In order to reduce the problem size, representative periods are often used in optimization models. However, this often limits the ability to properly account for seasonal storages.

In SpineOpt, we provide functionality to use representative days with seasonal storages.

General idea

The general idea is to mimick the seasonal effects throughout a non-representative period, e.g. a year of optimization, by introducing a specific sequence of the representative periods.

Usage of representative days and seasonal storages for investment problems

Assuming you already have an investment model with a certain temporal structure that works, you can turn it into a representative periods model with the following steps.

  1. Identify the nodes and units whose flows and statuses you want to model using representative periods, as well as their associated temporal_blocks.
  2. Select the representative periods. For example if you are modelling a year, you can select a few weeks (one in summer, one in winder, and one in mid season).
  3. For each representative period, create a temporal_block specifying block_start, block_end and resolution.
  4. Associate these temporal_blocks to the nodes and units identified in step 1, via node__temporal_block and units_on__temporal_block relationships.
  5. Finally, for each original temporal_block associated to these nodes and units (those identified in step 1), specify the value of the representative_periods_mapping parameter. This should be a map where each entry associates a date-time to the name of one of the representative period temporal_blocks created in step 3. More specifically, an entry with t as the key and b as the value means that time slices from the original block starting at t, are 'represented' by time slices from the b block. In other words, time slices between t and t plus the duration of b are represented by b.

In SpineOpt, this will be interpreted in the following way:

  • All operational variables, with the exception of the node_state variable, will be created only for the representative periods. For the non-representative periods, SpineOpt will use the variable of the corresponding representative period according to the value of the representative_periods_mapping parameter.
  • The node_state variable and the investment variables will be created for all periods, representative and non-representative.

The SpinePeriods.jl package provides an alternative, perhaps simpler way to setup a representative periods model based on the automatic selection and ordering of periods.

diff --git a/dev/advanced_concepts/reserves/index.html b/dev/advanced_concepts/reserves/index.html index 43ccf2b118..23f1983ec7 100644 --- a/dev/advanced_concepts/reserves/index.html +++ b/dev/advanced_concepts/reserves/index.html @@ -1,2 +1,2 @@ -Reserves · SpineOpt.jl

Reserves

To include a requirement of reserve provision in a model, SpineOpt offers the possibility of creating reserve nodes. Of course reserve provision is different from regular operation, because the reserved capacity does not actually get activated. In this section we will take a look at the things that are particular for a reserve node.

Defining a reserve node

To define a reserve node, the following parameters have to be defined for the relevant node:

  • is_reserve_node : this boolean parameter indicates that this node is a reserve node.
  • upward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns upward reserves.
  • downward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns downward reserves.
  • reserve_procurement_cost: (optional) this parameter indicates the procurement cost of a unit for a certain reserve product and can be define on a unit__to_node or unit__from_node relationship.
+Reserves · SpineOpt.jl

Reserves

To include a requirement of reserve provision in a model, SpineOpt offers the possibility of creating reserve nodes. Of course reserve provision is different from regular operation, because the reserved capacity does not actually get activated. In this section we will take a look at the things that are particular for a reserve node.

Defining a reserve node

To define a reserve node, the following parameters have to be defined for the relevant node:

  • is_reserve_node : this boolean parameter indicates that this node is a reserve node.
  • upward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns upward reserves.
  • downward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns downward reserves.
  • reserve_procurement_cost: (optional) this parameter indicates the procurement cost of a unit for a certain reserve product and can be define on a unit__to_node or unit__from_node relationship.
diff --git a/dev/advanced_concepts/stochastic_framework/index.html b/dev/advanced_concepts/stochastic_framework/index.html index 231930e7a2..3f9694a468 100644 --- a/dev/advanced_concepts/stochastic_framework/index.html +++ b/dev/advanced_concepts/stochastic_framework/index.html @@ -6,4 +6,4 @@ # If not a root `stochastic_scenario` -weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

Finally, with all the pieces in place, we'll need to connect the defined stochastic_structure objects to the desired objects in the Systemic object classes using the Structural relationship classes like node__stochastic_structure etc. Here, we essentially tell which parts of the modelled system use which stochastic_structure. Since creating each of these relationships individually can be a bit of a pain, there are a few Meta relationship classes like the model__default_stochastic_structure, that can be used to set model-wide defaults that are used if specific relationships are missing.

Example of deterministic stochastics

Here, we'll demonstrate step-by-step how to create the simplest possible stochastic frame: the fully deterministic one. See the Deterministic Stochastic Structure archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Create a stochastic_scenario called e.g. realization and a stochastic_structure called e.g. deterministic.
  2. We can skip the parent_stochastic_scenario__child_stochastic_scenario relationship, since there isn't a stochastic DAG in this example, and the default behaviour of each stochastic_scenario being independent works for our purposes (only one stochastic_scenario anyhow).
  3. Create the stochastic_structure__stochastic_scenario relationship for (deterministic, realization), and set its weight_relative_to_parents parameter to 1. We don't need to define the stochastic_scenario_end parameter, as we want the realization to go on indefinitely.
  4. Relate the deterministic stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Example of branching stochastics

Here, we'll demonstrate step-by-step how to create a simple branching stochastic tree, where one scenario branches into three at a specific point in time. See the Branching Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Create four stochastic_scenario objects called e.g. realization, forecast1, forecast2, and forecast3, and a stochastic_structure called e.g. branching.
  2. Define the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (realization, forecast1), (realization, forecast2), and (realization, forecast3).
  3. Create the stochastic_structure__stochastic_scenario relationship for (branching, realization), (branching, forecast1), (branching, forecast2), and (branching, forecast3).
  4. Set the weight_relative_to_parents parameter to 1 and the stochastic_scenario_end parameter e.g. to 6h for the stochastic_structure__stochastic_scenario relationship (branching, realization). Now, the realization stochastic_scenario will end after 6 hours of time steps, and its children (forecast1, forecast2, and forecast3) will become active.
  5. Set the weight_relative_to_parents Parameters for the (branching, forecast1), (branching, forecast2), and (branching, forecast3) stochastic_structure__stochastic_scenario relationships to whatever you desire, e.g. 0.33 for equal probabilities across all forecasts.
  6. Relate the branching stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Example of converging stochastics

Here, we'll demonstrate step-by-step how to create a simple stochastic DAG, where both branching and converging occurs. This example relies on the previous Example of branching stochastics, but adds another stochastic_scenario at the end, which is a child of the forecast1, forecast2, and forecast3 scenarios. See the Converging Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Follow the steps 1-5 in the previous Example of branching stochastics, except call the stochastic_structure something different, e.g. converging.
  2. Create a new stochastic_scenario called e.g. converged_forecast.
  3. Alter the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (forecast1, converged_forecast), (forecast2, converged_forecast), and (forecast3, converged_forecast). Now all three forecasts will converge into a single converged_forecast.
  4. Add the stochastic_structure__stochastic_scenario relationship for (converging, converged_forecast), and set its weight_relative_to_parents parameter to 1. Now, all the probability mass in forecast1, forecast2, and forecast3 will be summed up back to the converged_forecast.
  5. Set the stochastic_scenario_end Parameters of the stochastic_structure__stochastic_scenario relationships (converging, forecast1), (converging, forecast2), and (converging, forecast3) to e.g. 1D, so that all three scenarios end at the same time and the converged_forecast becomes active.
  6. Relate the converging stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Working with stochastic updating data

Now that we've discussed how to set up stochastics for SpineOpt, let's focus on stochastic data. The most complex form of input data SpineOpt can currently handle is both stochastic and updating, meaning that the values the parameter takes can depend on both the stochastic_scenario, and the analysis time (first time step) of each solve. However, just stochastic or just updating cases are supported as well, using the same input data format.

In SpineOpt, stochastic data uses the Map data type from SpineInterface.jl. Essentially, Maps are general indexed data containers, which SpineOpt tries to interpret as stochastic data. Every time SpineOpt calls a parameter, it passes the stochastic_scenario and analysis time as keyword arguments to the parameter, but depending on the parameter type, it doesn't necessarily do anything with that information. For Map type parameters, those keyword arguments are used for navigating the indices of the Map to try and find the corresponding value. If the Map doesn't include the stochastic_scenario index it's looking for, it assumes there's no stochastic information in the Map and carries on to search for analysis time indices. This logic is useful for defining both stochastic and updating data, as well as either case by itself, as shown in the following examples.

Example of stochastic data

By stochastic data, we mean parameter values that depend only on the stochastic_scenario. In such a case, the input data must be formatted as a Map with the following structure

stochastic_scenariovalue
scenario1value1
scenario2value2

where stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 in scenario1, and value2 in scenario2. Note that since there's no analysis time index in this example, the values are used regardless of the analysis time.

Example of updating data

By updating data, we mean parameter values that depend only on the analysis time. In such a case, the input data must be formatted as a Map with the following structure

analysis timevalue
2000-01-01T00:00:00value1
2000-01-01T12:00:00value2

where the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00, and value2 if the first time step of the simulation is after 2000-01-01T12:00:00. Note that since there's no stochastic_scenario index in this example, the values are used regardless of the stochastic_scenario.

Example of stochastic updating data

By stochastic updating data, we mean parameter values that depend on both the stochastic_scenario and the analysis time. In such a case, the input data must be formatted as a Map with the following structure

stochastic_scenarioanalysis timevalue
scenario12000-01-01T00:00:00value1
scenario12000-01-01T12:00:00value2
scenario22000-01-01T00:00:00value3
scenario22000-01-01T12:00:00value4

where the stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects, and the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00 and the parameter is called in scenario1, and value3 in scenario2. If the first time step of the current simulation is after 2000-01-01T12:00:00, the parameter will take value2 in scenario1, and value4 in scenario2.

Constraint generation with stochastic path indexing

Every time a constraint might refer to variables either on different time steps or on different stochastic scenarios (meaning different nodes or units), the constraint needs to use stochastic path indexing in order to be correctly generated for arbitrary stochastic DAGs. In practise, this means following the procedure outlined below:

  1. Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. This is done along with generating the stochastic structure, so no real impact on constraint generation.
  2. Find all the stochastic scenarios that are active on all the stochastic structures and time slices included in the constraint.
  3. Find all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.
  4. Generate constraints over each unique stochastic path found in step 3.

Steps 2 and 3 are the crucial ones, and are currently handled by separate constraint_<constraint_name>_indices functions. Essentially, these functions go through all the variables on all the time steps included in the constraint, collect the set of active stochastic_scenarios on each time step, and then determine the unique active stochastic paths on each time step. The functions pre-form the index set over which the constraint is then generated in the add_constraint_<constraint_name> functions.

+weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

Finally, with all the pieces in place, we'll need to connect the defined stochastic_structure objects to the desired objects in the Systemic object classes using the Structural relationship classes like node__stochastic_structure etc. Here, we essentially tell which parts of the modelled system use which stochastic_structure. Since creating each of these relationships individually can be a bit of a pain, there are a few Meta relationship classes like the model__default_stochastic_structure, that can be used to set model-wide defaults that are used if specific relationships are missing.

Example of deterministic stochastics

Here, we'll demonstrate step-by-step how to create the simplest possible stochastic frame: the fully deterministic one. See the Deterministic Stochastic Structure archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Create a stochastic_scenario called e.g. realization and a stochastic_structure called e.g. deterministic.
  2. We can skip the parent_stochastic_scenario__child_stochastic_scenario relationship, since there isn't a stochastic DAG in this example, and the default behaviour of each stochastic_scenario being independent works for our purposes (only one stochastic_scenario anyhow).
  3. Create the stochastic_structure__stochastic_scenario relationship for (deterministic, realization), and set its weight_relative_to_parents parameter to 1. We don't need to define the stochastic_scenario_end parameter, as we want the realization to go on indefinitely.
  4. Relate the deterministic stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Example of branching stochastics

Here, we'll demonstrate step-by-step how to create a simple branching stochastic tree, where one scenario branches into three at a specific point in time. See the Branching Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Create four stochastic_scenario objects called e.g. realization, forecast1, forecast2, and forecast3, and a stochastic_structure called e.g. branching.
  2. Define the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (realization, forecast1), (realization, forecast2), and (realization, forecast3).
  3. Create the stochastic_structure__stochastic_scenario relationship for (branching, realization), (branching, forecast1), (branching, forecast2), and (branching, forecast3).
  4. Set the weight_relative_to_parents parameter to 1 and the stochastic_scenario_end parameter e.g. to 6h for the stochastic_structure__stochastic_scenario relationship (branching, realization). Now, the realization stochastic_scenario will end after 6 hours of time steps, and its children (forecast1, forecast2, and forecast3) will become active.
  5. Set the weight_relative_to_parents Parameters for the (branching, forecast1), (branching, forecast2), and (branching, forecast3) stochastic_structure__stochastic_scenario relationships to whatever you desire, e.g. 0.33 for equal probabilities across all forecasts.
  6. Relate the branching stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Example of converging stochastics

Here, we'll demonstrate step-by-step how to create a simple stochastic DAG, where both branching and converging occurs. This example relies on the previous Example of branching stochastics, but adds another stochastic_scenario at the end, which is a child of the forecast1, forecast2, and forecast3 scenarios. See the Converging Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.

  1. Follow the steps 1-5 in the previous Example of branching stochastics, except call the stochastic_structure something different, e.g. converging.
  2. Create a new stochastic_scenario called e.g. converged_forecast.
  3. Alter the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (forecast1, converged_forecast), (forecast2, converged_forecast), and (forecast3, converged_forecast). Now all three forecasts will converge into a single converged_forecast.
  4. Add the stochastic_structure__stochastic_scenario relationship for (converging, converged_forecast), and set its weight_relative_to_parents parameter to 1. Now, all the probability mass in forecast1, forecast2, and forecast3 will be summed up back to the converged_forecast.
  5. Set the stochastic_scenario_end Parameters of the stochastic_structure__stochastic_scenario relationships (converging, forecast1), (converging, forecast2), and (converging, forecast3) to e.g. 1D, so that all three scenarios end at the same time and the converged_forecast becomes active.
  6. Relate the converging stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.

Working with stochastic updating data

Now that we've discussed how to set up stochastics for SpineOpt, let's focus on stochastic data. The most complex form of input data SpineOpt can currently handle is both stochastic and updating, meaning that the values the parameter takes can depend on both the stochastic_scenario, and the analysis time (first time step) of each solve. However, just stochastic or just updating cases are supported as well, using the same input data format.

In SpineOpt, stochastic data uses the Map data type from SpineInterface.jl. Essentially, Maps are general indexed data containers, which SpineOpt tries to interpret as stochastic data. Every time SpineOpt calls a parameter, it passes the stochastic_scenario and analysis time as keyword arguments to the parameter, but depending on the parameter type, it doesn't necessarily do anything with that information. For Map type parameters, those keyword arguments are used for navigating the indices of the Map to try and find the corresponding value. If the Map doesn't include the stochastic_scenario index it's looking for, it assumes there's no stochastic information in the Map and carries on to search for analysis time indices. This logic is useful for defining both stochastic and updating data, as well as either case by itself, as shown in the following examples.

Example of stochastic data

By stochastic data, we mean parameter values that depend only on the stochastic_scenario. In such a case, the input data must be formatted as a Map with the following structure

stochastic_scenariovalue
scenario1value1
scenario2value2

where stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 in scenario1, and value2 in scenario2. Note that since there's no analysis time index in this example, the values are used regardless of the analysis time.

Example of updating data

By updating data, we mean parameter values that depend only on the analysis time. In such a case, the input data must be formatted as a Map with the following structure

analysis timevalue
2000-01-01T00:00:00value1
2000-01-01T12:00:00value2

where the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00, and value2 if the first time step of the simulation is after 2000-01-01T12:00:00. Note that since there's no stochastic_scenario index in this example, the values are used regardless of the stochastic_scenario.

Example of stochastic updating data

By stochastic updating data, we mean parameter values that depend on both the stochastic_scenario and the analysis time. In such a case, the input data must be formatted as a Map with the following structure

stochastic_scenarioanalysis timevalue
scenario12000-01-01T00:00:00value1
scenario12000-01-01T12:00:00value2
scenario22000-01-01T00:00:00value3
scenario22000-01-01T12:00:00value4

where the stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects, and the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00 and the parameter is called in scenario1, and value3 in scenario2. If the first time step of the current simulation is after 2000-01-01T12:00:00, the parameter will take value2 in scenario1, and value4 in scenario2.

Constraint generation with stochastic path indexing

Every time a constraint might refer to variables either on different time steps or on different stochastic scenarios (meaning different nodes or units), the constraint needs to use stochastic path indexing in order to be correctly generated for arbitrary stochastic DAGs. In practise, this means following the procedure outlined below:

  1. Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. This is done along with generating the stochastic structure, so no real impact on constraint generation.
  2. Find all the stochastic scenarios that are active on all the stochastic structures and time slices included in the constraint.
  3. Find all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.
  4. Generate constraints over each unique stochastic path found in step 3.

Steps 2 and 3 are the crucial ones, and are currently handled by separate constraint_<constraint_name>_indices functions. Essentially, these functions go through all the variables on all the time steps included in the constraint, collect the set of active stochastic_scenarios on each time step, and then determine the unique active stochastic paths on each time step. The functions pre-form the index set over which the constraint is then generated in the add_constraint_<constraint_name> functions.

diff --git a/dev/advanced_concepts/temporal_framework/index.html b/dev/advanced_concepts/temporal_framework/index.html index 3d214fb75e..5c768c68b3 100644 --- a/dev/advanced_concepts/temporal_framework/index.html +++ b/dev/advanced_concepts/temporal_framework/index.html @@ -1,2 +1,2 @@ -Temporal Framework · SpineOpt.jl

Temporal Framework

Spine Model aims to provide a high degree of flexibility in the temporal dimension across different components of the created model. This means that the user has some freedom to choose how the temporal aspects of different components of the model are defined. This freedom increases the variety of problems that can be tackled in Spine: from very coarse, long term models, to very detailed models with a more limited horizon, or a mix of both. The choice of the user on how this flexibility is used will lead to the temporal structure of the model.

The main components of flexibility consist of the following parts:

  • The horizon that is modeled: end and start time
  • Temporal resolution
  • Possibility of a rolling optimization window
  • Support for commonly used methods such as representative days

Part of the temporal flexibility in Spine is due to the fact that these options mentioned above can be implemented differently across different components of the model, which can be very useful when different markets are coupled in a single model. The resolution and horizon of the gas market can for example be taken differently than that of the electricity market. This documentation aims to give the reader insight in how these aspects are defined, and which objects are used for this.

We start by introducing the relevant objects with their parameters, and the relevant relationship classes for the temporal structure. Afterwards, we will discuss how this setting creates flexibility and will present some of the practical approaches to create a variety of temporal structures.

Objects, relationships, and their parameters

In this section, the objects and relationships will be discussed that form the temporal structure together.

Objects relevant for the temporal framework

For the objects, the relevant parameters will also be introduced, along with the type of values that are allowed, following the format below:

  • 'parameter_name' : "Allowed value type"

model object

Each model object holds general information about the model at hand. Here we only discuss the time related parameters:

These two parameters define the model horizon. A Datetime value is to be taken for both parameters, in which case they directly mark respectively the beginning and end of the modeled time horizon.

This parameters gives the unit of duration that is used in the model calculations. The default value for this parameter is 'minute'. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.

This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In the practical approaches presented below, the rolling window optimization will be explained in more detail.

temporal_block object

A temporal block defines the properties of the optimization that is to be solved in the current window. Most importantly, it holds the necessary information about the resolution and horizon of the optimization.

  • resolution (optional): "duration value" or "array of duration values"

This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run.

  • block_start (optional): "duration value" or "Date time value"

Indicates the start of this temporal block.

  • block_end(optional): "duration value" or "Date time value"

Indicates the end of this temporal block.

Relationships relevant for the temporal framework

model__temporal_block relationship

In this relationship, a model instance is linked to a temporal block. If this relationship doesn't exist - the temporal block is disregarded from this optimization model.

model__default_temporal_block relationship

Defines the default temporal block used for model objects, which will be replaced when a specific relationship is defined for a model in model__temporal_block.

node__temporal_block relationship

This relationship will link a node to a temporal block.

units_on__temporal_block relationship

This relationship links the units_on variable of a unit to a temporal block and will therefore govern the time-resolution of the unit's online/offline status.

unit__investment_temporal_block relationship

This relationship sets the temporal dimensions for investment decisions of a certain unit. The separation between this relationship and the units_on__temporal_block, allows the user for example to give a much finer resolution to a unit's on- or offline status than to it's investment decisions.

model__default_investment_temporal_block relationship

Defines the default temporal block used for investment decisions, which will be replaced when a specific relationship is defined for a unit in unit__investment_temporal_block.

General principle of the temporal framework

The general principle of the Spine modeling temporal structure is that different temporal blocks can be defined and linked to different objects in a model. This leads to great flexibility in the temporal structure of the model as a whole. To illustrate this, we will discuss some of the possibilities that arise in this framework.

One single temporal_block

Single solve with single block

The simplest case is a single solve of the entire time horizon (so roll_forward not defined) with a fixed resolution. In this case, only one temporal block has to be defined with a fixed resolution. Each node has to be linked to this temporal_block.

Alternatively, a variable resolution can be defined by choosing an array of durations for the resolution parameter. The sum of the durations in the array then have to match the length of the temporal block. The example below illustrates an optimization that spans one day for which the resolution is hourly in the beginning and then gradually decreases to a 6h resolution at the end.

  • temporal_block_1
    • block_start: 0h (Alternative DateTime: e.g. 2030-01-01T00:00:00)
    • block_end: 1D (Alternative DateTime: e.g. 2030-01-02T00:00:00)
    • resolution: [1h 1h 1h 1h 2h 2h 2h 4h 4h 6h]

Note that, as mentioned above, the block_start and block_end parameters can also be entered as absolute values, i.e. DateTime values.

Rolling window optimization with single block

A model with a single temporal_block can also be optimized in a rolling horizon framework. In this case, the roll_forward parameter has to be defined in the model object. The roll_forward parameter will then determine how much the optimization moves forward with every step, while the size of the temporal block will determine how large a time frame is optimized in each step. To see this more clearly, let's take a look at an example.

Suppose we want to model a horizon of one week, with a rolling window size of one day. The roll_forward parameter will then be a duration value of 1d. If we take the temporal_block parameters block_start and block_end to be the duration values 0h and 1d respectively, the model will optimize each day of the week separately. However, we could also take the block_end parameter to be 2d. Now the model will start by optimizing day 1 and day 2 together, after which it keeps only the values obtained for the first day, and moves forward to optimize the second and third day together.

Again, a variable resolution can be implemented for the rolling window optimization. The sum of the durations must in this case match the size of the optimized window.

Advanced usage: multiple temporal_block objects

Single solve with multiple blocks

Disconnected time periods

Multiple temporal blocks can be used to optimize disconnected periods. Let's take a look at an example in which two temporal blocks are defined.

  • temporal_block_1
    • block_start: 0h
    • block_end: 4h
  • temporal_block_2
    • block_start: 12h
    • block_end: 16h

This example will lead to an optimization of the first four hours of the model horizon, and also of hour 12 to 16. By defining exactly the same relationships for the two temporal blocks, an optimization of disconnected periods is achieved for exactly the same model components. This leads to the possibility of implementing the widely used representative days method. If desired, it is possible to choose a different temporal resolution for the different temporal_blocks.

It is worth noting that dynamic variables like node_state and units_on merit special attention when using disconnected time periods. By default, when trying to access variables Variables outside the defined temporal_blocks, SpineOpt.jl assumes such variables exist but allows them to take any values within specified bounds. If fixed initial conditions for the disconnected periods are desired, one needs to use parameters such as fix_node_state or fix_units_on.

Different regions/commodities in different resolutions

Multiple temporal blocks can also be used to model different regions or different commodities with a different resolution. This is especially useful when there is a certain region or commodity of interest, while other elements are connected to this but require less detail. For this kind of usage, the relationships that are defined for the temporal blocks will be different, as shown in the example below.

  • temporal_blocks
    • temporal_block_1
      • resolution: 1h
    • temporal_block_2
      • resolution: 2h
  • nodes
    • node_1
    • node_2
  • node_temporal_block relationships
    • node_1_temporal_block_1
    • node_2_temporal_block_2

Similarly, the on- and offline status of a unit can be modeled with a lower resolution than the actual output of that unit, by defining the units_on_temporal_block relationship with a different temporal block than the one used for the node_temporal_block relationship (of the node to which the unit is connected).

Rolling horizon with multiple blocks

Rolling horizon with different window sizes

Similar to what has been discussed above in Different regions/commodities in different resolutions, different commodities or regions can be modeled with a different resolution in the rolling horizon setting. The way to do it is completely analogous. Furthermore, when using the rolling horizon framework, a different window size can be chosen for the different modeled components, by simply using a different block_end parameter. However, using different block_ends e.g. for interconnected regions should be treated with care, as the variables for each region will only be generated for their respective temporal_block, which in most cases will lead to inconsistent linking constraints.

Putting it all together: rolling horizon with variable resolution that differs for different model components

Below is an example of an advanced use case in which a rolling horizon optimization is used, and different model components are optimized with a different resolution. By choosing the relevant parameters in the following way:

  • model
    • roll_forward: 4h
  • temporal_blocks
    • temporal_block_A
      • resolution: [1h 1h 2h 2h 2h 3h 3h]
      • block_end: 14h
    • temporal_block_B
      • resolution: [2h 2h 4h 6h]
      • block_end: 14h
  • nodes
    • node_1
    • node_2
  • node_temporal_block relationships
    • node_1_temporal_block_A
    • node_2_temporal_block_B

The two model components that are considered have a different resolution, and their own resolution is also varying within the optimization window. Note that in this case the two optimization windows have the same size, but this is not strictly necessary. The image below visualizes the first two window optimizations of this model.

temporal structure

+Temporal Framework · SpineOpt.jl

Temporal Framework

Spine Model aims to provide a high degree of flexibility in the temporal dimension across different components of the created model. This means that the user has some freedom to choose how the temporal aspects of different components of the model are defined. This freedom increases the variety of problems that can be tackled in Spine: from very coarse, long term models, to very detailed models with a more limited horizon, or a mix of both. The choice of the user on how this flexibility is used will lead to the temporal structure of the model.

The main components of flexibility consist of the following parts:

  • The horizon that is modeled: end and start time
  • Temporal resolution
  • Possibility of a rolling optimization window
  • Support for commonly used methods such as representative days

Part of the temporal flexibility in Spine is due to the fact that these options mentioned above can be implemented differently across different components of the model, which can be very useful when different markets are coupled in a single model. The resolution and horizon of the gas market can for example be taken differently than that of the electricity market. This documentation aims to give the reader insight in how these aspects are defined, and which objects are used for this.

We start by introducing the relevant objects with their parameters, and the relevant relationship classes for the temporal structure. Afterwards, we will discuss how this setting creates flexibility and will present some of the practical approaches to create a variety of temporal structures.

Objects, relationships, and their parameters

In this section, the objects and relationships will be discussed that form the temporal structure together.

Objects relevant for the temporal framework

For the objects, the relevant parameters will also be introduced, along with the type of values that are allowed, following the format below:

  • 'parameter_name' : "Allowed value type"

model object

Each model object holds general information about the model at hand. Here we only discuss the time related parameters:

These two parameters define the model horizon. A Datetime value is to be taken for both parameters, in which case they directly mark respectively the beginning and end of the modeled time horizon.

This parameters gives the unit of duration that is used in the model calculations. The default value for this parameter is 'minute'. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.

This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In the practical approaches presented below, the rolling window optimization will be explained in more detail.

temporal_block object

A temporal block defines the properties of the optimization that is to be solved in the current window. Most importantly, it holds the necessary information about the resolution and horizon of the optimization.

  • resolution (optional): "duration value" or "array of duration values"

This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run.

  • block_start (optional): "duration value" or "Date time value"

Indicates the start of this temporal block.

  • block_end(optional): "duration value" or "Date time value"

Indicates the end of this temporal block.

Relationships relevant for the temporal framework

model__temporal_block relationship

In this relationship, a model instance is linked to a temporal block. If this relationship doesn't exist - the temporal block is disregarded from this optimization model.

model__default_temporal_block relationship

Defines the default temporal block used for model objects, which will be replaced when a specific relationship is defined for a model in model__temporal_block.

node__temporal_block relationship

This relationship will link a node to a temporal block.

units_on__temporal_block relationship

This relationship links the units_on variable of a unit to a temporal block and will therefore govern the time-resolution of the unit's online/offline status.

unit__investment_temporal_block relationship

This relationship sets the temporal dimensions for investment decisions of a certain unit. The separation between this relationship and the units_on__temporal_block, allows the user for example to give a much finer resolution to a unit's on- or offline status than to it's investment decisions.

model__default_investment_temporal_block relationship

Defines the default temporal block used for investment decisions, which will be replaced when a specific relationship is defined for a unit in unit__investment_temporal_block.

General principle of the temporal framework

The general principle of the Spine modeling temporal structure is that different temporal blocks can be defined and linked to different objects in a model. This leads to great flexibility in the temporal structure of the model as a whole. To illustrate this, we will discuss some of the possibilities that arise in this framework.

One single temporal_block

Single solve with single block

The simplest case is a single solve of the entire time horizon (so roll_forward not defined) with a fixed resolution. In this case, only one temporal block has to be defined with a fixed resolution. Each node has to be linked to this temporal_block.

Alternatively, a variable resolution can be defined by choosing an array of durations for the resolution parameter. The sum of the durations in the array then have to match the length of the temporal block. The example below illustrates an optimization that spans one day for which the resolution is hourly in the beginning and then gradually decreases to a 6h resolution at the end.

  • temporal_block_1
    • block_start: 0h (Alternative DateTime: e.g. 2030-01-01T00:00:00)
    • block_end: 1D (Alternative DateTime: e.g. 2030-01-02T00:00:00)
    • resolution: [1h 1h 1h 1h 2h 2h 2h 4h 4h 6h]

Note that, as mentioned above, the block_start and block_end parameters can also be entered as absolute values, i.e. DateTime values.

Rolling window optimization with single block

A model with a single temporal_block can also be optimized in a rolling horizon framework. In this case, the roll_forward parameter has to be defined in the model object. The roll_forward parameter will then determine how much the optimization moves forward with every step, while the size of the temporal block will determine how large a time frame is optimized in each step. To see this more clearly, let's take a look at an example.

Suppose we want to model a horizon of one week, with a rolling window size of one day. The roll_forward parameter will then be a duration value of 1d. If we take the temporal_block parameters block_start and block_end to be the duration values 0h and 1d respectively, the model will optimize each day of the week separately. However, we could also take the block_end parameter to be 2d. Now the model will start by optimizing day 1 and day 2 together, after which it keeps only the values obtained for the first day, and moves forward to optimize the second and third day together.

Again, a variable resolution can be implemented for the rolling window optimization. The sum of the durations must in this case match the size of the optimized window.

Advanced usage: multiple temporal_block objects

Single solve with multiple blocks

Disconnected time periods

Multiple temporal blocks can be used to optimize disconnected periods. Let's take a look at an example in which two temporal blocks are defined.

  • temporal_block_1
    • block_start: 0h
    • block_end: 4h
  • temporal_block_2
    • block_start: 12h
    • block_end: 16h

This example will lead to an optimization of the first four hours of the model horizon, and also of hour 12 to 16. By defining exactly the same relationships for the two temporal blocks, an optimization of disconnected periods is achieved for exactly the same model components. This leads to the possibility of implementing the widely used representative days method. If desired, it is possible to choose a different temporal resolution for the different temporal_blocks.

It is worth noting that dynamic variables like node_state and units_on merit special attention when using disconnected time periods. By default, when trying to access variables Variables outside the defined temporal_blocks, SpineOpt.jl assumes such variables exist but allows them to take any values within specified bounds. If fixed initial conditions for the disconnected periods are desired, one needs to use parameters such as fix_node_state or fix_units_on.

Different regions/commodities in different resolutions

Multiple temporal blocks can also be used to model different regions or different commodities with a different resolution. This is especially useful when there is a certain region or commodity of interest, while other elements are connected to this but require less detail. For this kind of usage, the relationships that are defined for the temporal blocks will be different, as shown in the example below.

  • temporal_blocks
    • temporal_block_1
      • resolution: 1h
    • temporal_block_2
      • resolution: 2h
  • nodes
    • node_1
    • node_2
  • node_temporal_block relationships
    • node_1_temporal_block_1
    • node_2_temporal_block_2

Similarly, the on- and offline status of a unit can be modeled with a lower resolution than the actual output of that unit, by defining the units_on_temporal_block relationship with a different temporal block than the one used for the node_temporal_block relationship (of the node to which the unit is connected).

Rolling horizon with multiple blocks

Rolling horizon with different window sizes

Similar to what has been discussed above in Different regions/commodities in different resolutions, different commodities or regions can be modeled with a different resolution in the rolling horizon setting. The way to do it is completely analogous. Furthermore, when using the rolling horizon framework, a different window size can be chosen for the different modeled components, by simply using a different block_end parameter. However, using different block_ends e.g. for interconnected regions should be treated with care, as the variables for each region will only be generated for their respective temporal_block, which in most cases will lead to inconsistent linking constraints.

Putting it all together: rolling horizon with variable resolution that differs for different model components

Below is an example of an advanced use case in which a rolling horizon optimization is used, and different model components are optimized with a different resolution. By choosing the relevant parameters in the following way:

  • model
    • roll_forward: 4h
  • temporal_blocks
    • temporal_block_A
      • resolution: [1h 1h 2h 2h 2h 3h 3h]
      • block_end: 14h
    • temporal_block_B
      • resolution: [2h 2h 4h 6h]
      • block_end: 14h
  • nodes
    • node_1
    • node_2
  • node_temporal_block relationships
    • node_1_temporal_block_A
    • node_2_temporal_block_B

The two model components that are considered have a different resolution, and their own resolution is also varying within the optimization window. Note that in this case the two optimization windows have the same size, but this is not strictly necessary. The image below visualizes the first two window optimizations of this model.

temporal structure

diff --git a/dev/advanced_concepts/unit_commitment/index.html b/dev/advanced_concepts/unit_commitment/index.html index 5d2771913c..1529862dd4 100644 --- a/dev/advanced_concepts/unit_commitment/index.html +++ b/dev/advanced_concepts/unit_commitment/index.html @@ -1,2 +1,2 @@ -Unit Commitment · SpineOpt.jl

Unit commitment

To incorporate technical detail about (clustered) unit-commitment statuses of units, the online, started and shutdown status of units can be tracked and constrained in SpineOpt. In the following, relevant relationships and parameters are introduced and the general working principle is described.

Key concepts for unit commitment

Here, we briefly describe the key concepts involved in the representation of (clustered) unit commitment models:

  • units_on is an optimization variable that holds information about the on- or offline status of a unit. Unit commitment restrictions will govern how this variable can change through time.

  • units_on__temporal_block is a relationship linking the units_on variable of this unit to a specific temporal_block object. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

  • online_variable_type is a method parameter and can take the values unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear. If the binary value is chosen, the units status is modelled as a binary (classic UC). For clustered unit commitment units, the integer type is applicable. Note that if the parameter is not defined, the default will be linear. If the units status is not crucial, this can reduce the computational burden.

  • number_of_units defines how many units of a certain unit type are available. Typically this parameter takes a binary (UC) or integer (clustered UC) value. To avoid confusion the following distinction will be made in this document: unit will be used to identify a Spine unit object, which can have multiple members. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). The default value for this parameter is $1$. It is possible to allow the model to increase the number_of_units itself, through Investment Optimization

  • unit_availability_factor: (number value or time series). Is the fraction of the time that this unit is considered to be available, by acting as a multiplier on the capacity. A time series can be used to indicate the intermittent character of renewable generation technologies.

  • min_up_time: (duration value). Sets the minimum time that a unit has to stay online after a startup. Inclusion of this parameter will trigger the creation of the constraint on Minimum up time (basic version)

  • min_down_time: (duration value). Sets the minimum time that a unit has to stay offline after a shutdown. Inclusion of this parameter will trigger the creation of the constraint on Minimum down time (basic version)

  • minimum_operating_point: (number value) limits the minimum value of the unit_flow variable for a unit which is currently online. Inclusion of this parameter will trigger the creation of the Constraint on minimum operating point

  • start_up_cost: "number value". Cost associated with starting up a unit.

  • shut_down_cost: "number value". Cost associated with shutting down a unit.

Illustrative unit commitment examples

Step 1: defining the number of members of a unit type

A spine unit can represent multiple members. This can be incorporated in a model by setting the number_of_units parameter to a specific value. For example, if we define a single unit in a model as follows:

  • unit_1
    • number_of_units: 2

And we link the unit to a certain node_1 with a unit__to_node relationship.

  • unit_1_to__node_1

The single Spine unit defined here, now represents two members. This means that a single unit_flow variable will be created for this unit, but the restrictions as imposed by the Ramping and Reserves framework will be adapted to reflect the fact that there are two members present, thus doubling the total capacity.

Step 2: choosing the online_variable_type

Next, we have to decide the online_variable_type for this unit, which will restrict the kind of values that the units_on variable can take. This basically comes down to deciding if we are working in a classical UC framework (unit_online_variable_type_binary), a clustered UC framework (unit_online_variable_type_integer), or a relaxed clustered UC framework (unit_online_variable_type_linear), in which a non-integer number of units can be online.

The classical UC framework can only be applied when the number_of_units equals 1.

Step 3: imposing a minimum operating point

The output of an online unit to a specific node can be restricted to be above a certain minimum by choosing a value for the minimum_operating_point parameter. This parameter is defined for the unit__to_node relationship, and is given as a fraction of the unit_capacity. If we continue with the example above, and define the following objects, relationships, and parameters:

  • unit_1
    • number_of_units: 2
    • unit_online_variable_type: "unit_online_variable_type_integer"
  • unit_1_to__node_1
    • minimum_operating_point: 0.2
    • unit_capacity: 200

It can be seen that in this case the unit_flow form unit_1 to node_1 must for any timestep $t$ be larger than $units\_on(t) * 0.2 * 200$

Step 4: imposing a minimum up or down time

Spine units can also be restricted in their commitment status with minimum up- or down times by choosing a value for the min_up_time or min_down_time respectively. These parameters are defined for the unit object, and should be duration values. We can continue the example and add a minimum up time for the unit:

  • unit_1
    • number_of_units: 2
    • unit_online_variable_type: "unit_online_variable_type_integer"
    • min_up_time: 2h
  • unit_1_to__node_1
    • minimum_operating_point: 0.2
    • unit_capacity: 200

Whereas the units_on variable was restricted (before inclusion of the min_up_time parameter) to be smaller than or equal to the number_of_units for any timestep $t$, it now has to be smaller than or equal to the number_of_units decremented with the units_started_up summed over the timesteps that include t - min_up_time. This implies that a unit which has started up, has to stay online for at least the min_up_time

To consider a simple example let's assume that we have a model with a resolution of 1h. Suppose that before t, there is no member of the unit online and in timestep t -> t + 1h, one member starts up. Another member starts up in timestep t + 1h \-> t + 2h. The first startup, along with the minimum up time of 2 hours implies that the units_on variable of this unit has now changed to $1$ in timestep t -> t + 1h and can not go back to $0$ in timestep t-> t + 1h -> t + 2h. The second startup further restricts the number of units that are allowed to be online, it can be seen that the following restrictions apply when both startups are combined with the minimum up time of 2h:

  • t-> t + 1h : $units\_on = 1$
  • t + 1h -> t + 2h: $units\_on = 2$
  • t + 2h-> t + 3h: $units\_on \in {1,2}$
  • t + 3h-> t + 4h: $units\_on \in {0,1,2}$

The minimum down time restrictions operate in very much the same way, they simply impose that units that have been shut down, have to stay offline for the chosen period of time.

Step 5: allocationg a cost to startups or shutdowns

Costs can be allocated to startups or shutdowns by choosing a value for the start_up_cost or shut_down_cost respectively.

Step 6: defining unit availabilities

By defining a unit_availability_factor, the fact that typical members are not available all the time can be reflected in the model.

Typically, units are not available $100$% of the time, due to scheduled maintenance, unforeseen outages, or other things. This can be incorporated in the model by setting the unit_availability_factor to a fractional value. For each timestep in the model, an upper bound is then imposed on the units_on variable, equal to number_of_units $*$ unit_availability_factor. This parameter can not be used when the online_variable_type is binary. It should also be noted that when the online_variable_type is of integer type, the aforementioned product must be integer as well, since it will determine the value of the units_available parameter which is restricted to integer values. The default value for this parameter is $1$.

The unit_availability_factor can also be taken as a timeseries. By allowing a different availability factor for each timestep in the model, it can perfectly be used to represent intermittent technologies of which the output cannot be fully controlled.

+Unit Commitment · SpineOpt.jl

Unit commitment

To incorporate technical detail about (clustered) unit-commitment statuses of units, the online, started and shutdown status of units can be tracked and constrained in SpineOpt. In the following, relevant relationships and parameters are introduced and the general working principle is described.

Key concepts for unit commitment

Here, we briefly describe the key concepts involved in the representation of (clustered) unit commitment models:

  • units_on is an optimization variable that holds information about the on- or offline status of a unit. Unit commitment restrictions will govern how this variable can change through time.

  • units_on__temporal_block is a relationship linking the units_on variable of this unit to a specific temporal_block object. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

  • online_variable_type is a method parameter and can take the values unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear. If the binary value is chosen, the units status is modelled as a binary (classic UC). For clustered unit commitment units, the integer type is applicable. Note that if the parameter is not defined, the default will be linear. If the units status is not crucial, this can reduce the computational burden.

  • number_of_units defines how many units of a certain unit type are available. Typically this parameter takes a binary (UC) or integer (clustered UC) value. To avoid confusion the following distinction will be made in this document: unit will be used to identify a Spine unit object, which can have multiple members. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). The default value for this parameter is $1$. It is possible to allow the model to increase the number_of_units itself, through Investment Optimization

  • unit_availability_factor: (number value or time series). Is the fraction of the time that this unit is considered to be available, by acting as a multiplier on the capacity. A time series can be used to indicate the intermittent character of renewable generation technologies.

  • min_up_time: (duration value). Sets the minimum time that a unit has to stay online after a startup. Inclusion of this parameter will trigger the creation of the constraint on Minimum up time (basic version)

  • min_down_time: (duration value). Sets the minimum time that a unit has to stay offline after a shutdown. Inclusion of this parameter will trigger the creation of the constraint on Minimum down time (basic version)

  • minimum_operating_point: (number value) limits the minimum value of the unit_flow variable for a unit which is currently online. Inclusion of this parameter will trigger the creation of the Constraint on minimum operating point

  • start_up_cost: "number value". Cost associated with starting up a unit.

  • shut_down_cost: "number value". Cost associated with shutting down a unit.

Illustrative unit commitment examples

Step 1: defining the number of members of a unit type

A spine unit can represent multiple members. This can be incorporated in a model by setting the number_of_units parameter to a specific value. For example, if we define a single unit in a model as follows:

  • unit_1
    • number_of_units: 2

And we link the unit to a certain node_1 with a unit__to_node relationship.

  • unit_1_to__node_1

The single Spine unit defined here, now represents two members. This means that a single unit_flow variable will be created for this unit, but the restrictions as imposed by the Ramping and Reserves framework will be adapted to reflect the fact that there are two members present, thus doubling the total capacity.

Step 2: choosing the online_variable_type

Next, we have to decide the online_variable_type for this unit, which will restrict the kind of values that the units_on variable can take. This basically comes down to deciding if we are working in a classical UC framework (unit_online_variable_type_binary), a clustered UC framework (unit_online_variable_type_integer), or a relaxed clustered UC framework (unit_online_variable_type_linear), in which a non-integer number of units can be online.

The classical UC framework can only be applied when the number_of_units equals 1.

Step 3: imposing a minimum operating point

The output of an online unit to a specific node can be restricted to be above a certain minimum by choosing a value for the minimum_operating_point parameter. This parameter is defined for the unit__to_node relationship, and is given as a fraction of the unit_capacity. If we continue with the example above, and define the following objects, relationships, and parameters:

  • unit_1
    • number_of_units: 2
    • unit_online_variable_type: "unit_online_variable_type_integer"
  • unit_1_to__node_1
    • minimum_operating_point: 0.2
    • unit_capacity: 200

It can be seen that in this case the unit_flow form unit_1 to node_1 must for any timestep $t$ be larger than $units\_on(t) * 0.2 * 200$

Step 4: imposing a minimum up or down time

Spine units can also be restricted in their commitment status with minimum up- or down times by choosing a value for the min_up_time or min_down_time respectively. These parameters are defined for the unit object, and should be duration values. We can continue the example and add a minimum up time for the unit:

  • unit_1
    • number_of_units: 2
    • unit_online_variable_type: "unit_online_variable_type_integer"
    • min_up_time: 2h
  • unit_1_to__node_1
    • minimum_operating_point: 0.2
    • unit_capacity: 200

Whereas the units_on variable was restricted (before inclusion of the min_up_time parameter) to be smaller than or equal to the number_of_units for any timestep $t$, it now has to be smaller than or equal to the number_of_units decremented with the units_started_up summed over the timesteps that include t - min_up_time. This implies that a unit which has started up, has to stay online for at least the min_up_time

To consider a simple example let's assume that we have a model with a resolution of 1h. Suppose that before t, there is no member of the unit online and in timestep t -> t + 1h, one member starts up. Another member starts up in timestep t + 1h \-> t + 2h. The first startup, along with the minimum up time of 2 hours implies that the units_on variable of this unit has now changed to $1$ in timestep t -> t + 1h and can not go back to $0$ in timestep t-> t + 1h -> t + 2h. The second startup further restricts the number of units that are allowed to be online, it can be seen that the following restrictions apply when both startups are combined with the minimum up time of 2h:

  • t-> t + 1h : $units\_on = 1$
  • t + 1h -> t + 2h: $units\_on = 2$
  • t + 2h-> t + 3h: $units\_on \in {1,2}$
  • t + 3h-> t + 4h: $units\_on \in {0,1,2}$

The minimum down time restrictions operate in very much the same way, they simply impose that units that have been shut down, have to stay offline for the chosen period of time.

Step 5: allocationg a cost to startups or shutdowns

Costs can be allocated to startups or shutdowns by choosing a value for the start_up_cost or shut_down_cost respectively.

Step 6: defining unit availabilities

By defining a unit_availability_factor, the fact that typical members are not available all the time can be reflected in the model.

Typically, units are not available $100$% of the time, due to scheduled maintenance, unforeseen outages, or other things. This can be incorporated in the model by setting the unit_availability_factor to a fractional value. For each timestep in the model, an upper bound is then imposed on the units_on variable, equal to number_of_units $*$ unit_availability_factor. This parameter can not be used when the online_variable_type is binary. It should also be noted that when the online_variable_type is of integer type, the aforementioned product must be integer as well, since it will determine the value of the units_available parameter which is restricted to integer values. The default value for this parameter is $1$.

The unit_availability_factor can also be taken as a timeseries. By allowing a different availability factor for each timestep in the model, it can perfectly be used to represent intermittent technologies of which the output cannot be fully controlled.

diff --git a/dev/advanced_concepts/user_constraints/index.html b/dev/advanced_concepts/user_constraints/index.html index e7ba4c6f7e..0b9df1e4c8 100644 --- a/dev/advanced_concepts/user_constraints/index.html +++ b/dev/advanced_concepts/user_constraints/index.html @@ -1,2 +1,2 @@ -User Constraints · SpineOpt.jl

User Constraints

User constraints allow the user to define arbitrary linear constraints involving most of the problem variables. This section describes this function and how to use it.

Key User Constraint Concepts

  1. The basic principle: The basic steps involved in forming a user constraint are:
  • Creating a user constraint object: One creates a new user_constraint object which will be used as a unique handle for the specific constraint and on which constraint-level parameters will be defined.
  • Specify which variables are involved in the constraint: this generally involves creating a relationship involving the user_constraint object. For example, specifying the relationship unit__from_node__user_constraint specifies that the corresponding unit_flow variable is involved in the constraint. The table below contains a complete list of variables and the corresponding relationships to set.
  • Specify the variable coefficients: this will generally involve specifying a parameter named *_coefficient on the relationship defined above to specify the coefficient on that particular variable in the constraint. For example, to define the coefficient on the unit_flow variable, one specifies the unit_flow_coefficient parameter on the approrpriate unit__from_node__user_constraint relationship. The table below contains a complete list of variables and the corresponding coefficient parameters to set.
  • Specify the right-hand-side constant term: The constraint should be formed in conventional form with all constant terms moved to the right-hand side. The right-hand-side constant term is specified by setting the right_hand_side user_constraint parameter.
    • Specify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are ==, >= and <=.
    • Coefficients can be defined on some parameters themselves. For example, one may specify a coefficient on a node's demand parameter. This is done by specifying the relationship node__user_constraint and specifying the demand_coefficient parameter on that relationship
  1. Piecewise unit_flow coefficients: As described in operating_points, specifying this parameter decomposes the unit_flow variable into a number of sub operating segment variables named unit_flow_op in the model and with an additional index, i for the operating segment. The intention of this functionality is to allow unit_flow coefficients to be defined individually per segment to define a piecewise linear function. To accomplish this, the steps are as described above with the exception that one must define operating_points on the appropriate unit__from_node or unit__to_node as an array type with the dimension corresponding to the number of operating points and then set the unit_flow_coefficient for the appropriate unit__from_node__user_constraint relationship, also as an array type with the same number of elements. Note that if operating points is defined as an array type with more than one elements, unit_flow_coefficient may be defined as either an array or non-array type. However, if operating_points is of non-array type, corresponding unit_flow_coefficients must also be of non-array types.
  2. Variables, relationships and coefficient guide for user constraints The table below provides guidance regarding what relationships and coefficients to set for various problem variables and parameters.
Problem variable / Parameter NameRelationshipParameter
unit_flow (direction=from_node)unit__from_node__user_constraintunit_flow_coefficient (non-array type)
unit_flow (direction=to_node)unit__to_node__user_constraintunit_flow_coefficient (non-array type)
unit_flow_op (direction=from_node)unit__from_node__user_constraintunit_flow_coefficient (array type)
unit_flow_op (direction=to_node)unit__to_node__user_constraintunit_flow_coefficient (array type)
connection_flow (direction=from_node)connection__from_node__user_constraintconnection_flow_coefficient
connection_flow (direction=to_node)connection__to_node__user_constraintconnection_flow_coefficient
node_statenode__user_constraintnode_state_coefficient
storages_investednode__user_constraintstorages_invested_coefficient
storages_invested_availablenode__user_constraintstorages_invested_available_coefficient
demandnode__user_constraintdemand_coefficient
units_onunit__user_constraintunits_on_coefficient
units_started_upunit__user_constraintunits_started_up_coefficient
units_investedunit__user_constraintunits_invested_coefficient
units_invested_availableunit__user_constraintunits_invested_available_coefficient
connections_investedconnection__user_constraintconnections_invested_coefficient
connections_invested_availableconnection__user_constraintconnections_invested_available_coefficient
+User Constraints · SpineOpt.jl

User Constraints

User constraints allow the user to define arbitrary linear constraints involving most of the problem variables. This section describes this function and how to use it.

Key User Constraint Concepts

  1. The basic principle: The basic steps involved in forming a user constraint are:
  • Creating a user constraint object: One creates a new user_constraint object which will be used as a unique handle for the specific constraint and on which constraint-level parameters will be defined.
  • Specify which variables are involved in the constraint: this generally involves creating a relationship involving the user_constraint object. For example, specifying the relationship unit__from_node__user_constraint specifies that the corresponding unit_flow variable is involved in the constraint. The table below contains a complete list of variables and the corresponding relationships to set.
  • Specify the variable coefficients: this will generally involve specifying a parameter named *_coefficient on the relationship defined above to specify the coefficient on that particular variable in the constraint. For example, to define the coefficient on the unit_flow variable, one specifies the unit_flow_coefficient parameter on the approrpriate unit__from_node__user_constraint relationship. The table below contains a complete list of variables and the corresponding coefficient parameters to set.
  • Specify the right-hand-side constant term: The constraint should be formed in conventional form with all constant terms moved to the right-hand side. The right-hand-side constant term is specified by setting the right_hand_side user_constraint parameter.
    • Specify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are ==, >= and <=.
    • Coefficients can be defined on some parameters themselves. For example, one may specify a coefficient on a node's demand parameter. This is done by specifying the relationship node__user_constraint and specifying the demand_coefficient parameter on that relationship
  1. Piecewise unit_flow coefficients: As described in operating_points, specifying this parameter decomposes the unit_flow variable into a number of sub operating segment variables named unit_flow_op in the model and with an additional index, i for the operating segment. The intention of this functionality is to allow unit_flow coefficients to be defined individually per segment to define a piecewise linear function. To accomplish this, the steps are as described above with the exception that one must define operating_points on the appropriate unit__from_node or unit__to_node as an array type with the dimension corresponding to the number of operating points and then set the unit_flow_coefficient for the appropriate unit__from_node__user_constraint relationship, also as an array type with the same number of elements. Note that if operating points is defined as an array type with more than one elements, unit_flow_coefficient may be defined as either an array or non-array type. However, if operating_points is of non-array type, corresponding unit_flow_coefficients must also be of non-array types.
  2. Variables, relationships and coefficient guide for user constraints The table below provides guidance regarding what relationships and coefficients to set for various problem variables and parameters.
Problem variable / Parameter NameRelationshipParameter
unit_flow (direction=from_node)unit__from_node__user_constraintunit_flow_coefficient (non-array type)
unit_flow (direction=to_node)unit__to_node__user_constraintunit_flow_coefficient (non-array type)
unit_flow_op (direction=from_node)unit__from_node__user_constraintunit_flow_coefficient (array type)
unit_flow_op (direction=to_node)unit__to_node__user_constraintunit_flow_coefficient (array type)
connection_flow (direction=from_node)connection__from_node__user_constraintconnection_flow_coefficient
connection_flow (direction=to_node)connection__to_node__user_constraintconnection_flow_coefficient
node_statenode__user_constraintnode_state_coefficient
storages_investednode__user_constraintstorages_invested_coefficient
storages_invested_availablenode__user_constraintstorages_invested_available_coefficient
demandnode__user_constraintdemand_coefficient
units_onunit__user_constraintunits_on_coefficient
units_started_upunit__user_constraintunits_started_up_coefficient
units_investedunit__user_constraintunits_invested_coefficient
units_invested_availableunit__user_constraintunits_invested_available_coefficient
connections_investedconnection__user_constraintconnections_invested_coefficient
connections_invested_availableconnection__user_constraintconnections_invested_available_coefficient
diff --git a/dev/concept_reference/Object Classes/index.html b/dev/concept_reference/Object Classes/index.html index baa72dc941..bfefa0fc0e 100644 --- a/dev/concept_reference/Object Classes/index.html +++ b/dev/concept_reference/Object Classes/index.html @@ -1,2 +1,2 @@ -Object Classes · SpineOpt.jl

Object Classes

commodity

A good or product that can be consumed, produced, traded. E.g., electricity, oil, gas, water...

Related Parameters: commodity_lodf_tolerance, commodity_physics_duration, commodity_physics, commodity_ptdf_threshold, is_active, mp_min_res_gen_to_demand_ratio_slack_penalty and mp_min_res_gen_to_demand_ratio

Related Relationship Classes: node__commodity and unit__commodity

Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)

connection

A transfer of commodities between nodes. E.g. electricity line, gas pipeline...

Related Parameters: benders_starting_connections_invested, candidate_connections, connection_availability_factor, connection_contingency, connection_investment_cost, connection_investment_lifetime, connection_investment_variable_type, connection_monitored, connection_reactance_base, connection_reactance, connection_resistance, connection_type, connections_invested_big_m_mga, connections_invested_mga_weight, connections_invested_mga, fix_connections_invested_available, fix_connections_invested, forced_availability_factor, graph_view_position, has_binary_gas_flow, initial_connections_invested_available, initial_connections_invested and is_active

Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__investment_group, connection__investment_stochastic_structure, connection__investment_temporal_block, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node and connection__user_constraint

A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.

A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.

investment_group

A group of investments that need to be done together.

Related Parameters: equal_investments, maximum_capacity_invested_available, maximum_entities_invested_available, minimum_capacity_invested_available and minimum_entities_invested_available

Related Relationship Classes: connection__from_node__investment_group, connection__investment_group, connection__to_node__investment_group, node__investment_group, unit__from_node__investment_group, unit__investment_group and unit__to_node__investment_group

The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.

To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.

model

An instance of SpineOpt, that specifies general parameters such as the temporal horizon.

Related Parameters: big_m, db_lp_solver_options, db_lp_solver, db_mip_solver_options, db_mip_solver, duration_unit, is_active, max_gap, max_iterations, max_mga_iterations, max_mga_slack, min_iterations, model_end, model_start, model_type, roll_forward, window_duration, window_weight, write_lodf_file, write_mps_file and write_ptdf_file

Related Relationship Classes: model__default_investment_stochastic_structure, model__default_investment_temporal_block, model__default_stochastic_structure, model__default_temporal_block, model__report, model__stochastic_structure and model__temporal_block

The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).

node

A universal aggregator of commodify flows over units and connections, with storage capabilities.

Related Parameters: balance_type, benders_starting_storages_invested, candidate_storages, demand, downward_reserve, fix_node_pressure, fix_node_state, fix_node_voltage_angle, fix_storages_invested_available, fix_storages_invested, frac_state_loss, fractional_demand, graph_view_position, has_pressure, has_state, has_voltage_angle, initial_node_pressure, initial_node_state, initial_node_voltage_angle, initial_storages_invested_available, initial_storages_invested, is_active, is_non_spinning, is_reserve_node, max_node_pressure, max_voltage_angle, min_node_pressure, min_voltage_angle, minimum_reserve_activation_time, nodal_balance_sense, node_opf_type, node_slack_penalty, node_state_cap, node_state_min, state_coeff, storage_investment_cost, storage_investment_lifetime, storage_investment_variable_type, storages_invested_big_m_mga, storages_invested_mga_weight, storages_invested_mga, tax_in_unit_flow, tax_net_unit_flow, tax_out_unit_flow and upward_reserve

Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node, node__commodity, node__investment_group, node__investment_stochastic_structure, node__investment_temporal_block, node__node, node__stochastic_structure, node__temporal_block, node__user_constraint, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint and unit__to_node

The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.

Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.

output

A variable name from SpineOpt that can be included in a report.

Related Parameters: is_active and output_resolution

Related Relationship Classes: report__output

An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

report

A results report from a particular SpineOpt run, including the value of specific variables.

Related Parameters: is_active and output_db_url

Related Relationship Classes: model__report and report__output

A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

settings

Internal SpineOpt settings. We kindly advise not to mess with this one.

Related Parameters: version

TODO

stochastic_scenario

A scenario for stochastic optimisation in SpineOpt.

Related Parameters: is_active

Related Relationship Classes: parent_stochastic_scenario__child_stochastic_scenario and stochastic_structure__stochastic_scenario

Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.

stochastic_structure

A group of stochastic scenarios that represent a structure.

Related Parameters: is_active

Related Relationship Classes: connection__investment_stochastic_structure, model__default_investment_stochastic_structure, model__default_stochastic_structure, model__stochastic_structure, node__investment_stochastic_structure, node__stochastic_structure, stochastic_structure__stochastic_scenario, unit__investment_stochastic_structure and units_on__stochastic_structure

The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.

The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.

temporal_block

A length of time with a particular resolution.

Related Parameters: block_end, block_start, is_active, representative_periods_mapping, resolution and weight

Related Relationship Classes: connection__investment_temporal_block, model__default_investment_temporal_block, model__default_temporal_block, model__temporal_block, node__investment_temporal_block, node__temporal_block, unit__investment_temporal_block and units_on__temporal_block

A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.

unit

A conversion of one/many comodities between nodes.

Related Parameters: benders_starting_units_invested, candidate_units, curtailment_cost, fix_units_invested_available, fix_units_invested, fix_units_on, fom_cost, forced_availability_factor, graph_view_position, initial_units_invested_available, initial_units_invested, initial_units_on, is_active, is_renewable, min_down_time, min_up_time, number_of_units, online_variable_type, shut_down_cost, start_up_cost, unit_availability_factor, unit_investment_cost, unit_investment_lifetime, unit_investment_variable_type, units_invested_big_m_mga, units_invested_mga_weight, units_invested_mga, units_on_cost, units_on_non_anticipativity_margin and units_on_non_anticipativity_time

Related Relationship Classes: unit__commodity, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__investment_group, unit__investment_stochastic_structure, unit__investment_temporal_block, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint, unit__to_node, unit__user_constraint, units_on__stochastic_structure and units_on__temporal_block

A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.

A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.

user_constraint

A generic data-driven custom constraint.

Related Parameters: constraint_sense, is_active, right_hand_side and user_constraint_slack_penalty

Related Relationship Classes: connection__from_node__user_constraint, connection__to_node__user_constraint, connection__user_constraint, node__user_constraint, unit__from_node__user_constraint, unit__to_node__user_constraint and unit__user_constraint

The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.

Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.

For more information, see the dedicated article on User Constraints

+Object Classes · SpineOpt.jl

Object Classes

commodity

A good or product that can be consumed, produced, traded. E.g., electricity, oil, gas, water...

Related Parameters: commodity_lodf_tolerance, commodity_physics_duration, commodity_physics, commodity_ptdf_threshold, is_active, mp_min_res_gen_to_demand_ratio_slack_penalty and mp_min_res_gen_to_demand_ratio

Related Relationship Classes: node__commodity and unit__commodity

Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)

connection

A transfer of commodities between nodes. E.g. electricity line, gas pipeline...

Related Parameters: benders_starting_connections_invested, candidate_connections, connection_availability_factor, connection_contingency, connection_investment_cost, connection_investment_lifetime, connection_investment_variable_type, connection_monitored, connection_reactance_base, connection_reactance, connection_resistance, connection_type, connections_invested_big_m_mga, connections_invested_mga_weight, connections_invested_mga, fix_connections_invested_available, fix_connections_invested, forced_availability_factor, graph_view_position, has_binary_gas_flow, initial_connections_invested_available, initial_connections_invested and is_active

Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__investment_group, connection__investment_stochastic_structure, connection__investment_temporal_block, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node and connection__user_constraint

A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.

A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.

investment_group

A group of investments that need to be done together.

Related Parameters: equal_investments, maximum_capacity_invested_available, maximum_entities_invested_available, minimum_capacity_invested_available and minimum_entities_invested_available

Related Relationship Classes: connection__from_node__investment_group, connection__investment_group, connection__to_node__investment_group, node__investment_group, unit__from_node__investment_group, unit__investment_group and unit__to_node__investment_group

The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.

To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.

model

An instance of SpineOpt, that specifies general parameters such as the temporal horizon.

Related Parameters: big_m, db_lp_solver_options, db_lp_solver, db_mip_solver_options, db_mip_solver, duration_unit, is_active, max_gap, max_iterations, max_mga_iterations, max_mga_slack, min_iterations, model_end, model_start, model_type, roll_forward, window_duration, window_weight, write_lodf_file, write_mps_file and write_ptdf_file

Related Relationship Classes: model__default_investment_stochastic_structure, model__default_investment_temporal_block, model__default_stochastic_structure, model__default_temporal_block, model__report, model__stochastic_structure and model__temporal_block

The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).

node

A universal aggregator of commodify flows over units and connections, with storage capabilities.

Related Parameters: balance_type, benders_starting_storages_invested, candidate_storages, demand, downward_reserve, fix_node_pressure, fix_node_state, fix_node_voltage_angle, fix_storages_invested_available, fix_storages_invested, frac_state_loss, fractional_demand, graph_view_position, has_pressure, has_state, has_voltage_angle, initial_node_pressure, initial_node_state, initial_node_voltage_angle, initial_storages_invested_available, initial_storages_invested, is_active, is_non_spinning, is_reserve_node, max_node_pressure, max_voltage_angle, min_node_pressure, min_voltage_angle, minimum_reserve_activation_time, nodal_balance_sense, node_opf_type, node_slack_penalty, node_state_cap, node_state_min, state_coeff, storage_investment_cost, storage_investment_lifetime, storage_investment_variable_type, storages_invested_big_m_mga, storages_invested_mga_weight, storages_invested_mga, tax_in_unit_flow, tax_net_unit_flow, tax_out_unit_flow and upward_reserve

Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node, node__commodity, node__investment_group, node__investment_stochastic_structure, node__investment_temporal_block, node__node, node__stochastic_structure, node__temporal_block, node__user_constraint, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint and unit__to_node

The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.

Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.

output

A variable name from SpineOpt that can be included in a report.

Related Parameters: is_active and output_resolution

Related Relationship Classes: report__output

An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

report

A results report from a particular SpineOpt run, including the value of specific variables.

Related Parameters: is_active and output_db_url

Related Relationship Classes: model__report and report__output

A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

settings

Internal SpineOpt settings. We kindly advise not to mess with this one.

Related Parameters: version

TODO

stochastic_scenario

A scenario for stochastic optimisation in SpineOpt.

Related Parameters: is_active

Related Relationship Classes: parent_stochastic_scenario__child_stochastic_scenario and stochastic_structure__stochastic_scenario

Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.

stochastic_structure

A group of stochastic scenarios that represent a structure.

Related Parameters: is_active

Related Relationship Classes: connection__investment_stochastic_structure, model__default_investment_stochastic_structure, model__default_stochastic_structure, model__stochastic_structure, node__investment_stochastic_structure, node__stochastic_structure, stochastic_structure__stochastic_scenario, unit__investment_stochastic_structure and units_on__stochastic_structure

The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.

The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.

temporal_block

A length of time with a particular resolution.

Related Parameters: block_end, block_start, is_active, representative_periods_mapping, resolution and weight

Related Relationship Classes: connection__investment_temporal_block, model__default_investment_temporal_block, model__default_temporal_block, model__temporal_block, node__investment_temporal_block, node__temporal_block, unit__investment_temporal_block and units_on__temporal_block

A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.

unit

A conversion of one/many comodities between nodes.

Related Parameters: benders_starting_units_invested, candidate_units, curtailment_cost, fix_units_invested_available, fix_units_invested, fix_units_on, fom_cost, forced_availability_factor, graph_view_position, initial_units_invested_available, initial_units_invested, initial_units_on, is_active, is_renewable, min_down_time, min_up_time, number_of_units, online_variable_type, shut_down_cost, start_up_cost, unit_availability_factor, unit_investment_cost, unit_investment_lifetime, unit_investment_variable_type, units_invested_big_m_mga, units_invested_mga_weight, units_invested_mga, units_on_cost, units_on_non_anticipativity_margin and units_on_non_anticipativity_time

Related Relationship Classes: unit__commodity, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__investment_group, unit__investment_stochastic_structure, unit__investment_temporal_block, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint, unit__to_node, unit__user_constraint, units_on__stochastic_structure and units_on__temporal_block

A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.

A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.

user_constraint

A generic data-driven custom constraint.

Related Parameters: constraint_sense, is_active, right_hand_side and user_constraint_slack_penalty

Related Relationship Classes: connection__from_node__user_constraint, connection__to_node__user_constraint, connection__user_constraint, node__user_constraint, unit__from_node__user_constraint, unit__to_node__user_constraint and unit__user_constraint

The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.

Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.

For more information, see the dedicated article on User Constraints

diff --git a/dev/concept_reference/Parameter Value Lists/index.html b/dev/concept_reference/Parameter Value Lists/index.html index 610ff85727..0115c95120 100644 --- a/dev/concept_reference/Parameter Value Lists/index.html +++ b/dev/concept_reference/Parameter Value Lists/index.html @@ -1,2 +1,2 @@ -Parameter Value Lists · SpineOpt.jl

Parameter Value Lists

balance_type_list

Possible values: balance_type_group, balance_type_node and balance_type_none

The balance_type_list parameter value list contains the possible values for the balance_type parameter.

boolean_value_list

Possible values: false and true

A list of boolean values (True or False).

commodity_physics_list

Possible values: commodity_physics_lodf, commodity_physics_none and commodity_physics_ptdf

commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details

connection_investment_variable_type_list

Possible values: connection_investment_variable_type_continuous and connection_investment_variable_type_integer

The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous.

connection_type_list

Possible values: connection_type_lossless_bidirectional and connection_type_normal

connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details

constraint_sense_list

Possible values: <=, == and >=

The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.

db_lp_solver_list

Possible values: CDCS.jl, CDDLib.jl, COSMO.jl, CPLEX.jl, CSDP.jl, Clp.jl, ECOS.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Hypatia.jl, Ipopt.jl, KNITRO.jl, MadNLP.jl, MosekTools.jl, NLopt.jl, OSQP.jl, ProxSDP.jl, SCIP.jl, SCS.jl, SDPA.jl, SDPNAL.jl, SDPT3.jl, SeDuMi.jl and Xpress.jl

List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.

db_mip_solver_list

Possible values: CPLEX.jl, Cbc.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Juniper.jl, KNITRO.jl, MosekTools.jl, SCIP.jl and Xpress.jl

List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.

duration_unit_list

Possible values: hour and minute

The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.

model_type_list

Possible values: spineopt_benders, spineopt_mga, spineopt_other and spineopt_standard

model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details

node_opf_type_list

Possible values: node_opf_type_normal and node_opf_type_reference

Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.

See also powerflow.

unit_investment_variable_type_list

Possible values: unit_investment_variable_type_continuous and unit_investment_variable_type_integer

unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous.

unit_online_variable_type_list

Possible values: unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear and unit_online_variable_type_none

unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear.

variable_type_list

Possible values: variable_type_binary, variable_type_continuous and variable_type_integer

The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.

write_mps_file_list

Possible values: write_mps_always, write_mps_never and write_mps_on_no_solve

This parameter value list is deprecated and will be removed in a future version.

Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\_mps\_on\_no\_solve, and write\_mps\_never.

+Parameter Value Lists · SpineOpt.jl

Parameter Value Lists

balance_type_list

Possible values: balance_type_group, balance_type_node and balance_type_none

The balance_type_list parameter value list contains the possible values for the balance_type parameter.

boolean_value_list

Possible values: false and true

A list of boolean values (True or False).

commodity_physics_list

Possible values: commodity_physics_lodf, commodity_physics_none and commodity_physics_ptdf

commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details

connection_investment_variable_type_list

Possible values: connection_investment_variable_type_continuous and connection_investment_variable_type_integer

The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous.

connection_type_list

Possible values: connection_type_lossless_bidirectional and connection_type_normal

connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details

constraint_sense_list

Possible values: <=, == and >=

The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.

db_lp_solver_list

Possible values: CDCS.jl, CDDLib.jl, COSMO.jl, CPLEX.jl, CSDP.jl, Clp.jl, ECOS.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Hypatia.jl, Ipopt.jl, KNITRO.jl, MadNLP.jl, MosekTools.jl, NLopt.jl, OSQP.jl, ProxSDP.jl, SCIP.jl, SCS.jl, SDPA.jl, SDPNAL.jl, SDPT3.jl, SeDuMi.jl and Xpress.jl

List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.

db_mip_solver_list

Possible values: CPLEX.jl, Cbc.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Juniper.jl, KNITRO.jl, MosekTools.jl, SCIP.jl and Xpress.jl

List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.

duration_unit_list

Possible values: hour and minute

The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.

model_type_list

Possible values: spineopt_benders, spineopt_mga, spineopt_other and spineopt_standard

model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details

node_opf_type_list

Possible values: node_opf_type_normal and node_opf_type_reference

Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.

See also powerflow.

unit_investment_variable_type_list

Possible values: unit_investment_variable_type_continuous and unit_investment_variable_type_integer

unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous.

unit_online_variable_type_list

Possible values: unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear and unit_online_variable_type_none

unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear.

variable_type_list

Possible values: variable_type_binary, variable_type_continuous and variable_type_integer

The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.

write_mps_file_list

Possible values: write_mps_always, write_mps_never and write_mps_on_no_solve

This parameter value list is deprecated and will be removed in a future version.

Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\_mps\_on\_no\_solve, and write\_mps\_never.

diff --git a/dev/concept_reference/Parameters/index.html b/dev/concept_reference/Parameters/index.html index 72059ec4dc..020cc086a7 100644 --- a/dev/concept_reference/Parameters/index.html +++ b/dev/concept_reference/Parameters/index.html @@ -5,4 +5,4 @@ # If not a root `stochastic_scenario` -weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.

window_duration

The duration of the window in case it differs from roll_forward

Related Object Classes: model

TODO

window_weight

The weight of the window in the rolling subproblem

Default value: 1

Related Object Classes: model

The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.

To use weighted rolling representative periods Benders, do the following.

Note that it the problem rolls n times, then you have n + 1 windows.

write_lodf_file

A boolean flag for whether the LODF values should be written to a results file.

Default value: false

Uses Parameter Value Lists: boolean_value_list

Related Object Classes: model

If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.

write_mps_file

A selector for writing an .mps file of the model.

Uses Parameter Value Lists: write_mps_file_list

Related Object Classes: model

This parameter is deprecated and will be removed in a future version.

This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\_mps\_on\_no\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\_mps\_never, no file will be written

write_ptdf_file

A boolean flag for whether the LODF values should be written to a results file.

Default value: false

Uses Parameter Value Lists: boolean_value_list

Related Object Classes: model

If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.

+weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.

window_duration

The duration of the window in case it differs from roll_forward

Related Object Classes: model

TODO

window_weight

The weight of the window in the rolling subproblem

Default value: 1

Related Object Classes: model

The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.

To use weighted rolling representative periods Benders, do the following.

Note that it the problem rolls n times, then you have n + 1 windows.

write_lodf_file

A boolean flag for whether the LODF values should be written to a results file.

Default value: false

Uses Parameter Value Lists: boolean_value_list

Related Object Classes: model

If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.

write_mps_file

A selector for writing an .mps file of the model.

Uses Parameter Value Lists: write_mps_file_list

Related Object Classes: model

This parameter is deprecated and will be removed in a future version.

This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\_mps\_on\_no\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\_mps\_never, no file will be written

write_ptdf_file

A boolean flag for whether the LODF values should be written to a results file.

Default value: false

Uses Parameter Value Lists: boolean_value_list

Related Object Classes: model

If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.

diff --git a/dev/concept_reference/Relationship Classes/index.html b/dev/concept_reference/Relationship Classes/index.html index edc567bb9e..cd3381d184 100644 --- a/dev/concept_reference/Relationship Classes/index.html +++ b/dev/concept_reference/Relationship Classes/index.html @@ -1,2 +1,2 @@ -Relationship Classes · SpineOpt.jl

Relationship Classes

connection__from_node

Defines the nodes the connection can take input from, and holds most connection_flow variable specific parameters.

Related Object Classes: connection and node

Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow

connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

connection__from_node__investment_group

Indicates which connection capacities are included in the capacity invested available of an investment group

Related Object Classes: connection, investment_group and node

TODO

connection__from_node__user_constraint

when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint

Related Object Classes: connection, node and user_constraint

Related Parameters: connection_flow_coefficient

TODO

connection__investment_group

Indicates that a connection belongs in an investment_group.

Related Object Classes: connection and investment_group

TODO

connection__investment_stochastic_structure

Defines the stochastic structure of the connections investments variable

Related Object Classes: connection and stochastic_structure

The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.

The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

connection__investment_temporal_block

Defines the temporal resolution of the connections investments variable

Related Object Classes: connection and temporal_block

connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.

See also Investment Optimization

connection__node__node

Holds parameters spanning multiple connection_flow variables to and from multiple nodes.

Related Object Classes: connection and node

Related Parameters: compression_factor, connection_flow_delay, connection_linepack_constant, fix_ratio_out_in_connection_flow, fixed_pressure_constant_0, fixed_pressure_constant_1, max_ratio_out_in_connection_flow and min_ratio_out_in_connection_flow

connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1

connection__to_node

Defines the nodes the connection can output to, and holds most connection_flow variable specific parameters.

Related Object Classes: connection and node

Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow

connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

connection__to_node__investment_group

Indicates which connection capacities are included in the capacity invested available of an investment group

Related Object Classes: connection, investment_group and node

TODO

connection__to_node__user_constraint

when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint

Related Object Classes: connection, node and user_constraint

Related Parameters: connection_flow_coefficient

TODO

connection__user_constraint

Relationship required to involve a connections investment variables in a user_constraint

Related Object Classes: connection and user_constraint

Related Parameters: connections_invested_available_coefficient and connections_invested_coefficient

TODO

model__default_investment_stochastic_structure

Defines the default stochastic structure used for investment variables, which will be replaced by more specific definitions

Related Object Classes: model and stochastic_structure

The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.

model__default_investment_temporal_block

Defines the default temporal block used for investment variables, which will be replaced by more specific definitions

Related Object Classes: model and temporal_block

model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.

See also Investment Optimization

model__default_stochastic_structure

Defines the default stochastic structure used for model variables, which will be replaced by more specific definitions

Related Object Classes: model and stochastic_structure

The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.

model__default_temporal_block

Defines the default temporal block used for model variables, which will be replaced by more specific definitions

Related Object Classes: model and temporal_block

The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.

model__report

Determines which reports are written for each model and in turn, which outputs are written for each model

Related Object Classes: model and report

The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!

model__stochastic_structure

Defines which stochastic_structures are included in which models.

Related Object Classes: model and stochastic_structure

The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.

model__temporal_block

Defines which temporal_blocks are included in which models.

Related Object Classes: model and temporal_block

The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.

node__commodity

Define a commodity for a node. Only a single commodity is permitted per node

Related Object Classes: commodity and node

node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:

  1. To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow
  2. Only connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.

node__investment_group

Indicates that a node belongs in a investment_group.

Related Object Classes: investment_group and node

TODO

node__investment_stochastic_structure

defines the stochastic structure for node related investments, currently only storages

Related Object Classes: node and stochastic_structure

The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.

The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

node__investment_temporal_block

defines the temporal resolution for node related investments, currently only storages

Related Object Classes: node and temporal_block

node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.

See also Investment Optimization

node__node

Holds parameters for direct interactions between two nodes, e.g. node_state diffusion coefficients.

Related Object Classes: node

Related Parameters: diff_coeff

The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that

node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).

Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.

node__stochastic_structure

Defines which specific stochastic_structure is used by the node and all flow variables associated with it. Only one stochastic_structure is permitted per node.

Related Object Classes: node and stochastic_structure

Related Parameters: is_active

The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.

The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

node__temporal_block

Defines the temporal_blocks used by the node and all the flow variables associated with it.

Related Object Classes: node and temporal_block

Related Parameters: cyclic_condition and is_active

This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.

For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.

node__user_constraint

specifying this relationship allows a node's demand or node_state to be included in the specified user constraint

Related Object Classes: node and user_constraint

Related Parameters: demand_coefficient, node_state_coefficient, storages_invested_available_coefficient and storages_invested_coefficient

TODO

parent_stochastic_scenario__child_stochastic_scenario

Defines the master stochastic direct acyclic graph, meaning how the stochastic_scenarios are related to each other.

Related Object Classes: stochastic_scenario

The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.

The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.

report__output

Output object related to a report object are returned to the output database (if they appear in the model as variables)

Related Object Classes: output and report

Related Parameters: overwrite_results_on_rolling

The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!

stochastic_structure__stochastic_scenario

Defines which stochastic_scenarios are included in which stochastic_structure, and holds the parameters required for realizing the structure in combination with the temporal_blocks.

Related Object Classes: stochastic_scenario and stochastic_structure

Related Parameters: stochastic_scenario_end and weight_relative_to_parents

The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.

unit__commodity

Holds parameters for commodities used by the unit.

Related Object Classes: commodity and unit

Related Parameters: max_cum_in_unit_flow_bound

To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.

Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.

unit__from_node

Defines the nodes the unit can take input from, and holds most unit_flow variable specific parameters.

Related Object Classes: node and unit

Related Parameters: fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.

It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

unit__from_node__investment_group

Indicates which unit capacities are included in the capacity invested available of an investment group

Related Object Classes: investment_group, node and unit

TODO

unit__from_node__user_constraint

Defines which input unit_flows are included in the user_constraint, and holds their parameters.

Related Object Classes: node, unit and user_constraint

Related Parameters: graph_view_position and unit_flow_coefficient

TODO

unit__investment_group

Indicates that a unit belongs in an investment_group.

Related Object Classes: investment_group and unit

TODO

unit__investment_stochastic_structure

Sets the stochastic structure for investment decisions - overrides model__default_investment_stochastic_structure.

Related Object Classes: stochastic_structure and unit

The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.

The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

unit__investment_temporal_block

Sets the temporal resolution of investment decisions - overrides model__default_investment_temporal_block

Related Object Classes: temporal_block and unit

unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.

See also Investment Optimization

unit__node__node

Holds parameters spanning multiple unit_flow variables to and from multiple nodes.

Related Object Classes: node and unit

Related Parameters: fix_ratio_in_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_out_in_unit_flow, fix_ratio_out_out_unit_flow, fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, fix_units_on_coefficient_out_out, max_ratio_in_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_out_in_unit_flow, max_ratio_out_out_unit_flow, max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, max_units_on_coefficient_out_out, min_ratio_in_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_out_in_unit_flow, min_ratio_out_out_unit_flow, min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, min_units_on_coefficient_out_out, unit_idle_heat_rate, unit_incremental_heat_rate and unit_start_flow

While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.

In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.

unit__to_node

Defines the nodes the unit can output to, and holds most unit_flow variable specific parameters.

Related Object Classes: node and unit

Related Parameters: fix_nonspin_units_shut_down, fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_shut_down, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.

It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

unit__to_node__investment_group

Indicates which unit capacities are included in the capacity invested available of an investment group

Related Object Classes: investment_group, node and unit

TODO

unit__to_node__user_constraint

Defines which output unit_flows are included in the user_constraint, and holds their parameters.

Related Object Classes: node, unit and user_constraint

Related Parameters: graph_view_position and unit_flow_coefficient

TODO

unit__user_constraint

Defines which units_on variables are included in the user_constraint, and holds their parameters.

Related Object Classes: unit and user_constraint

Related Parameters: units_invested_available_coefficient, units_invested_coefficient, units_on_coefficient and units_started_up_coefficient

TODO

units_on__stochastic_structure

Defines which specific stochastic_structure is used for the units_on variable of the unit. Only one stochastic_structure is permitted per unit.

Related Object Classes: stochastic_structure and unit

Related Parameters: is_active

The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.

The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

units_on__temporal_block

Defines which specific temporal_blocks are used by the units_on variable of the unit.

Related Object Classes: temporal_block and unit

Related Parameters: is_active

units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

+Relationship Classes · SpineOpt.jl

Relationship Classes

connection__from_node

Defines the nodes the connection can take input from, and holds most connection_flow variable specific parameters.

Related Object Classes: connection and node

Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow

connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

connection__from_node__investment_group

Indicates which connection capacities are included in the capacity invested available of an investment group

Related Object Classes: connection, investment_group and node

TODO

connection__from_node__user_constraint

when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint

Related Object Classes: connection, node and user_constraint

Related Parameters: connection_flow_coefficient

TODO

connection__investment_group

Indicates that a connection belongs in an investment_group.

Related Object Classes: connection and investment_group

TODO

connection__investment_stochastic_structure

Defines the stochastic structure of the connections investments variable

Related Object Classes: connection and stochastic_structure

The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.

The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

connection__investment_temporal_block

Defines the temporal resolution of the connections investments variable

Related Object Classes: connection and temporal_block

connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.

See also Investment Optimization

connection__node__node

Holds parameters spanning multiple connection_flow variables to and from multiple nodes.

Related Object Classes: connection and node

Related Parameters: compression_factor, connection_flow_delay, connection_linepack_constant, fix_ratio_out_in_connection_flow, fixed_pressure_constant_0, fixed_pressure_constant_1, max_ratio_out_in_connection_flow and min_ratio_out_in_connection_flow

connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1

connection__to_node

Defines the nodes the connection can output to, and holds most connection_flow variable specific parameters.

Related Object Classes: connection and node

Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow

connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

connection__to_node__investment_group

Indicates which connection capacities are included in the capacity invested available of an investment group

Related Object Classes: connection, investment_group and node

TODO

connection__to_node__user_constraint

when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint

Related Object Classes: connection, node and user_constraint

Related Parameters: connection_flow_coefficient

TODO

connection__user_constraint

Relationship required to involve a connections investment variables in a user_constraint

Related Object Classes: connection and user_constraint

Related Parameters: connections_invested_available_coefficient and connections_invested_coefficient

TODO

model__default_investment_stochastic_structure

Defines the default stochastic structure used for investment variables, which will be replaced by more specific definitions

Related Object Classes: model and stochastic_structure

The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.

model__default_investment_temporal_block

Defines the default temporal block used for investment variables, which will be replaced by more specific definitions

Related Object Classes: model and temporal_block

model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.

See also Investment Optimization

model__default_stochastic_structure

Defines the default stochastic structure used for model variables, which will be replaced by more specific definitions

Related Object Classes: model and stochastic_structure

The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.

model__default_temporal_block

Defines the default temporal block used for model variables, which will be replaced by more specific definitions

Related Object Classes: model and temporal_block

The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.

model__report

Determines which reports are written for each model and in turn, which outputs are written for each model

Related Object Classes: model and report

The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!

model__stochastic_structure

Defines which stochastic_structures are included in which models.

Related Object Classes: model and stochastic_structure

The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.

model__temporal_block

Defines which temporal_blocks are included in which models.

Related Object Classes: model and temporal_block

The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.

node__commodity

Define a commodity for a node. Only a single commodity is permitted per node

Related Object Classes: commodity and node

node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:

  1. To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow
  2. Only connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.

node__investment_group

Indicates that a node belongs in a investment_group.

Related Object Classes: investment_group and node

TODO

node__investment_stochastic_structure

defines the stochastic structure for node related investments, currently only storages

Related Object Classes: node and stochastic_structure

The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.

The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

node__investment_temporal_block

defines the temporal resolution for node related investments, currently only storages

Related Object Classes: node and temporal_block

node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.

See also Investment Optimization

node__node

Holds parameters for direct interactions between two nodes, e.g. node_state diffusion coefficients.

Related Object Classes: node

Related Parameters: diff_coeff

The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that

node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).

Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.

node__stochastic_structure

Defines which specific stochastic_structure is used by the node and all flow variables associated with it. Only one stochastic_structure is permitted per node.

Related Object Classes: node and stochastic_structure

Related Parameters: is_active

The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.

The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

node__temporal_block

Defines the temporal_blocks used by the node and all the flow variables associated with it.

Related Object Classes: node and temporal_block

Related Parameters: cyclic_condition and is_active

This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.

For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.

node__user_constraint

specifying this relationship allows a node's demand or node_state to be included in the specified user constraint

Related Object Classes: node and user_constraint

Related Parameters: demand_coefficient, node_state_coefficient, storages_invested_available_coefficient and storages_invested_coefficient

TODO

parent_stochastic_scenario__child_stochastic_scenario

Defines the master stochastic direct acyclic graph, meaning how the stochastic_scenarios are related to each other.

Related Object Classes: stochastic_scenario

The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.

The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.

report__output

Output object related to a report object are returned to the output database (if they appear in the model as variables)

Related Object Classes: output and report

Related Parameters: overwrite_results_on_rolling

The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!

stochastic_structure__stochastic_scenario

Defines which stochastic_scenarios are included in which stochastic_structure, and holds the parameters required for realizing the structure in combination with the temporal_blocks.

Related Object Classes: stochastic_scenario and stochastic_structure

Related Parameters: stochastic_scenario_end and weight_relative_to_parents

The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.

unit__commodity

Holds parameters for commodities used by the unit.

Related Object Classes: commodity and unit

Related Parameters: max_cum_in_unit_flow_bound

To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.

Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.

unit__from_node

Defines the nodes the unit can take input from, and holds most unit_flow variable specific parameters.

Related Object Classes: node and unit

Related Parameters: fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.

It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

unit__from_node__investment_group

Indicates which unit capacities are included in the capacity invested available of an investment group

Related Object Classes: investment_group, node and unit

TODO

unit__from_node__user_constraint

Defines which input unit_flows are included in the user_constraint, and holds their parameters.

Related Object Classes: node, unit and user_constraint

Related Parameters: graph_view_position and unit_flow_coefficient

TODO

unit__investment_group

Indicates that a unit belongs in an investment_group.

Related Object Classes: investment_group and unit

TODO

unit__investment_stochastic_structure

Sets the stochastic structure for investment decisions - overrides model__default_investment_stochastic_structure.

Related Object Classes: stochastic_structure and unit

The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.

The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.

unit__investment_temporal_block

Sets the temporal resolution of investment decisions - overrides model__default_investment_temporal_block

Related Object Classes: temporal_block and unit

unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.

See also Investment Optimization

unit__node__node

Holds parameters spanning multiple unit_flow variables to and from multiple nodes.

Related Object Classes: node and unit

Related Parameters: fix_ratio_in_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_out_in_unit_flow, fix_ratio_out_out_unit_flow, fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, fix_units_on_coefficient_out_out, max_ratio_in_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_out_in_unit_flow, max_ratio_out_out_unit_flow, max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, max_units_on_coefficient_out_out, min_ratio_in_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_out_in_unit_flow, min_ratio_out_out_unit_flow, min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, min_units_on_coefficient_out_out, unit_idle_heat_rate, unit_incremental_heat_rate and unit_start_flow

While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.

In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.

unit__to_node

Defines the nodes the unit can output to, and holds most unit_flow variable specific parameters.

Related Object Classes: node and unit

Related Parameters: fix_nonspin_units_shut_down, fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_shut_down, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.

It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

unit__to_node__investment_group

Indicates which unit capacities are included in the capacity invested available of an investment group

Related Object Classes: investment_group, node and unit

TODO

unit__to_node__user_constraint

Defines which output unit_flows are included in the user_constraint, and holds their parameters.

Related Object Classes: node, unit and user_constraint

Related Parameters: graph_view_position and unit_flow_coefficient

TODO

unit__user_constraint

Defines which units_on variables are included in the user_constraint, and holds their parameters.

Related Object Classes: unit and user_constraint

Related Parameters: units_invested_available_coefficient, units_invested_coefficient, units_on_coefficient and units_started_up_coefficient

TODO

units_on__stochastic_structure

Defines which specific stochastic_structure is used for the units_on variable of the unit. Only one stochastic_structure is permitted per unit.

Related Object Classes: stochastic_structure and unit

Related Parameters: is_active

The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.

The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

units_on__temporal_block

Defines which specific temporal_blocks are used by the units_on variable of the unit.

Related Object Classes: temporal_block and unit

Related Parameters: is_active

units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

diff --git a/dev/concept_reference/_example/index.html b/dev/concept_reference/_example/index.html index 590dcaa588..b2490c450d 100644 --- a/dev/concept_reference/_example/index.html +++ b/dev/concept_reference/_example/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

AN EXAMPLE DESCRIPTION FOR HOW THE AUTOGENERATION OF CONCEPT REFERENCE BASED ON SPINEOPT TEMPLATE WORKS

References to other sections, e.g. node are handled like this. Don't use the grave accents around the reference name, as it breaks the reference! Grave accents in Documenter.jl refer to docstrings in the code instead of sections in the documentation.

+- · SpineOpt.jl

AN EXAMPLE DESCRIPTION FOR HOW THE AUTOGENERATION OF CONCEPT REFERENCE BASED ON SPINEOPT TEMPLATE WORKS

References to other sections, e.g. node are handled like this. Don't use the grave accents around the reference name, as it breaks the reference! Grave accents in Documenter.jl refer to docstrings in the code instead of sections in the documentation.

diff --git a/dev/concept_reference/balance_type/index.html b/dev/concept_reference/balance_type/index.html index 1b8dd99169..9c2f9e8166 100644 --- a/dev/concept_reference/balance_type/index.html +++ b/dev/concept_reference/balance_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.

The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.

+- · SpineOpt.jl

The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.

The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.

diff --git a/dev/concept_reference/balance_type_list/index.html b/dev/concept_reference/balance_type_list/index.html index e1917ff9c7..61b59cbebc 100644 --- a/dev/concept_reference/balance_type_list/index.html +++ b/dev/concept_reference/balance_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/big_m/index.html b/dev/concept_reference/big_m/index.html index ef67d55126..66c7435711 100644 --- a/dev/concept_reference/big_m/index.html +++ b/dev/concept_reference/big_m/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.

+- · SpineOpt.jl

The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.

diff --git a/dev/concept_reference/block_end/index.html b/dev/concept_reference/block_end/index.html index c8d27dc865..57d3c424b1 100644 --- a/dev/concept_reference/block_end/index.html +++ b/dev/concept_reference/block_end/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.

single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.

rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.

+- · SpineOpt.jl

Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.

single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.

rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.

diff --git a/dev/concept_reference/block_start/index.html b/dev/concept_reference/block_start/index.html index 7c0f61a1d0..96bcc4021e 100644 --- a/dev/concept_reference/block_start/index.html +++ b/dev/concept_reference/block_start/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.

single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.

rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.

+- · SpineOpt.jl

Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.

single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.

rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.

diff --git a/dev/concept_reference/boolean_value_list/index.html b/dev/concept_reference/boolean_value_list/index.html index f49bd360ae..f06cd7473a 100644 --- a/dev/concept_reference/boolean_value_list/index.html +++ b/dev/concept_reference/boolean_value_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A list of boolean values (True or False).

+- · SpineOpt.jl

A list of boolean values (True or False).

diff --git a/dev/concept_reference/candidate_connections/index.html b/dev/concept_reference/candidate_connections/index.html index 6b91869830..94012070dd 100644 --- a/dev/concept_reference/candidate_connections/index.html +++ b/dev/concept_reference/candidate_connections/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/candidate_storages/index.html b/dev/concept_reference/candidate_storages/index.html index 0d4a1af7ec..422b2aec09 100644 --- a/dev/concept_reference/candidate_storages/index.html +++ b/dev/concept_reference/candidate_storages/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.

Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.

See also Investment Optimization and storage_investment_variable_type

+- · SpineOpt.jl

Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.

Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.

See also Investment Optimization and storage_investment_variable_type

diff --git a/dev/concept_reference/candidate_units/index.html b/dev/concept_reference/candidate_units/index.html index 0f8c691989..5ef1082a5e 100644 --- a/dev/concept_reference/candidate_units/index.html +++ b/dev/concept_reference/candidate_units/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.

Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.

See also Investment Optimization and unit_investment_variable_type

+- · SpineOpt.jl

Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.

Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.

See also Investment Optimization and unit_investment_variable_type

diff --git a/dev/concept_reference/commodity/index.html b/dev/concept_reference/commodity/index.html index 16ef092fe2..58270e6465 100644 --- a/dev/concept_reference/commodity/index.html +++ b/dev/concept_reference/commodity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)

+- · SpineOpt.jl

Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)

diff --git a/dev/concept_reference/commodity_lodf_tolerance/index.html b/dev/concept_reference/commodity_lodf_tolerance/index.html index 81d7563764..be0893aaa1 100644 --- a/dev/concept_reference/commodity_lodf_tolerance/index.html +++ b/dev/concept_reference/commodity_lodf_tolerance/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.

The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.

In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).

+- · SpineOpt.jl

Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.

The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.

In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).

diff --git a/dev/concept_reference/commodity_physics/index.html b/dev/concept_reference/commodity_physics/index.html index 21970060e8..c869e4df56 100644 --- a/dev/concept_reference/commodity_physics/index.html +++ b/dev/concept_reference/commodity_physics/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.

See also powerflow

+- · SpineOpt.jl

This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.

See also powerflow

diff --git a/dev/concept_reference/commodity_physics_duration/index.html b/dev/concept_reference/commodity_physics_duration/index.html index 26b84f231d..5aabefedc1 100644 --- a/dev/concept_reference/commodity_physics_duration/index.html +++ b/dev/concept_reference/commodity_physics_duration/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.

See also powerflow

+- · SpineOpt.jl

This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.

See also powerflow

diff --git a/dev/concept_reference/commodity_physics_list/index.html b/dev/concept_reference/commodity_physics_list/index.html index 5adc93375b..a6dc80820e 100644 --- a/dev/concept_reference/commodity_physics_list/index.html +++ b/dev/concept_reference/commodity_physics_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/commodity_ptdf_threshold/index.html b/dev/concept_reference/commodity_ptdf_threshold/index.html index abfca60b9e..b1ffb8d507 100644 --- a/dev/concept_reference/commodity_ptdf_threshold/index.html +++ b/dev/concept_reference/commodity_ptdf_threshold/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.

The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.

In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).

+- · SpineOpt.jl

Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.

The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.

In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).

diff --git a/dev/concept_reference/compression_factor/index.html b/dev/concept_reference/compression_factor/index.html index 8f82ce906d..536687018f 100644 --- a/dev/concept_reference/compression_factor/index.html +++ b/dev/concept_reference/compression_factor/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.

+- · SpineOpt.jl

This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.

diff --git a/dev/concept_reference/connection/index.html b/dev/concept_reference/connection/index.html index a0aebd45a4..d15c65c4f2 100644 --- a/dev/concept_reference/connection/index.html +++ b/dev/concept_reference/connection/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.

A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.

+- · SpineOpt.jl

A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.

A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.

diff --git a/dev/concept_reference/connection__from_node/index.html b/dev/concept_reference/connection__from_node/index.html index 6f4b07500f..52c2211a87 100644 --- a/dev/concept_reference/connection__from_node/index.html +++ b/dev/concept_reference/connection__from_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

+- · SpineOpt.jl

connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

diff --git a/dev/concept_reference/connection__from_node__unit_constraint/index.html b/dev/concept_reference/connection__from_node__unit_constraint/index.html index b3b530e07a..db39ade402 100644 --- a/dev/concept_reference/connection__from_node__unit_constraint/index.html +++ b/dev/concept_reference/connection__from_node__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__from_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable to the specified connection from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__from_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint

+- · SpineOpt.jl

connection__from_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable to the specified connection from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__from_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint

diff --git a/dev/concept_reference/connection__investment_stochastic_structure/index.html b/dev/concept_reference/connection__investment_stochastic_structure/index.html index 11479fb6c6..390731d2b9 100644 --- a/dev/concept_reference/connection__investment_stochastic_structure/index.html +++ b/dev/concept_reference/connection__investment_stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection__investment_temporal_block/index.html b/dev/concept_reference/connection__investment_temporal_block/index.html index 7d71be432b..6cf443383f 100644 --- a/dev/concept_reference/connection__investment_temporal_block/index.html +++ b/dev/concept_reference/connection__investment_temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.

See also Investment Optimization

+- · SpineOpt.jl

connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.

See also Investment Optimization

diff --git a/dev/concept_reference/connection__node__node/index.html b/dev/concept_reference/connection__node__node/index.html index 05a9642608..2a20c0880d 100644 --- a/dev/concept_reference/connection__node__node/index.html +++ b/dev/concept_reference/connection__node__node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1

+- · SpineOpt.jl

connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1

diff --git a/dev/concept_reference/connection__to_node/index.html b/dev/concept_reference/connection__to_node/index.html index 2960e3ea8d..204362e17e 100644 --- a/dev/concept_reference/connection__to_node/index.html +++ b/dev/concept_reference/connection__to_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

+- · SpineOpt.jl

connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.

diff --git a/dev/concept_reference/connection__to_node__unit_constraint/index.html b/dev/concept_reference/connection__to_node__unit_constraint/index.html index 8ce03c227d..674ade3666 100644 --- a/dev/concept_reference/connection__to_node__unit_constraint/index.html +++ b/dev/concept_reference/connection__to_node__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection__to_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable from the specified connection to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__to_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint

+- · SpineOpt.jl

connection__to_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable from the specified connection to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__to_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint

diff --git a/dev/concept_reference/connection_availability_factor/index.html b/dev/concept_reference/connection_availability_factor/index.html index 29e0568567..1d69d2ae25 100644 --- a/dev/concept_reference/connection_availability_factor/index.html +++ b/dev/concept_reference/connection_availability_factor/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.

+- · SpineOpt.jl

To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.

diff --git a/dev/concept_reference/connection_capacity/index.html b/dev/concept_reference/connection_capacity/index.html index 4393a14624..53fba46b02 100644 --- a/dev/concept_reference/connection_capacity/index.html +++ b/dev/concept_reference/connection_capacity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.

+- · SpineOpt.jl

Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.

diff --git a/dev/concept_reference/connection_contingency/index.html b/dev/concept_reference/connection_contingency/index.html index cd57dd5cb5..b1217aa599 100644 --- a/dev/concept_reference/connection_contingency/index.html +++ b/dev/concept_reference/connection_contingency/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).

See also powerflow

+- · SpineOpt.jl

Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).

See also powerflow

diff --git a/dev/concept_reference/connection_conv_cap_to_flow/index.html b/dev/concept_reference/connection_conv_cap_to_flow/index.html index be97236da4..6bfe7116e0 100644 --- a/dev/concept_reference/connection_conv_cap_to_flow/index.html +++ b/dev/concept_reference/connection_conv_cap_to_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_emergency_capacity/index.html b/dev/concept_reference/connection_emergency_capacity/index.html index a857510d2d..69074ce67a 100644 --- a/dev/concept_reference/connection_emergency_capacity/index.html +++ b/dev/concept_reference/connection_emergency_capacity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_flow_coefficient/index.html b/dev/concept_reference/connection_flow_coefficient/index.html index de1a1b4df5..fe64c67717 100644 --- a/dev/concept_reference/connection_flow_coefficient/index.html +++ b/dev/concept_reference/connection_flow_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_flow_cost/index.html b/dev/concept_reference/connection_flow_cost/index.html index 77d6b0ec9d..b3a2cfc737 100644 --- a/dev/concept_reference/connection_flow_cost/index.html +++ b/dev/concept_reference/connection_flow_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.

+- · SpineOpt.jl

By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.

diff --git a/dev/concept_reference/connection_flow_delay/index.html b/dev/concept_reference/connection_flow_delay/index.html index 5159dd0926..b64e8ba377 100644 --- a/dev/concept_reference/connection_flow_delay/index.html +++ b/dev/concept_reference/connection_flow_delay/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_investment_cost/index.html b/dev/concept_reference/connection_investment_cost/index.html index 523f9a1512..a6b0f110d8 100644 --- a/dev/concept_reference/connection_investment_cost/index.html +++ b/dev/concept_reference/connection_investment_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.

+- · SpineOpt.jl

By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.

diff --git a/dev/concept_reference/connection_investment_lifetime/index.html b/dev/concept_reference/connection_investment_lifetime/index.html index 842f05a8ac..73d5199524 100644 --- a/dev/concept_reference/connection_investment_lifetime/index.html +++ b/dev/concept_reference/connection_investment_lifetime/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

+- · SpineOpt.jl

connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

diff --git a/dev/concept_reference/connection_investment_variable_type/index.html b/dev/concept_reference/connection_investment_variable_type/index.html index 33012dcb66..ea8778cf45 100644 --- a/dev/concept_reference/connection_investment_variable_type/index.html +++ b/dev/concept_reference/connection_investment_variable_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.

The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.

+- · SpineOpt.jl

The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.

The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.

diff --git a/dev/concept_reference/connection_investment_variable_type_list/index.html b/dev/concept_reference/connection_investment_variable_type_list/index.html index 370ea711fa..7bd7202c46 100644 --- a/dev/concept_reference/connection_investment_variable_type_list/index.html +++ b/dev/concept_reference/connection_investment_variable_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_linepack_constant/index.html b/dev/concept_reference/connection_linepack_constant/index.html index 0159bde1af..2b8c501fdd 100644 --- a/dev/concept_reference/connection_linepack_constant/index.html +++ b/dev/concept_reference/connection_linepack_constant/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.

+- · SpineOpt.jl

The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.

diff --git a/dev/concept_reference/connection_monitored/index.html b/dev/concept_reference/connection_monitored/index.html index 9bcbb314b0..aa08428225 100644 --- a/dev/concept_reference/connection_monitored/index.html +++ b/dev/concept_reference/connection_monitored/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_reactance/index.html b/dev/concept_reference/connection_reactance/index.html index b98c4cb322..072e73d2ae 100644 --- a/dev/concept_reference/connection_reactance/index.html +++ b/dev/concept_reference/connection_reactance/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node.

+- · SpineOpt.jl

The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node.

diff --git a/dev/concept_reference/connection_reactance_base/index.html b/dev/concept_reference/connection_reactance_base/index.html index d4aa3d1dc4..da62e5604b 100644 --- a/dev/concept_reference/connection_reactance_base/index.html +++ b/dev/concept_reference/connection_reactance_base/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connection_resistance/index.html b/dev/concept_reference/connection_resistance/index.html index 83fb92d7cd..af3a1bc5a4 100644 --- a/dev/concept_reference/connection_resistance/index.html +++ b/dev/concept_reference/connection_resistance/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The per unit resistance of a transmission line. Currently unimplemented!

+- · SpineOpt.jl

The per unit resistance of a transmission line. Currently unimplemented!

diff --git a/dev/concept_reference/connection_type/index.html b/dev/concept_reference/connection_type/index.html index 8cebc2f20f..8e9aaa778b 100644 --- a/dev/concept_reference/connection_type/index.html +++ b/dev/concept_reference/connection_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:

If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:

+- · SpineOpt.jl

Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:

If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:

diff --git a/dev/concept_reference/connection_type_list/index.html b/dev/concept_reference/connection_type_list/index.html index 8865c16b9d..e648169768 100644 --- a/dev/concept_reference/connection_type_list/index.html +++ b/dev/concept_reference/connection_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connections_invested_avaiable_coefficient/index.html b/dev/concept_reference/connections_invested_avaiable_coefficient/index.html index 83b89a3904..82f505b21b 100644 --- a/dev/concept_reference/connections_invested_avaiable_coefficient/index.html +++ b/dev/concept_reference/connections_invested_avaiable_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connections_invested_big_m_mga/index.html b/dev/concept_reference/connections_invested_big_m_mga/index.html index e2789e101d..47e6d2bfc5 100644 --- a/dev/concept_reference/connections_invested_big_m_mga/index.html +++ b/dev/concept_reference/connections_invested_big_m_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)

+- · SpineOpt.jl

The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)

diff --git a/dev/concept_reference/connections_invested_coefficient/index.html b/dev/concept_reference/connections_invested_coefficient/index.html index 91143dbc7b..d76b916afd 100644 --- a/dev/concept_reference/connections_invested_coefficient/index.html +++ b/dev/concept_reference/connections_invested_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/connections_invested_mga/index.html b/dev/concept_reference/connections_invested_mga/index.html index fa7ef9423d..8a78764a4a 100644 --- a/dev/concept_reference/connections_invested_mga/index.html +++ b/dev/concept_reference/connections_invested_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/constraint_sense/index.html b/dev/concept_reference/constraint_sense/index.html index 7e1989eba0..a00bf80fc7 100644 --- a/dev/concept_reference/constraint_sense/index.html +++ b/dev/concept_reference/constraint_sense/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/constraint_sense_list/index.html b/dev/concept_reference/constraint_sense_list/index.html index 2d5623a64a..b019c28c5e 100644 --- a/dev/concept_reference/constraint_sense_list/index.html +++ b/dev/concept_reference/constraint_sense_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/curtailment_cost/index.html b/dev/concept_reference/curtailment_cost/index.html index cc9a11339e..4e9092fadf 100644 --- a/dev/concept_reference/curtailment_cost/index.html +++ b/dev/concept_reference/curtailment_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/cyclic_condition/index.html b/dev/concept_reference/cyclic_condition/index.html index 669d736870..e03d1040b3 100644 --- a/dev/concept_reference/cyclic_condition/index.html +++ b/dev/concept_reference/cyclic_condition/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/db_lp_solver/index.html b/dev/concept_reference/db_lp_solver/index.html index 4463d5c96e..fa07db7def 100644 --- a/dev/concept_reference/db_lp_solver/index.html +++ b/dev/concept_reference/db_lp_solver/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.

+- · SpineOpt.jl

Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.

diff --git a/dev/concept_reference/db_lp_solver_list/index.html b/dev/concept_reference/db_lp_solver_list/index.html index 694e021a27..aba3329e02 100644 --- a/dev/concept_reference/db_lp_solver_list/index.html +++ b/dev/concept_reference/db_lp_solver_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.

+- · SpineOpt.jl

List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.

diff --git a/dev/concept_reference/db_lp_solver_options/index.html b/dev/concept_reference/db_lp_solver_options/index.html index 47a971ab67..6b904176f6 100644 --- a/dev/concept_reference/db_lp_solver_options/index.html +++ b/dev/concept_reference/db_lp_solver_options/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. example db_lp_solver_options map parameter

+- · SpineOpt.jl

LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. example db_lp_solver_options map parameter

diff --git a/dev/concept_reference/db_mip_solver/index.html b/dev/concept_reference/db_mip_solver/index.html index e2a0e25180..a70c11a775 100644 --- a/dev/concept_reference/db_mip_solver/index.html +++ b/dev/concept_reference/db_mip_solver/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.

+- · SpineOpt.jl

Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.

diff --git a/dev/concept_reference/db_mip_solver_list/index.html b/dev/concept_reference/db_mip_solver_list/index.html index 65cd39128c..4a9f6eb449 100644 --- a/dev/concept_reference/db_mip_solver_list/index.html +++ b/dev/concept_reference/db_mip_solver_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.

+- · SpineOpt.jl

List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.

diff --git a/dev/concept_reference/db_mip_solver_options/index.html b/dev/concept_reference/db_mip_solver_options/index.html index 58e7c48638..78612cf892 100644 --- a/dev/concept_reference/db_mip_solver_options/index.html +++ b/dev/concept_reference/db_mip_solver_options/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. example db_mip_solver_options map parameter

+- · SpineOpt.jl

MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. example db_mip_solver_options map parameter

diff --git a/dev/concept_reference/demand/index.html b/dev/concept_reference/demand/index.html index 7adb9d10d4..7322d7b1cc 100644 --- a/dev/concept_reference/demand/index.html +++ b/dev/concept_reference/demand/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The demand parameter represents a "demand" or a "load" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as "demand" or "load" for the modelled system, while negative values provide the system with "influx" or "gain". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects

The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.

+- · SpineOpt.jl

The demand parameter represents a "demand" or a "load" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as "demand" or "load" for the modelled system, while negative values provide the system with "influx" or "gain". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects

The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.

diff --git a/dev/concept_reference/demand_coefficient/index.html b/dev/concept_reference/demand_coefficient/index.html index f7d5ffe1dd..4cd067ae0b 100644 --- a/dev/concept_reference/demand_coefficient/index.html +++ b/dev/concept_reference/demand_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/diff_coeff/index.html b/dev/concept_reference/diff_coeff/index.html index 977ccc46bf..9503d2083a 100644 --- a/dev/concept_reference/diff_coeff/index.html +++ b/dev/concept_reference/diff_coeff/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines

diff_coeff(node1=n1, node2=n2),

there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways

diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).
+- · SpineOpt.jl

The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines

diff_coeff(node1=n1, node2=n2),

there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways

diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).
diff --git a/dev/concept_reference/downward_reserve/index.html b/dev/concept_reference/downward_reserve/index.html index 5af63521dc..dfbe6de605 100644 --- a/dev/concept_reference/downward_reserve/index.html +++ b/dev/concept_reference/downward_reserve/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.

+- · SpineOpt.jl

If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.

diff --git a/dev/concept_reference/duration_unit/index.html b/dev/concept_reference/duration_unit/index.html index af49713255..93708cc329 100644 --- a/dev/concept_reference/duration_unit/index.html +++ b/dev/concept_reference/duration_unit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.

+- · SpineOpt.jl

The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.

diff --git a/dev/concept_reference/duration_unit_list/index.html b/dev/concept_reference/duration_unit_list/index.html index 58bac636b6..6135f65046 100644 --- a/dev/concept_reference/duration_unit_list/index.html +++ b/dev/concept_reference/duration_unit_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_binary_gas_connection_flow/index.html b/dev/concept_reference/fix_binary_gas_connection_flow/index.html index fe5ef7baf5..1463ae48de 100644 --- a/dev/concept_reference/fix_binary_gas_connection_flow/index.html +++ b/dev/concept_reference/fix_binary_gas_connection_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_connection_flow/index.html b/dev/concept_reference/fix_connection_flow/index.html index 318c0726e8..c19243ac7f 100644 --- a/dev/concept_reference/fix_connection_flow/index.html +++ b/dev/concept_reference/fix_connection_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_connection_intact_flow/index.html b/dev/concept_reference/fix_connection_intact_flow/index.html index fac18b8e9b..0620d35486 100644 --- a/dev/concept_reference/fix_connection_intact_flow/index.html +++ b/dev/concept_reference/fix_connection_intact_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_connections_invested/index.html b/dev/concept_reference/fix_connections_invested/index.html index 8f26b725fd..a3fe9c8953 100644 --- a/dev/concept_reference/fix_connections_invested/index.html +++ b/dev/concept_reference/fix_connections_invested/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_connections_invested_available/index.html b/dev/concept_reference/fix_connections_invested_available/index.html index 1ccd2859b3..44a51df065 100644 --- a/dev/concept_reference/fix_connections_invested_available/index.html +++ b/dev/concept_reference/fix_connections_invested_available/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_node_pressure/index.html b/dev/concept_reference/fix_node_pressure/index.html index 4204129fe3..3716ca92ae 100644 --- a/dev/concept_reference/fix_node_pressure/index.html +++ b/dev/concept_reference/fix_node_pressure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.

+- · SpineOpt.jl

In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.

diff --git a/dev/concept_reference/fix_node_state/index.html b/dev/concept_reference/fix_node_state/index.html index e1d698f811..4923e80a28 100644 --- a/dev/concept_reference/fix_node_state/index.html +++ b/dev/concept_reference/fix_node_state/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.

+- · SpineOpt.jl

The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.

diff --git a/dev/concept_reference/fix_node_voltage_angle/index.html b/dev/concept_reference/fix_node_voltage_angle/index.html index e39fe9f8e0..7223ea5d3f 100644 --- a/dev/concept_reference/fix_node_voltage_angle/index.html +++ b/dev/concept_reference/fix_node_voltage_angle/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.

+- · SpineOpt.jl

For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.

diff --git a/dev/concept_reference/fix_nonspin_units_shut_down/index.html b/dev/concept_reference/fix_nonspin_units_shut_down/index.html index ed062bd063..f9a08da6ae 100644 --- a/dev/concept_reference/fix_nonspin_units_shut_down/index.html +++ b/dev/concept_reference/fix_nonspin_units_shut_down/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.

When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

+- · SpineOpt.jl

The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.

When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

diff --git a/dev/concept_reference/fix_nonspin_units_started_up/index.html b/dev/concept_reference/fix_nonspin_units_started_up/index.html index 6264cbefb4..d9c694b712 100644 --- a/dev/concept_reference/fix_nonspin_units_started_up/index.html +++ b/dev/concept_reference/fix_nonspin_units_started_up/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.

When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

+- · SpineOpt.jl

The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.

When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

diff --git a/dev/concept_reference/fix_ratio_in_in_unit_flow/index.html b/dev/concept_reference/fix_ratio_in_in_unit_flow/index.html index 0dee98ae1f..81021b645f 100644 --- a/dev/concept_reference/fix_ratio_in_in_unit_flow/index.html +++ b/dev/concept_reference/fix_ratio_in_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.

+- · SpineOpt.jl

The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.

diff --git a/dev/concept_reference/fix_ratio_in_out_unit_flow/index.html b/dev/concept_reference/fix_ratio_in_out_unit_flow/index.html index 5c66fab312..74cc7b9bc0 100644 --- a/dev/concept_reference/fix_ratio_in_out_unit_flow/index.html +++ b/dev/concept_reference/fix_ratio_in_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.

To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

+- · SpineOpt.jl

The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.

To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

diff --git a/dev/concept_reference/fix_ratio_out_in_connection_flow/index.html b/dev/concept_reference/fix_ratio_out_in_connection_flow/index.html index 16ba0c43a8..ff39b0dba6 100644 --- a/dev/concept_reference/fix_ratio_out_in_connection_flow/index.html +++ b/dev/concept_reference/fix_ratio_out_in_connection_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.

To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.

+- · SpineOpt.jl

The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.

To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.

diff --git a/dev/concept_reference/fix_ratio_out_in_unit_flow/index.html b/dev/concept_reference/fix_ratio_out_in_unit_flow/index.html index d48326a319..e484dcce70 100644 --- a/dev/concept_reference/fix_ratio_out_in_unit_flow/index.html +++ b/dev/concept_reference/fix_ratio_out_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.

To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

+- · SpineOpt.jl

The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.

To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

diff --git a/dev/concept_reference/fix_ratio_out_out_unit_flow/index.html b/dev/concept_reference/fix_ratio_out_out_unit_flow/index.html index fc7a1e13ed..e052d8914b 100644 --- a/dev/concept_reference/fix_ratio_out_out_unit_flow/index.html +++ b/dev/concept_reference/fix_ratio_out_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

+- · SpineOpt.jl

The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

diff --git a/dev/concept_reference/fix_storages_invested/index.html b/dev/concept_reference/fix_storages_invested/index.html index fa10f0dd7d..78a289c94b 100644 --- a/dev/concept_reference/fix_storages_invested/index.html +++ b/dev/concept_reference/fix_storages_invested/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_storages_invested_available/index.html b/dev/concept_reference/fix_storages_invested_available/index.html index 6c02ab352b..7da4bce1e5 100644 --- a/dev/concept_reference/fix_storages_invested_available/index.html +++ b/dev/concept_reference/fix_storages_invested_available/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.

See also candidate_storages and Investment Optimization

+- · SpineOpt.jl

Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.

See also candidate_storages and Investment Optimization

diff --git a/dev/concept_reference/fix_unit_flow/index.html b/dev/concept_reference/fix_unit_flow/index.html index e6c4871a8e..50df8f6ec3 100644 --- a/dev/concept_reference/fix_unit_flow/index.html +++ b/dev/concept_reference/fix_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.

Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.

Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.

+- · SpineOpt.jl

The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.

Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.

Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.

diff --git a/dev/concept_reference/fix_unit_flow_op/index.html b/dev/concept_reference/fix_unit_flow_op/index.html index cf02b897ab..16779972e4 100644 --- a/dev/concept_reference/fix_unit_flow_op/index.html +++ b/dev/concept_reference/fix_unit_flow_op/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.

+- · SpineOpt.jl

If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.

diff --git a/dev/concept_reference/fix_units_invested/index.html b/dev/concept_reference/fix_units_invested/index.html index e573b5c018..d13a29c176 100644 --- a/dev/concept_reference/fix_units_invested/index.html +++ b/dev/concept_reference/fix_units_invested/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fix_units_invested_available/index.html b/dev/concept_reference/fix_units_invested_available/index.html index 849f4029d7..e3d69faaf7 100644 --- a/dev/concept_reference/fix_units_invested_available/index.html +++ b/dev/concept_reference/fix_units_invested_available/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.

See also Investment Optimization, candidate_units and unit_investment_variable_type

+- · SpineOpt.jl

Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.

See also Investment Optimization, candidate_units and unit_investment_variable_type

diff --git a/dev/concept_reference/fix_units_on/index.html b/dev/concept_reference/fix_units_on/index.html index f8f1a7d573..20df5f1c46 100644 --- a/dev/concept_reference/fix_units_on/index.html +++ b/dev/concept_reference/fix_units_on/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

+- · SpineOpt.jl

The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.

diff --git a/dev/concept_reference/fix_units_on_coefficient_in_in/index.html b/dev/concept_reference/fix_units_on_coefficient_in_in/index.html index 69bb7186c7..534bea93b5 100644 --- a/dev/concept_reference/fix_units_on_coefficient_in_in/index.html +++ b/dev/concept_reference/fix_units_on_coefficient_in_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.

+- · SpineOpt.jl

The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.

diff --git a/dev/concept_reference/fix_units_on_coefficient_in_out/index.html b/dev/concept_reference/fix_units_on_coefficient_in_out/index.html index f61c62ce76..e767c48c7a 100644 --- a/dev/concept_reference/fix_units_on_coefficient_in_out/index.html +++ b/dev/concept_reference/fix_units_on_coefficient_in_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.

+- · SpineOpt.jl

The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.

diff --git a/dev/concept_reference/fix_units_on_coefficient_out_in/index.html b/dev/concept_reference/fix_units_on_coefficient_out_in/index.html index b836d691aa..9cd711d0a5 100644 --- a/dev/concept_reference/fix_units_on_coefficient_out_in/index.html +++ b/dev/concept_reference/fix_units_on_coefficient_out_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.

+- · SpineOpt.jl

The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.

diff --git a/dev/concept_reference/fix_units_on_coefficient_out_out/index.html b/dev/concept_reference/fix_units_on_coefficient_out_out/index.html index a51e69405c..fcfdf6a3a5 100644 --- a/dev/concept_reference/fix_units_on_coefficient_out_out/index.html +++ b/dev/concept_reference/fix_units_on_coefficient_out_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.

+- · SpineOpt.jl

The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.

diff --git a/dev/concept_reference/fixed_pressure_constant_0/index.html b/dev/concept_reference/fixed_pressure_constant_0/index.html index 5ef0b2245c..ffddf142b9 100644 --- a/dev/concept_reference/fixed_pressure_constant_0/index.html +++ b/dev/concept_reference/fixed_pressure_constant_0/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.

+- · SpineOpt.jl

For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.

diff --git a/dev/concept_reference/fixed_pressure_constant_1/index.html b/dev/concept_reference/fixed_pressure_constant_1/index.html index c5e5716810..3279a1814f 100644 --- a/dev/concept_reference/fixed_pressure_constant_1/index.html +++ b/dev/concept_reference/fixed_pressure_constant_1/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.

+- · SpineOpt.jl

For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.

diff --git a/dev/concept_reference/fom_cost/index.html b/dev/concept_reference/fom_cost/index.html index 3dfb9d7179..33b8dad5ad 100644 --- a/dev/concept_reference/fom_cost/index.html +++ b/dev/concept_reference/fom_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.

+- · SpineOpt.jl

By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.

diff --git a/dev/concept_reference/frac_state_loss/index.html b/dev/concept_reference/frac_state_loss/index.html index e40e1bbaff..b019005adf 100644 --- a/dev/concept_reference/frac_state_loss/index.html +++ b/dev/concept_reference/frac_state_loss/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.

+- · SpineOpt.jl

The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.

diff --git a/dev/concept_reference/fractional_demand/index.html b/dev/concept_reference/fractional_demand/index.html index db84793d19..41aa1946ab 100644 --- a/dev/concept_reference/fractional_demand/index.html +++ b/dev/concept_reference/fractional_demand/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/fuel_cost/index.html b/dev/concept_reference/fuel_cost/index.html index 545c1e023f..425e8bdebb 100644 --- a/dev/concept_reference/fuel_cost/index.html +++ b/dev/concept_reference/fuel_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/graph_view_position/index.html b/dev/concept_reference/graph_view_position/index.html index 7a36eaf46d..b7f29d014f 100644 --- a/dev/concept_reference/graph_view_position/index.html +++ b/dev/concept_reference/graph_view_position/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.

+- · SpineOpt.jl

The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.

diff --git a/dev/concept_reference/has_binary_gas_flow/index.html b/dev/concept_reference/has_binary_gas_flow/index.html index 363630e5ae..7ff64c812b 100644 --- a/dev/concept_reference/has_binary_gas_flow/index.html +++ b/dev/concept_reference/has_binary_gas_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.

+- · SpineOpt.jl

This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.

diff --git a/dev/concept_reference/has_pressure/index.html b/dev/concept_reference/has_pressure/index.html index 61807ca78a..61b1f9c194 100644 --- a/dev/concept_reference/has_pressure/index.html +++ b/dev/concept_reference/has_pressure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here

+- · SpineOpt.jl

If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here

diff --git a/dev/concept_reference/has_state/index.html b/dev/concept_reference/has_state/index.html index 9214a24b0f..cea5b92c9d 100644 --- a/dev/concept_reference/has_state/index.html +++ b/dev/concept_reference/has_state/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.

+- · SpineOpt.jl

The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.

diff --git a/dev/concept_reference/has_voltage_angle/index.html b/dev/concept_reference/has_voltage_angle/index.html index 37289f94ad..6ca4b0eac0 100644 --- a/dev/concept_reference/has_voltage_angle/index.html +++ b/dev/concept_reference/has_voltage_angle/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here

+- · SpineOpt.jl

For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here

diff --git a/dev/concept_reference/investment_group/index.html b/dev/concept_reference/investment_group/index.html index 82958a2701..88d9d7d588 100644 --- a/dev/concept_reference/investment_group/index.html +++ b/dev/concept_reference/investment_group/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.

To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.

+- · SpineOpt.jl

The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.

To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.

diff --git a/dev/concept_reference/is_active/index.html b/dev/concept_reference/is_active/index.html index 6f8f33acd7..30dcb0f6db 100644 --- a/dev/concept_reference/is_active/index.html +++ b/dev/concept_reference/is_active/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not.

+- · SpineOpt.jl

is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not.

diff --git a/dev/concept_reference/is_non_spinning/index.html b/dev/concept_reference/is_non_spinning/index.html index e822a49a31..d59c03bd86 100644 --- a/dev/concept_reference/is_non_spinning/index.html +++ b/dev/concept_reference/is_non_spinning/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.

+- · SpineOpt.jl

By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.

diff --git a/dev/concept_reference/is_renewable/index.html b/dev/concept_reference/is_renewable/index.html index c39e643a1a..6d119a5779 100644 --- a/dev/concept_reference/is_renewable/index.html +++ b/dev/concept_reference/is_renewable/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.

+- · SpineOpt.jl

A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.

diff --git a/dev/concept_reference/is_reserve_node/index.html b/dev/concept_reference/is_reserve_node/index.html index 3804a02e3d..4c4dec29a3 100644 --- a/dev/concept_reference/is_reserve_node/index.html +++ b/dev/concept_reference/is_reserve_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.

+- · SpineOpt.jl

By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.

diff --git a/dev/concept_reference/max_cum_in_unit_flow_bound/index.html b/dev/concept_reference/max_cum_in_unit_flow_bound/index.html index e3834f8936..da774e5a35 100644 --- a/dev/concept_reference/max_cum_in_unit_flow_bound/index.html +++ b/dev/concept_reference/max_cum_in_unit_flow_bound/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.

Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)

+- · SpineOpt.jl

To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.

Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)

diff --git a/dev/concept_reference/max_gap/index.html b/dev/concept_reference/max_gap/index.html index f30a6621de..999839ef50 100644 --- a/dev/concept_reference/max_gap/index.html +++ b/dev/concept_reference/max_gap/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.

+- · SpineOpt.jl

This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.

diff --git a/dev/concept_reference/max_iterations/index.html b/dev/concept_reference/max_iterations/index.html index db8fbbb5ce..282c37a9ff 100644 --- a/dev/concept_reference/max_iterations/index.html +++ b/dev/concept_reference/max_iterations/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.

+- · SpineOpt.jl

When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.

diff --git a/dev/concept_reference/max_mga_iterations/index.html b/dev/concept_reference/max_mga_iterations/index.html index 8d3046a42f..8bdb97064d 100644 --- a/dev/concept_reference/max_mga_iterations/index.html +++ b/dev/concept_reference/max_mga_iterations/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.

+- · SpineOpt.jl

In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.

diff --git a/dev/concept_reference/max_mga_slack/index.html b/dev/concept_reference/max_mga_slack/index.html index e5056e6685..06825b8d81 100644 --- a/dev/concept_reference/max_mga_slack/index.html +++ b/dev/concept_reference/max_mga_slack/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).

+- · SpineOpt.jl

In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).

diff --git a/dev/concept_reference/max_node_pressure/index.html b/dev/concept_reference/max_node_pressure/index.html index 89d85e0016..922fce3753 100644 --- a/dev/concept_reference/max_node_pressure/index.html +++ b/dev/concept_reference/max_node_pressure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/max_ratio_in_in_unit_flow/index.html b/dev/concept_reference/max_ratio_in_in_unit_flow/index.html index 514e15a59c..c2ecba5c0b 100644 --- a/dev/concept_reference/max_ratio_in_in_unit_flow/index.html +++ b/dev/concept_reference/max_ratio_in_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.

+- · SpineOpt.jl

The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.

diff --git a/dev/concept_reference/max_ratio_in_out_unit_flow/index.html b/dev/concept_reference/max_ratio_in_out_unit_flow/index.html index 6a8441aba9..1a0f57cef8 100644 --- a/dev/concept_reference/max_ratio_in_out_unit_flow/index.html +++ b/dev/concept_reference/max_ratio_in_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

+- · SpineOpt.jl

The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

diff --git a/dev/concept_reference/max_ratio_out_in_connection_flow/index.html b/dev/concept_reference/max_ratio_out_in_connection_flow/index.html index 7fbacfae48..8102807e99 100644 --- a/dev/concept_reference/max_ratio_out_in_connection_flow/index.html +++ b/dev/concept_reference/max_ratio_out_in_connection_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.

Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.

+- · SpineOpt.jl

The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.

Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.

diff --git a/dev/concept_reference/max_ratio_out_in_unit_flow/index.html b/dev/concept_reference/max_ratio_out_in_unit_flow/index.html index ec2b49c21d..c0e5d8ad3f 100644 --- a/dev/concept_reference/max_ratio_out_in_unit_flow/index.html +++ b/dev/concept_reference/max_ratio_out_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

+- · SpineOpt.jl

The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

diff --git a/dev/concept_reference/max_ratio_out_out_unit_flow/index.html b/dev/concept_reference/max_ratio_out_out_unit_flow/index.html index e3742cdb05..0481668d97 100644 --- a/dev/concept_reference/max_ratio_out_out_unit_flow/index.html +++ b/dev/concept_reference/max_ratio_out_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

+- · SpineOpt.jl

The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

diff --git a/dev/concept_reference/max_total_cumulated_unit_flow_from_node/index.html b/dev/concept_reference/max_total_cumulated_unit_flow_from_node/index.html index 6c765e7501..0017a2c675 100644 --- a/dev/concept_reference/max_total_cumulated_unit_flow_from_node/index.html +++ b/dev/concept_reference/max_total_cumulated_unit_flow_from_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

+- · SpineOpt.jl

The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

diff --git a/dev/concept_reference/max_total_cumulated_unit_flow_to_node/index.html b/dev/concept_reference/max_total_cumulated_unit_flow_to_node/index.html index 0df569f60a..9f73613e81 100644 --- a/dev/concept_reference/max_total_cumulated_unit_flow_to_node/index.html +++ b/dev/concept_reference/max_total_cumulated_unit_flow_to_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

+- · SpineOpt.jl

The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

diff --git a/dev/concept_reference/max_units_on_coefficient_in_in/index.html b/dev/concept_reference/max_units_on_coefficient_in_in/index.html index a58bdc8b76..6c4379a4a4 100644 --- a/dev/concept_reference/max_units_on_coefficient_in_in/index.html +++ b/dev/concept_reference/max_units_on_coefficient_in_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.

+- · SpineOpt.jl

The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.

diff --git a/dev/concept_reference/max_units_on_coefficient_in_out/index.html b/dev/concept_reference/max_units_on_coefficient_in_out/index.html index d41a48fb8b..5d1a8d7ac3 100644 --- a/dev/concept_reference/max_units_on_coefficient_in_out/index.html +++ b/dev/concept_reference/max_units_on_coefficient_in_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.

+- · SpineOpt.jl

The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.

diff --git a/dev/concept_reference/max_units_on_coefficient_out_in/index.html b/dev/concept_reference/max_units_on_coefficient_out_in/index.html index 07bd8c8feb..32291fcb21 100644 --- a/dev/concept_reference/max_units_on_coefficient_out_in/index.html +++ b/dev/concept_reference/max_units_on_coefficient_out_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.

+- · SpineOpt.jl

The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.

diff --git a/dev/concept_reference/max_units_on_coefficient_out_out/index.html b/dev/concept_reference/max_units_on_coefficient_out_out/index.html index c53ac3c0b0..9d29dd6080 100644 --- a/dev/concept_reference/max_units_on_coefficient_out_out/index.html +++ b/dev/concept_reference/max_units_on_coefficient_out_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.

+- · SpineOpt.jl

The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.

diff --git a/dev/concept_reference/max_voltage_angle/index.html b/dev/concept_reference/max_voltage_angle/index.html index 856c5cf7c5..8b11565d20 100644 --- a/dev/concept_reference/max_voltage_angle/index.html +++ b/dev/concept_reference/max_voltage_angle/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/mga_diff_relative/index.html b/dev/concept_reference/mga_diff_relative/index.html index 5eb9c5a147..2a5f228726 100644 --- a/dev/concept_reference/mga_diff_relative/index.html +++ b/dev/concept_reference/mga_diff_relative/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Currently, the MGA algorithm (see mga-advanced) only supports absolute differences between MGA variables (e.g. absolute differences between units_invested_available etc.). Hence, the default for this parameter is false and should not be changed for now.

+- · SpineOpt.jl

Currently, the MGA algorithm (see mga-advanced) only supports absolute differences between MGA variables (e.g. absolute differences between units_invested_available etc.). Hence, the default for this parameter is false and should not be changed for now.

diff --git a/dev/concept_reference/min_down_time/index.html b/dev/concept_reference/min_down_time/index.html index 8eed912ac6..7f84486f68 100644 --- a/dev/concept_reference/min_down_time/index.html +++ b/dev/concept_reference/min_down_time/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.

It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

For a more complete description of unit commmitment restrictions, see Unit commitment.

+- · SpineOpt.jl

The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.

It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

For a more complete description of unit commmitment restrictions, see Unit commitment.

diff --git a/dev/concept_reference/min_node_pressure/index.html b/dev/concept_reference/min_node_pressure/index.html index 25f93b8900..4c92c54467 100644 --- a/dev/concept_reference/min_node_pressure/index.html +++ b/dev/concept_reference/min_node_pressure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/min_ratio_in_in_unit_flow/index.html b/dev/concept_reference/min_ratio_in_in_unit_flow/index.html index 70d537097e..acf519c8c5 100644 --- a/dev/concept_reference/min_ratio_in_in_unit_flow/index.html +++ b/dev/concept_reference/min_ratio_in_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.

+- · SpineOpt.jl

The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.

To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.

diff --git a/dev/concept_reference/min_ratio_in_out_unit_flow/index.html b/dev/concept_reference/min_ratio_in_out_unit_flow/index.html index 2a637c8c8c..eebcc3a8d2 100644 --- a/dev/concept_reference/min_ratio_in_out_unit_flow/index.html +++ b/dev/concept_reference/min_ratio_in_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

+- · SpineOpt.jl

The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.

diff --git a/dev/concept_reference/min_ratio_out_in_connection_flow/index.html b/dev/concept_reference/min_ratio_out_in_connection_flow/index.html index 5f44cd209a..33b949dc30 100644 --- a/dev/concept_reference/min_ratio_out_in_connection_flow/index.html +++ b/dev/concept_reference/min_ratio_out_in_connection_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.

Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.

To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.

+- · SpineOpt.jl

The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.

Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.

To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.

diff --git a/dev/concept_reference/min_ratio_out_in_unit_flow/index.html b/dev/concept_reference/min_ratio_out_in_unit_flow/index.html index bf69181b16..ff3a5cba2d 100644 --- a/dev/concept_reference/min_ratio_out_in_unit_flow/index.html +++ b/dev/concept_reference/min_ratio_out_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

+- · SpineOpt.jl

The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.

diff --git a/dev/concept_reference/min_ratio_out_out_unit_flow/index.html b/dev/concept_reference/min_ratio_out_out_unit_flow/index.html index f38e0c8bde..08dd9fe407 100644 --- a/dev/concept_reference/min_ratio_out_out_unit_flow/index.html +++ b/dev/concept_reference/min_ratio_out_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

+- · SpineOpt.jl

The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.

To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.

diff --git a/dev/concept_reference/min_total_cumulated_unit_flow_from_node/index.html b/dev/concept_reference/min_total_cumulated_unit_flow_from_node/index.html index f7108f297e..f6e3b92899 100644 --- a/dev/concept_reference/min_total_cumulated_unit_flow_from_node/index.html +++ b/dev/concept_reference/min_total_cumulated_unit_flow_from_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

+- · SpineOpt.jl

The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

diff --git a/dev/concept_reference/min_total_cumulated_unit_flow_to_node/index.html b/dev/concept_reference/min_total_cumulated_unit_flow_to_node/index.html index a1d6c8f39e..3b8baa95db 100644 --- a/dev/concept_reference/min_total_cumulated_unit_flow_to_node/index.html +++ b/dev/concept_reference/min_total_cumulated_unit_flow_to_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

+- · SpineOpt.jl

The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.

It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.

diff --git a/dev/concept_reference/min_units_on_coefficient_in_in/index.html b/dev/concept_reference/min_units_on_coefficient_in_in/index.html index 65a6465930..c3551805be 100644 --- a/dev/concept_reference/min_units_on_coefficient_in_in/index.html +++ b/dev/concept_reference/min_units_on_coefficient_in_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.

+- · SpineOpt.jl

The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.

diff --git a/dev/concept_reference/min_units_on_coefficient_in_out/index.html b/dev/concept_reference/min_units_on_coefficient_in_out/index.html index 59fe1512ce..1cd50a0bc9 100644 --- a/dev/concept_reference/min_units_on_coefficient_in_out/index.html +++ b/dev/concept_reference/min_units_on_coefficient_in_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.

+- · SpineOpt.jl

The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.

diff --git a/dev/concept_reference/min_units_on_coefficient_out_in/index.html b/dev/concept_reference/min_units_on_coefficient_out_in/index.html index 99b07aead5..5e433a8a4f 100644 --- a/dev/concept_reference/min_units_on_coefficient_out_in/index.html +++ b/dev/concept_reference/min_units_on_coefficient_out_in/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.

+- · SpineOpt.jl

The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.

diff --git a/dev/concept_reference/min_units_on_coefficient_out_out/index.html b/dev/concept_reference/min_units_on_coefficient_out_out/index.html index 69ada86013..1bb24d08a8 100644 --- a/dev/concept_reference/min_units_on_coefficient_out_out/index.html +++ b/dev/concept_reference/min_units_on_coefficient_out_out/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.

+- · SpineOpt.jl

The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.

Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.

diff --git a/dev/concept_reference/min_up_time/index.html b/dev/concept_reference/min_up_time/index.html index b5304621b3..d289c90fce 100644 --- a/dev/concept_reference/min_up_time/index.html +++ b/dev/concept_reference/min_up_time/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.

It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

For a more complete description of unit commmitment restrictions, see Unit commitment.

+- · SpineOpt.jl

The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.

It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

For a more complete description of unit commmitment restrictions, see Unit commitment.

diff --git a/dev/concept_reference/min_voltage_angle/index.html b/dev/concept_reference/min_voltage_angle/index.html index 7a407a1df3..d72ecddd5a 100644 --- a/dev/concept_reference/min_voltage_angle/index.html +++ b/dev/concept_reference/min_voltage_angle/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/minimum_operating_point/index.html b/dev/concept_reference/minimum_operating_point/index.html index 209063b1c0..5ed1439482 100644 --- a/dev/concept_reference/minimum_operating_point/index.html +++ b/dev/concept_reference/minimum_operating_point/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

+- · SpineOpt.jl

The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.

diff --git a/dev/concept_reference/minimum_reserve_activation_time/index.html b/dev/concept_reference/minimum_reserve_activation_time/index.html index 161666a503..0023a760c8 100644 --- a/dev/concept_reference/minimum_reserve_activation_time/index.html +++ b/dev/concept_reference/minimum_reserve_activation_time/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.

In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves

+- · SpineOpt.jl

The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.

In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves

diff --git a/dev/concept_reference/model/index.html b/dev/concept_reference/model/index.html index 674d911439..9108e7c4aa 100644 --- a/dev/concept_reference/model/index.html +++ b/dev/concept_reference/model/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).

+- · SpineOpt.jl

The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).

diff --git a/dev/concept_reference/model__default_investment_stochastic_structure/index.html b/dev/concept_reference/model__default_investment_stochastic_structure/index.html index 603cc1016f..2d5c0d94ee 100644 --- a/dev/concept_reference/model__default_investment_stochastic_structure/index.html +++ b/dev/concept_reference/model__default_investment_stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.

+- · SpineOpt.jl

The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.

diff --git a/dev/concept_reference/model__default_investment_temporal_block/index.html b/dev/concept_reference/model__default_investment_temporal_block/index.html index 21b5b29734..9e37d0a0a0 100644 --- a/dev/concept_reference/model__default_investment_temporal_block/index.html +++ b/dev/concept_reference/model__default_investment_temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.

See also Investment Optimization

+- · SpineOpt.jl

model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.

See also Investment Optimization

diff --git a/dev/concept_reference/model__default_stochastic_structure/index.html b/dev/concept_reference/model__default_stochastic_structure/index.html index a8db693eab..e2bb8a04e8 100644 --- a/dev/concept_reference/model__default_stochastic_structure/index.html +++ b/dev/concept_reference/model__default_stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/model__default_temporal_block/index.html b/dev/concept_reference/model__default_temporal_block/index.html index 40178a51c6..010a246424 100644 --- a/dev/concept_reference/model__default_temporal_block/index.html +++ b/dev/concept_reference/model__default_temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/model__report/index.html b/dev/concept_reference/model__report/index.html index 169962e225..afa7c64bff 100644 --- a/dev/concept_reference/model__report/index.html +++ b/dev/concept_reference/model__report/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/model__stochastic_structure/index.html b/dev/concept_reference/model__stochastic_structure/index.html index 4c21a53621..d84f4c353e 100644 --- a/dev/concept_reference/model__stochastic_structure/index.html +++ b/dev/concept_reference/model__stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.

+- · SpineOpt.jl

The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.

diff --git a/dev/concept_reference/model__temporal_block/index.html b/dev/concept_reference/model__temporal_block/index.html index f4e02b1b5f..c478a1eb01 100644 --- a/dev/concept_reference/model__temporal_block/index.html +++ b/dev/concept_reference/model__temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.

+- · SpineOpt.jl

The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.

diff --git a/dev/concept_reference/model_end/index.html b/dev/concept_reference/model_end/index.html index 742bd3e09c..770397f5df 100644 --- a/dev/concept_reference/model_end/index.html +++ b/dev/concept_reference/model_end/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.

In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].

A DateTime value should be chosen for this parameter.

+- · SpineOpt.jl

Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.

In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].

A DateTime value should be chosen for this parameter.

diff --git a/dev/concept_reference/model_start/index.html b/dev/concept_reference/model_start/index.html index c68aba9c86..95b8b702e4 100644 --- a/dev/concept_reference/model_start/index.html +++ b/dev/concept_reference/model_start/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.

A DateTime value should be chosen for this parameter.

+- · SpineOpt.jl

Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.

A DateTime value should be chosen for this parameter.

diff --git a/dev/concept_reference/model_type/index.html b/dev/concept_reference/model_type/index.html index f1275aee02..3bfd9d604a 100644 --- a/dev/concept_reference/model_type/index.html +++ b/dev/concept_reference/model_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:

spineopt_standard uses the standard algorithm.

spineopt_benders uses the Benders decomposition algorithm (see Decomposition.

spineopt_mga uses the Model to Generate Alternatives algorithm.

+- · SpineOpt.jl

This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:

spineopt_standard uses the standard algorithm.

spineopt_benders uses the Benders decomposition algorithm (see Decomposition.

spineopt_mga uses the Model to Generate Alternatives algorithm.

diff --git a/dev/concept_reference/model_type_list/index.html b/dev/concept_reference/model_type_list/index.html index 25ef633e16..e52153a451 100644 --- a/dev/concept_reference/model_type_list/index.html +++ b/dev/concept_reference/model_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details

+- · SpineOpt.jl

model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details

diff --git a/dev/concept_reference/mp_min_res_gen_to_demand_ratio/index.html b/dev/concept_reference/mp_min_res_gen_to_demand_ratio/index.html index 78787e06da..71c84000c8 100644 --- a/dev/concept_reference/mp_min_res_gen_to_demand_ratio/index.html +++ b/dev/concept_reference/mp_min_res_gen_to_demand_ratio/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).

A unit can be marked as a renewable generation source by setting is_renewable to true.

+- · SpineOpt.jl

For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).

A unit can be marked as a renewable generation source by setting is_renewable to true.

diff --git a/dev/concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/index.html b/dev/concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/index.html index 9825839201..31398b4cf9 100644 --- a/dev/concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/index.html +++ b/dev/concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.

+- · SpineOpt.jl

A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.

diff --git a/dev/concept_reference/nodal_balance_sense/index.html b/dev/concept_reference/nodal_balance_sense/index.html index d3970c3595..9107a9a7b0 100644 --- a/dev/concept_reference/nodal_balance_sense/index.html +++ b/dev/concept_reference/nodal_balance_sense/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.

+- · SpineOpt.jl

nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.

diff --git a/dev/concept_reference/node/index.html b/dev/concept_reference/node/index.html index bdb252c933..dfd06ea62f 100644 --- a/dev/concept_reference/node/index.html +++ b/dev/concept_reference/node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.

Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.

+- · SpineOpt.jl

The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.

Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.

diff --git a/dev/concept_reference/node__commodity/index.html b/dev/concept_reference/node__commodity/index.html index 79e924bd45..608727c58d 100644 --- a/dev/concept_reference/node__commodity/index.html +++ b/dev/concept_reference/node__commodity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:

  1. To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow
  2. Only connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.
+- · SpineOpt.jl

node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:

  1. To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow
  2. Only connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.
diff --git a/dev/concept_reference/node__investment_stochastic_structure/index.html b/dev/concept_reference/node__investment_stochastic_structure/index.html index 0e6d95ec29..3da5002ff6 100644 --- a/dev/concept_reference/node__investment_stochastic_structure/index.html +++ b/dev/concept_reference/node__investment_stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/node__investment_temporal_block/index.html b/dev/concept_reference/node__investment_temporal_block/index.html index 658bcf9af8..351e5e0e64 100644 --- a/dev/concept_reference/node__investment_temporal_block/index.html +++ b/dev/concept_reference/node__investment_temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.

See also Investment Optimization

+- · SpineOpt.jl

node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.

See also Investment Optimization

diff --git a/dev/concept_reference/node__node/index.html b/dev/concept_reference/node__node/index.html index 0255e8d730..1ec5ad1f56 100644 --- a/dev/concept_reference/node__node/index.html +++ b/dev/concept_reference/node__node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that

node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).

Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.

+- · SpineOpt.jl

The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that

node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).

Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.

diff --git a/dev/concept_reference/node__stochastic_structure/index.html b/dev/concept_reference/node__stochastic_structure/index.html index 23177478e2..b96dcace50 100644 --- a/dev/concept_reference/node__stochastic_structure/index.html +++ b/dev/concept_reference/node__stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.

The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

+- · SpineOpt.jl

The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.

The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

diff --git a/dev/concept_reference/node__temporal_block/index.html b/dev/concept_reference/node__temporal_block/index.html index 1ee9b1ac38..67a2762277 100644 --- a/dev/concept_reference/node__temporal_block/index.html +++ b/dev/concept_reference/node__temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.

For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.

+- · SpineOpt.jl

This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.

For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.

diff --git a/dev/concept_reference/node__unit_constraint/index.html b/dev/concept_reference/node__unit_constraint/index.html index 405e1c05ad..b5c50d1ac5 100644 --- a/dev/concept_reference/node__unit_constraint/index.html +++ b/dev/concept_reference/node__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

node__user_constraint is a two-dimensional relationship between a node and a user_constraint. The relationship specifies that a variable associated only with the node (currently only the node_state) is involved in the constraint. For example, the node_state_coefficient defined on node__user_constraint specifies the coefficient of the node's node_state variable in the specified user_constraint.

See also user_constraint

+- · SpineOpt.jl

node__user_constraint is a two-dimensional relationship between a node and a user_constraint. The relationship specifies that a variable associated only with the node (currently only the node_state) is involved in the constraint. For example, the node_state_coefficient defined on node__user_constraint specifies the coefficient of the node's node_state variable in the specified user_constraint.

See also user_constraint

diff --git a/dev/concept_reference/node_opf_type/index.html b/dev/concept_reference/node_opf_type/index.html index 85c06eb40f..2b1f77e325 100644 --- a/dev/concept_reference/node_opf_type/index.html +++ b/dev/concept_reference/node_opf_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/node_opf_type_list/index.html b/dev/concept_reference/node_opf_type_list/index.html index 81ee9b431a..0c280edb0a 100644 --- a/dev/concept_reference/node_opf_type_list/index.html +++ b/dev/concept_reference/node_opf_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.

See also powerflow.

+- · SpineOpt.jl

Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.

See also powerflow.

diff --git a/dev/concept_reference/node_slack_penalty/index.html b/dev/concept_reference/node_slack_penalty/index.html index d6cf53011b..4770e2a6fc 100644 --- a/dev/concept_reference/node_slack_penalty/index.html +++ b/dev/concept_reference/node_slack_penalty/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.

+- · SpineOpt.jl

node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.

diff --git a/dev/concept_reference/node_state_cap/index.html b/dev/concept_reference/node_state_cap/index.html index 1ebc4751be..bfbffe777a 100644 --- a/dev/concept_reference/node_state_cap/index.html +++ b/dev/concept_reference/node_state_cap/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.

+- · SpineOpt.jl

The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.

diff --git a/dev/concept_reference/node_state_coefficient/index.html b/dev/concept_reference/node_state_coefficient/index.html index 18e36812a2..9031256e77 100644 --- a/dev/concept_reference/node_state_coefficient/index.html +++ b/dev/concept_reference/node_state_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/node_state_min/index.html b/dev/concept_reference/node_state_min/index.html index 52ba07494a..ee20c29d5c 100644 --- a/dev/concept_reference/node_state_min/index.html +++ b/dev/concept_reference/node_state_min/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/number_of_units/index.html b/dev/concept_reference/number_of_units/index.html index ef6c4d2d38..078528db56 100644 --- a/dev/concept_reference/number_of_units/index.html +++ b/dev/concept_reference/number_of_units/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization

The default value for this parameter is 1.

+- · SpineOpt.jl

Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization

The default value for this parameter is 1.

diff --git a/dev/concept_reference/online_variable_type/index.html b/dev/concept_reference/online_variable_type/index.html index 807918d412..74cf19230e 100644 --- a/dev/concept_reference/online_variable_type/index.html +++ b/dev/concept_reference/online_variable_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values "unit_online_variable_type_binary", "unit_online_variable_type_integer", "unit_online_variable_type_linear" and "unit_online_variable_type_none".

If unit\_online\_variable\_type\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).

If unit\_online\_variable\_type\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment).

If unit\_online\_variable\_type\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\_online\_variable\_type\_integer.

If unit\_online\_variable\_type\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.

+- · SpineOpt.jl

online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values "unit_online_variable_type_binary", "unit_online_variable_type_integer", "unit_online_variable_type_linear" and "unit_online_variable_type_none".

If unit\_online\_variable\_type\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).

If unit\_online\_variable\_type\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment).

If unit\_online\_variable\_type\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\_online\_variable\_type\_integer.

If unit\_online\_variable\_type\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.

diff --git a/dev/concept_reference/operating_cost/index.html b/dev/concept_reference/operating_cost/index.html index 2dc4934893..54aba50578 100644 --- a/dev/concept_reference/operating_cost/index.html +++ b/dev/concept_reference/operating_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the operating_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for operating costs associated with that unit over the course of its operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the operating_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for operating costs associated with that unit over the course of its operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/operating_points/index.html b/dev/concept_reference/operating_points/index.html index 8cd03eb368..95222b93b8 100644 --- a/dev/concept_reference/operating_points/index.html +++ b/dev/concept_reference/operating_points/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.

Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.

+- · SpineOpt.jl

If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.

Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.

diff --git a/dev/concept_reference/ordered_unit_flow_op/index.html b/dev/concept_reference/ordered_unit_flow_op/index.html index 966a675bbc..a21deeeb25 100644 --- a/dev/concept_reference/ordered_unit_flow_op/index.html +++ b/dev/concept_reference/ordered_unit_flow_op/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.

Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.

+- · SpineOpt.jl

If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.

Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.

diff --git a/dev/concept_reference/output/index.html b/dev/concept_reference/output/index.html index 6039e17a1b..1b52d3e12f 100644 --- a/dev/concept_reference/output/index.html +++ b/dev/concept_reference/output/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

+- · SpineOpt.jl

An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

diff --git a/dev/concept_reference/output_db_url/index.html b/dev/concept_reference/output_db_url/index.html index f24fd2a865..7046e5d13f 100644 --- a/dev/concept_reference/output_db_url/index.html +++ b/dev/concept_reference/output_db_url/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.

+- · SpineOpt.jl

The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.

diff --git a/dev/concept_reference/output_resolution/index.html b/dev/concept_reference/output_resolution/index.html index 216137ee85..360ba180ff 100644 --- a/dev/concept_reference/output_resolution/index.html +++ b/dev/concept_reference/output_resolution/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The output_resolution parameter indicates the resolution at which output values should be reported.

If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.

+- · SpineOpt.jl

The output_resolution parameter indicates the resolution at which output values should be reported.

If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.

diff --git a/dev/concept_reference/overwrite_results_on_rolling/index.html b/dev/concept_reference/overwrite_results_on_rolling/index.html index e779acc488..00171eaa78 100644 --- a/dev/concept_reference/overwrite_results_on_rolling/index.html +++ b/dev/concept_reference/overwrite_results_on_rolling/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.

If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.

+- · SpineOpt.jl

The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.

If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.

diff --git a/dev/concept_reference/parent_stochastic_scenario__child_stochastic_scenario/index.html b/dev/concept_reference/parent_stochastic_scenario__child_stochastic_scenario/index.html index a435a56552..c0a913e048 100644 --- a/dev/concept_reference/parent_stochastic_scenario__child_stochastic_scenario/index.html +++ b/dev/concept_reference/parent_stochastic_scenario__child_stochastic_scenario/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.

The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.

+- · SpineOpt.jl

The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.

The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.

diff --git a/dev/concept_reference/ramp_down_limit/index.html b/dev/concept_reference/ramp_down_limit/index.html index 55c5e98ba2..ae7f8d3ff6 100644 --- a/dev/concept_reference/ramp_down_limit/index.html +++ b/dev/concept_reference/ramp_down_limit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.

For a more complete description of how ramping restrictions can be implemented, see Ramping.

+- · SpineOpt.jl

The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.

For a more complete description of how ramping restrictions can be implemented, see Ramping.

diff --git a/dev/concept_reference/ramp_up_limit/index.html b/dev/concept_reference/ramp_up_limit/index.html index 7165e1d4c9..288ea7c065 100644 --- a/dev/concept_reference/ramp_up_limit/index.html +++ b/dev/concept_reference/ramp_up_limit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.

For a more complete description of how ramping restrictions can be implemented, see Ramping.

+- · SpineOpt.jl

The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.

For a more complete description of how ramping restrictions can be implemented, see Ramping.

diff --git a/dev/concept_reference/report/index.html b/dev/concept_reference/report/index.html index 24206f1e11..c5bfb56021 100644 --- a/dev/concept_reference/report/index.html +++ b/dev/concept_reference/report/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

+- · SpineOpt.jl

A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!

diff --git a/dev/concept_reference/report__output/index.html b/dev/concept_reference/report__output/index.html index c7cbc46caf..060c2bbaf3 100644 --- a/dev/concept_reference/report__output/index.html +++ b/dev/concept_reference/report__output/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/representative_periods_mapping/index.html b/dev/concept_reference/representative_periods_mapping/index.html index 1e4081a2fc..6d30ae7214 100644 --- a/dev/concept_reference/representative_periods_mapping/index.html +++ b/dev/concept_reference/representative_periods_mapping/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.

Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.

To use representative periods in your model, do the following:

  1. Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.
  2. Define a set of temporal_block objects, each corresponding to one representative period.
  3. Specify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.
  4. Associate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.

See also Representative days with seasonal storages.

+- · SpineOpt.jl

Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.

Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.

To use representative periods in your model, do the following:

  1. Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.
  2. Define a set of temporal_block objects, each corresponding to one representative period.
  3. Specify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.
  4. Associate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.

See also Representative days with seasonal storages.

diff --git a/dev/concept_reference/reserve_procurement_cost/index.html b/dev/concept_reference/reserve_procurement_cost/index.html index df6852f425..a5d6d05e41 100644 --- a/dev/concept_reference/reserve_procurement_cost/index.html +++ b/dev/concept_reference/reserve_procurement_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/resolution/index.html b/dev/concept_reference/resolution/index.html index acd8f04e0e..e7fae7472f 100644 --- a/dev/concept_reference/resolution/index.html +++ b/dev/concept_reference/resolution/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.

An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.

+- · SpineOpt.jl

This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.

An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.

diff --git a/dev/concept_reference/right_hand_side/index.html b/dev/concept_reference/right_hand_side/index.html index 877ba198f3..1e449f154f 100644 --- a/dev/concept_reference/right_hand_side/index.html +++ b/dev/concept_reference/right_hand_side/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/roll_forward/index.html b/dev/concept_reference/roll_forward/index.html index 6529c2120a..d6b3de19c0 100644 --- a/dev/concept_reference/roll_forward/index.html +++ b/dev/concept_reference/roll_forward/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.

In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.

+- · SpineOpt.jl

This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.

In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.

diff --git a/dev/concept_reference/shut_down_cost/index.html b/dev/concept_reference/shut_down_cost/index.html index ec2d7dcded..a8e4b33e43 100644 --- a/dev/concept_reference/shut_down_cost/index.html +++ b/dev/concept_reference/shut_down_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/shut_down_limit/index.html b/dev/concept_reference/shut_down_limit/index.html index a9006d46f4..d739c8b470 100644 --- a/dev/concept_reference/shut_down_limit/index.html +++ b/dev/concept_reference/shut_down_limit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.

+- · SpineOpt.jl

The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.

diff --git a/dev/concept_reference/start_up_cost/index.html b/dev/concept_reference/start_up_cost/index.html index a5e873d5e2..b8f63f708f 100644 --- a/dev/concept_reference/start_up_cost/index.html +++ b/dev/concept_reference/start_up_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/start_up_limit/index.html b/dev/concept_reference/start_up_limit/index.html index 3ca978ac86..72bf897ae7 100644 --- a/dev/concept_reference/start_up_limit/index.html +++ b/dev/concept_reference/start_up_limit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.

+- · SpineOpt.jl

The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.

It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.

diff --git a/dev/concept_reference/state_coeff/index.html b/dev/concept_reference/state_coeff/index.html index f1148a656c..faa04275d4 100644 --- a/dev/concept_reference/state_coeff/index.html +++ b/dev/concept_reference/state_coeff/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.

Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.

+- · SpineOpt.jl

The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.

Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.

diff --git a/dev/concept_reference/stochastic_scenario/index.html b/dev/concept_reference/stochastic_scenario/index.html index 32881fe64d..c210d832bf 100644 --- a/dev/concept_reference/stochastic_scenario/index.html +++ b/dev/concept_reference/stochastic_scenario/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.

+- · SpineOpt.jl

Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.

diff --git a/dev/concept_reference/stochastic_scenario_end/index.html b/dev/concept_reference/stochastic_scenario_end/index.html index 8637687fc1..87e7317380 100644 --- a/dev/concept_reference/stochastic_scenario_end/index.html +++ b/dev/concept_reference/stochastic_scenario_end/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.

When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.

If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.

+- · SpineOpt.jl

The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.

When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.

If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.

diff --git a/dev/concept_reference/stochastic_structure/index.html b/dev/concept_reference/stochastic_structure/index.html index b843464c2c..98b0d9f68b 100644 --- a/dev/concept_reference/stochastic_structure/index.html +++ b/dev/concept_reference/stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.

The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.

+- · SpineOpt.jl

The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.

The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.

diff --git a/dev/concept_reference/stochastic_structure__stochastic_scenario/index.html b/dev/concept_reference/stochastic_structure__stochastic_scenario/index.html index 66d3bcc034..a752296343 100644 --- a/dev/concept_reference/stochastic_structure__stochastic_scenario/index.html +++ b/dev/concept_reference/stochastic_structure__stochastic_scenario/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.

+- · SpineOpt.jl

The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.

diff --git a/dev/concept_reference/storage_investment_cost/index.html b/dev/concept_reference/storage_investment_cost/index.html index 75ab4fee63..ef24681393 100644 --- a/dev/concept_reference/storage_investment_cost/index.html +++ b/dev/concept_reference/storage_investment_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.

+- · SpineOpt.jl

By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.

diff --git a/dev/concept_reference/storage_investment_lifetime/index.html b/dev/concept_reference/storage_investment_lifetime/index.html index 95ffa02f97..ab9e6d9613 100644 --- a/dev/concept_reference/storage_investment_lifetime/index.html +++ b/dev/concept_reference/storage_investment_lifetime/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

See also Investment Optimization and candidate_storages

+- · SpineOpt.jl

Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

See also Investment Optimization and candidate_storages

diff --git a/dev/concept_reference/storage_investment_variable_type/index.html b/dev/concept_reference/storage_investment_variable_type/index.html index 890b49e68b..cc3898b9ae 100644 --- a/dev/concept_reference/storage_investment_variable_type/index.html +++ b/dev/concept_reference/storage_investment_variable_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.

See also Investment Optimization and candidate_storages.

+- · SpineOpt.jl

Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.

See also Investment Optimization and candidate_storages.

diff --git a/dev/concept_reference/storages_invested_avaiable_coefficient/index.html b/dev/concept_reference/storages_invested_avaiable_coefficient/index.html index 03ba2b9eea..58a6f98692 100644 --- a/dev/concept_reference/storages_invested_avaiable_coefficient/index.html +++ b/dev/concept_reference/storages_invested_avaiable_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/storages_invested_big_m_mga/index.html b/dev/concept_reference/storages_invested_big_m_mga/index.html index 536d59af65..0dfddb242e 100644 --- a/dev/concept_reference/storages_invested_big_m_mga/index.html +++ b/dev/concept_reference/storages_invested_big_m_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)

+- · SpineOpt.jl

The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)

diff --git a/dev/concept_reference/storages_invested_coefficient/index.html b/dev/concept_reference/storages_invested_coefficient/index.html index 0096b034db..66c2db543c 100644 --- a/dev/concept_reference/storages_invested_coefficient/index.html +++ b/dev/concept_reference/storages_invested_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/storages_invested_mga/index.html b/dev/concept_reference/storages_invested_mga/index.html index 36a1274448..e837893dd1 100644 --- a/dev/concept_reference/storages_invested_mga/index.html +++ b/dev/concept_reference/storages_invested_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.

+- · SpineOpt.jl

The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.

diff --git a/dev/concept_reference/tax_in_unit_flow/index.html b/dev/concept_reference/tax_in_unit_flow/index.html index 2bcf96b0b6..c111d5b1cf 100644 --- a/dev/concept_reference/tax_in_unit_flow/index.html +++ b/dev/concept_reference/tax_in_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/tax_net_unit_flow/index.html b/dev/concept_reference/tax_net_unit_flow/index.html index fa1cff08b6..5048f89c7a 100644 --- a/dev/concept_reference/tax_net_unit_flow/index.html +++ b/dev/concept_reference/tax_net_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.

+- · SpineOpt.jl

By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.

diff --git a/dev/concept_reference/tax_out_unit_flow/index.html b/dev/concept_reference/tax_out_unit_flow/index.html index 331c33bc1a..0724aa62f5 100644 --- a/dev/concept_reference/tax_out_unit_flow/index.html +++ b/dev/concept_reference/tax_out_unit_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/temporal_block/index.html b/dev/concept_reference/temporal_block/index.html index e413e895cb..2421ddd408 100644 --- a/dev/concept_reference/temporal_block/index.html +++ b/dev/concept_reference/temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.

+- · SpineOpt.jl

A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.

diff --git a/dev/concept_reference/the_basics/index.html b/dev/concept_reference/the_basics/index.html index 420fec4045..7b9393639d 100644 --- a/dev/concept_reference/the_basics/index.html +++ b/dev/concept_reference/the_basics/index.html @@ -1,2 +1,2 @@ -Basics of the model structure · SpineOpt.jl

Basics of the model structure

In SpineOpt.jl, the model structure is generated based on the input data, allowing it to be used for a multitude of different problems. Here, we aim to provide you with a basic understanding of the SpineOpt.jl model and data structure, while the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections provide more in-depth explanations of each concept.

Introduction to object classes

Essentially, Object Classes represents different types of objects or entities that make up the model. For example, every power plant in the model is represented as an object of the object class unit, every power line as an object of the object class connection, and so forth. In order to add any new entity to a model, a new object has to be added to desired object class in the input data.

Each object class has a very specific purpose in SpineOpt.jl, so understanding their differences is key. The Object Classes can be roughly divided into three distinctive groups, namely Systemic object classes, Structural object classes, and Meta object classes.

Systemic object classes

As the name implies, system Object Classes are used to describe the system to be modelled. Essentially, they define what you want to model. These include:

  • commodity represents different goods to be generated, consumed, transported, etc.
  • connection handles the transfer of commodities between nodes.
  • node ensures the balance of the commodity flows, and can be used to store commodities as well.
  • unit handles the generation and consumption of commodities.

Structural object classes

Structural Object Classes are used to define the temporal and stochastic structure of the modelled problem, as well as custom User Constraints. Unlike the above system Object Classes, the structural Object Classes are more about how you want to model, instead of strictly what you want to model. These include:

Meta object classes

Meta Object Classes are used for defining things on the level of models or above, like model output and even multiple models for problem decompositions. These include:

  • model represents an individual model, grouping together all the things relevant for itself.
  • output defines which Variables are output from the model.
  • report groups together multiple output objects.

Introduction to relationship classes

While Object Classes define all the objects or entities that make up a model, Relationship Classes define how those entities are related to each other. Thus, Relationship Classes hold no meaning on their own, and always include at least one object class.

Similar to Object Classes, each relationship class has a very specific purpose in SpineOpt.jl, and understanding the purpose of each relationship class is paramount. The Relationship Classes can be roughly divided into Systemic relationship classes, Structural relationship classes, and Meta relationship classes, again similar to Object Classes.

Systemic relationship classes

Systemic Relationship Classes define how Systemic object classes are related to each other, thus helping define the system to be modelled. Most of these relationships deal with which units and connections interact with which nodes, and how those interactions work. This essentially defines the possible commodity flows to be modelled. Systemic Relationship Classes include:

Structural relationship classes

Structural Relationship Classes primarily relate Structural object classes to Systemic object classes, defining what structures the individual parts of the system use. These are mostly used to determine the temporal and stochastic structures to be used in different parts of the modelled system, or custom User Constraints.

SpineOpt.jl has a very flexible temporal and stochastic structure, explained in detail in the Temporal Framework and Stochastic Framework sections of the documentation. Unfortunately, this flexibility requires quite a few different structural Relationship Classes, the most important of which are the following basic structural Relationship Classes:

Furthermore, there are also a number of advanced structural Relationship Classes, which are only necessary when using some of the optional features of SpineOpt.jl. For Investment Optimization, the following relationships control the stochastic and temporal structures of the investment variables:

For User Constraints, which are essentially generic data-driven custom constraints, the following relationships are used to control which variables are included and with what coefficients:

Meta relationship classes

Meta Relationship Classes are used for defining model-level settings, like which temporal blocks or stochastic structures are active, and what the model output is. These include:

Introduction to parameters

While the primary function of Object Classes and Relationship Classes is to define the system to be modelled and it's structure, Parameters exist to constrain them. Every parameter is attributed to at least one object class or relationship class, but some appear in many classes whenever they serve a similar purpose.

Parameters accept different types of values depending on their purpose, e.g. whether they act as a flag for some specific functionality or appear as a coefficient in Constraints, so understanding each parameter is key. Most coefficient-type Parameters accept constant, time series, and even stochastic time series form input, but there are some exceptions. Most flag-type Parameters, on the other hand, have a restricted list of acceptable values defined by their Parameter Value Lists.

The existence of some Constraints is controlled based on if the relevant Parameters are defined. As a rule-of-thumb, a constraint only gets generated if at least one of the Parameters appearing in it is defined, but one should refer to the appropriate Constraints and Parameters sections when in doubt.

Introduction to groups of objects

Groups of objects are used within SpineOpt for different purposes. To create a group of objects, simply right-click the corresponding Object Class in the Spine Toolbox database editor and select Add object group. Groups are essentially special objects, that act as a single handle for all of its members.

On the one hand, groups can be used in order to impose constraints on the aggregation of a variable, e.g. on the sum of multiple unit_flow variables. Constraints based on parameters associated with the unit__node__node, unit__to_node, unit__from_node, connection__node__node, connection__to_node, connection__from_node can generally be used for this kind of flow aggregation by defining the parameters on groups of objects, typically node groups. (with the exception of variable fixing parameters, e.g. fix_unit_flow, fix_connection_flow etc.). See for instance constraint_unit_flow_capacity.

On the other hand, a node group can be used to for PTDF based powerflows. Here a node group is used to enforce a nodal balance on system level, while suppressing the node balances at individual nodes. See also balance_type and the node balance constraint.

+Basics of the model structure · SpineOpt.jl

Basics of the model structure

In SpineOpt.jl, the model structure is generated based on the input data, allowing it to be used for a multitude of different problems. Here, we aim to provide you with a basic understanding of the SpineOpt.jl model and data structure, while the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections provide more in-depth explanations of each concept.

Introduction to object classes

Essentially, Object Classes represents different types of objects or entities that make up the model. For example, every power plant in the model is represented as an object of the object class unit, every power line as an object of the object class connection, and so forth. In order to add any new entity to a model, a new object has to be added to desired object class in the input data.

Each object class has a very specific purpose in SpineOpt.jl, so understanding their differences is key. The Object Classes can be roughly divided into three distinctive groups, namely Systemic object classes, Structural object classes, and Meta object classes.

Systemic object classes

As the name implies, system Object Classes are used to describe the system to be modelled. Essentially, they define what you want to model. These include:

  • commodity represents different goods to be generated, consumed, transported, etc.
  • connection handles the transfer of commodities between nodes.
  • node ensures the balance of the commodity flows, and can be used to store commodities as well.
  • unit handles the generation and consumption of commodities.

Structural object classes

Structural Object Classes are used to define the temporal and stochastic structure of the modelled problem, as well as custom User Constraints. Unlike the above system Object Classes, the structural Object Classes are more about how you want to model, instead of strictly what you want to model. These include:

Meta object classes

Meta Object Classes are used for defining things on the level of models or above, like model output and even multiple models for problem decompositions. These include:

  • model represents an individual model, grouping together all the things relevant for itself.
  • output defines which Variables are output from the model.
  • report groups together multiple output objects.

Introduction to relationship classes

While Object Classes define all the objects or entities that make up a model, Relationship Classes define how those entities are related to each other. Thus, Relationship Classes hold no meaning on their own, and always include at least one object class.

Similar to Object Classes, each relationship class has a very specific purpose in SpineOpt.jl, and understanding the purpose of each relationship class is paramount. The Relationship Classes can be roughly divided into Systemic relationship classes, Structural relationship classes, and Meta relationship classes, again similar to Object Classes.

Systemic relationship classes

Systemic Relationship Classes define how Systemic object classes are related to each other, thus helping define the system to be modelled. Most of these relationships deal with which units and connections interact with which nodes, and how those interactions work. This essentially defines the possible commodity flows to be modelled. Systemic Relationship Classes include:

Structural relationship classes

Structural Relationship Classes primarily relate Structural object classes to Systemic object classes, defining what structures the individual parts of the system use. These are mostly used to determine the temporal and stochastic structures to be used in different parts of the modelled system, or custom User Constraints.

SpineOpt.jl has a very flexible temporal and stochastic structure, explained in detail in the Temporal Framework and Stochastic Framework sections of the documentation. Unfortunately, this flexibility requires quite a few different structural Relationship Classes, the most important of which are the following basic structural Relationship Classes:

Furthermore, there are also a number of advanced structural Relationship Classes, which are only necessary when using some of the optional features of SpineOpt.jl. For Investment Optimization, the following relationships control the stochastic and temporal structures of the investment variables:

For User Constraints, which are essentially generic data-driven custom constraints, the following relationships are used to control which variables are included and with what coefficients:

Meta relationship classes

Meta Relationship Classes are used for defining model-level settings, like which temporal blocks or stochastic structures are active, and what the model output is. These include:

Introduction to parameters

While the primary function of Object Classes and Relationship Classes is to define the system to be modelled and it's structure, Parameters exist to constrain them. Every parameter is attributed to at least one object class or relationship class, but some appear in many classes whenever they serve a similar purpose.

Parameters accept different types of values depending on their purpose, e.g. whether they act as a flag for some specific functionality or appear as a coefficient in Constraints, so understanding each parameter is key. Most coefficient-type Parameters accept constant, time series, and even stochastic time series form input, but there are some exceptions. Most flag-type Parameters, on the other hand, have a restricted list of acceptable values defined by their Parameter Value Lists.

The existence of some Constraints is controlled based on if the relevant Parameters are defined. As a rule-of-thumb, a constraint only gets generated if at least one of the Parameters appearing in it is defined, but one should refer to the appropriate Constraints and Parameters sections when in doubt.

Introduction to groups of objects

Groups of objects are used within SpineOpt for different purposes. To create a group of objects, simply right-click the corresponding Object Class in the Spine Toolbox database editor and select Add object group. Groups are essentially special objects, that act as a single handle for all of its members.

On the one hand, groups can be used in order to impose constraints on the aggregation of a variable, e.g. on the sum of multiple unit_flow variables. Constraints based on parameters associated with the unit__node__node, unit__to_node, unit__from_node, connection__node__node, connection__to_node, connection__from_node can generally be used for this kind of flow aggregation by defining the parameters on groups of objects, typically node groups. (with the exception of variable fixing parameters, e.g. fix_unit_flow, fix_connection_flow etc.). See for instance constraint_unit_flow_capacity.

On the other hand, a node group can be used to for PTDF based powerflows. Here a node group is used to enforce a nodal balance on system level, while suppressing the node balances at individual nodes. See also balance_type and the node balance constraint.

diff --git a/dev/concept_reference/unit/index.html b/dev/concept_reference/unit/index.html index 1f9a2341e4..f5a5750844 100644 --- a/dev/concept_reference/unit/index.html +++ b/dev/concept_reference/unit/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.

A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.

+- · SpineOpt.jl

A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.

A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.

The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.

diff --git a/dev/concept_reference/unit__commodity/index.html b/dev/concept_reference/unit__commodity/index.html index c457921078..d34b6aa881 100644 --- a/dev/concept_reference/unit__commodity/index.html +++ b/dev/concept_reference/unit__commodity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.

Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.

+- · SpineOpt.jl

To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.

Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.

diff --git a/dev/concept_reference/unit__from_node/index.html b/dev/concept_reference/unit__from_node/index.html index 15aa94ac0c..6a93dd2361 100644 --- a/dev/concept_reference/unit__from_node/index.html +++ b/dev/concept_reference/unit__from_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.

It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

+- · SpineOpt.jl

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.

It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

diff --git a/dev/concept_reference/unit__from_node__unit_constraint/index.html b/dev/concept_reference/unit__from_node__unit_constraint/index.html index c9c769f88e..1c3ba192dc 100644 --- a/dev/concept_reference/unit__from_node__unit_constraint/index.html +++ b/dev/concept_reference/unit__from_node__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit__from_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable to the specified unit from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__from_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint

+- · SpineOpt.jl

unit__from_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable to the specified unit from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__from_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint

diff --git a/dev/concept_reference/unit__investment_stochastic_structure/index.html b/dev/concept_reference/unit__investment_stochastic_structure/index.html index fb02989427..b20729bd08 100644 --- a/dev/concept_reference/unit__investment_stochastic_structure/index.html +++ b/dev/concept_reference/unit__investment_stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/unit__investment_temporal_block/index.html b/dev/concept_reference/unit__investment_temporal_block/index.html index cfaceafe81..068576ba75 100644 --- a/dev/concept_reference/unit__investment_temporal_block/index.html +++ b/dev/concept_reference/unit__investment_temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.

See also Investment Optimization

+- · SpineOpt.jl

unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.

See also Investment Optimization

diff --git a/dev/concept_reference/unit__node__node/index.html b/dev/concept_reference/unit__node__node/index.html index 24e1ee1ddc..298e252941 100644 --- a/dev/concept_reference/unit__node__node/index.html +++ b/dev/concept_reference/unit__node__node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.

In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.

+- · SpineOpt.jl

While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.

In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.

diff --git a/dev/concept_reference/unit__to_node/index.html b/dev/concept_reference/unit__to_node/index.html index 4634d166ea..6ac030b640 100644 --- a/dev/concept_reference/unit__to_node/index.html +++ b/dev/concept_reference/unit__to_node/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.

It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

+- · SpineOpt.jl

The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.

Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.

To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.

It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.

diff --git a/dev/concept_reference/unit__to_node__unit_constraint/index.html b/dev/concept_reference/unit__to_node__unit_constraint/index.html index 36aba34af3..2292f0601b 100644 --- a/dev/concept_reference/unit__to_node__unit_constraint/index.html +++ b/dev/concept_reference/unit__to_node__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit__to_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable from the specified unit to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__to_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint

+- · SpineOpt.jl

unit__to_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable from the specified unit to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__to_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint

diff --git a/dev/concept_reference/unit__unit_constraint/index.html b/dev/concept_reference/unit__unit_constraint/index.html index c4ac01d371..b54169e275 100644 --- a/dev/concept_reference/unit__unit_constraint/index.html +++ b/dev/concept_reference/unit__unit_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit__user_constraint is a two-dimensional relationship between a unit and a user_constraint. The relationship specifies that a variable or variable(s) associated only with the unit (not a unit_flow for example) are involved in the constraint. For example, the units_on_coefficient defined on unit__user_constraint specifies the coefficient of the unit's units_on variable in the specified user_constraint.

See also user_constraint

+- · SpineOpt.jl

unit__user_constraint is a two-dimensional relationship between a unit and a user_constraint. The relationship specifies that a variable or variable(s) associated only with the unit (not a unit_flow for example) are involved in the constraint. For example, the units_on_coefficient defined on unit__user_constraint specifies the coefficient of the unit's units_on variable in the specified user_constraint.

See also user_constraint

diff --git a/dev/concept_reference/unit_availability_factor/index.html b/dev/concept_reference/unit_availability_factor/index.html index 1f260868e1..fed78ca1a5 100644 --- a/dev/concept_reference/unit_availability_factor/index.html +++ b/dev/concept_reference/unit_availability_factor/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.

+- · SpineOpt.jl

To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.

diff --git a/dev/concept_reference/unit_capacity/index.html b/dev/concept_reference/unit_capacity/index.html index 5be75363bc..d1c935f134 100644 --- a/dev/concept_reference/unit_capacity/index.html +++ b/dev/concept_reference/unit_capacity/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/unit_conv_cap_to_flow/index.html b/dev/concept_reference/unit_conv_cap_to_flow/index.html index c60267bc20..b87e04deef 100644 --- a/dev/concept_reference/unit_conv_cap_to_flow/index.html +++ b/dev/concept_reference/unit_conv_cap_to_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable.

+- · SpineOpt.jl

The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable.

diff --git a/dev/concept_reference/unit_flow_coefficient/index.html b/dev/concept_reference/unit_flow_coefficient/index.html index ee314f3b6d..95cc68c0b7 100644 --- a/dev/concept_reference/unit_flow_coefficient/index.html +++ b/dev/concept_reference/unit_flow_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.

Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.

+- · SpineOpt.jl

The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.

Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.

diff --git a/dev/concept_reference/unit_idle_heat_rate/index.html b/dev/concept_reference/unit_idle_heat_rate/index.html index 5dd5057950..2af023c035 100644 --- a/dev/concept_reference/unit_idle_heat_rate/index.html +++ b/dev/concept_reference/unit_idle_heat_rate/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.

+- · SpineOpt.jl

Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.

diff --git a/dev/concept_reference/unit_incremental_heat_rate/index.html b/dev/concept_reference/unit_incremental_heat_rate/index.html index d7c155ea83..4f3a5aaa35 100644 --- a/dev/concept_reference/unit_incremental_heat_rate/index.html +++ b/dev/concept_reference/unit_incremental_heat_rate/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.

To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.

+- · SpineOpt.jl

Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.

To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.

diff --git a/dev/concept_reference/unit_investment_cost/index.html b/dev/concept_reference/unit_investment_cost/index.html index d8ad7c4229..1bda933dc2 100644 --- a/dev/concept_reference/unit_investment_cost/index.html +++ b/dev/concept_reference/unit_investment_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.

+- · SpineOpt.jl

By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.

diff --git a/dev/concept_reference/unit_investment_lifetime/index.html b/dev/concept_reference/unit_investment_lifetime/index.html index f46015ead7..b564718ca6 100644 --- a/dev/concept_reference/unit_investment_lifetime/index.html +++ b/dev/concept_reference/unit_investment_lifetime/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

See also Investment Optimization and candidate_units

+- · SpineOpt.jl

Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.

See also Investment Optimization and candidate_units

diff --git a/dev/concept_reference/unit_investment_variable_type/index.html b/dev/concept_reference/unit_investment_variable_type/index.html index 0426919060..9c3c3b58a5 100644 --- a/dev/concept_reference/unit_investment_variable_type/index.html +++ b/dev/concept_reference/unit_investment_variable_type/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.

See also Investment Optimization and candidate_units

+- · SpineOpt.jl

Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.

See also Investment Optimization and candidate_units

diff --git a/dev/concept_reference/unit_investment_variable_type_list/index.html b/dev/concept_reference/unit_investment_variable_type_list/index.html index ee7a23e63d..a2aba641ec 100644 --- a/dev/concept_reference/unit_investment_variable_type_list/index.html +++ b/dev/concept_reference/unit_investment_variable_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous.

+- · SpineOpt.jl

unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous.

diff --git a/dev/concept_reference/unit_online_variable_type_list/index.html b/dev/concept_reference/unit_online_variable_type_list/index.html index 3a66b2f8f1..3653de0e71 100644 --- a/dev/concept_reference/unit_online_variable_type_list/index.html +++ b/dev/concept_reference/unit_online_variable_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear.

+- · SpineOpt.jl

unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear.

diff --git a/dev/concept_reference/unit_start_flow/index.html b/dev/concept_reference/unit_start_flow/index.html index 90807b073f..2c47d7f70b 100644 --- a/dev/concept_reference/unit_start_flow/index.html +++ b/dev/concept_reference/unit_start_flow/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.

+- · SpineOpt.jl

Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.

diff --git a/dev/concept_reference/units_invested_avaiable_coefficient/index.html b/dev/concept_reference/units_invested_avaiable_coefficient/index.html index 74dd8a627a..42022880d3 100644 --- a/dev/concept_reference/units_invested_avaiable_coefficient/index.html +++ b/dev/concept_reference/units_invested_avaiable_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/units_invested_big_m_mga/index.html b/dev/concept_reference/units_invested_big_m_mga/index.html index 812116ca84..3c2ae6f0a6 100644 --- a/dev/concept_reference/units_invested_big_m_mga/index.html +++ b/dev/concept_reference/units_invested_big_m_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)

+- · SpineOpt.jl

The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)

diff --git a/dev/concept_reference/units_invested_coefficient/index.html b/dev/concept_reference/units_invested_coefficient/index.html index 9df3487355..3bdd93733c 100644 --- a/dev/concept_reference/units_invested_coefficient/index.html +++ b/dev/concept_reference/units_invested_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/units_invested_mga/index.html b/dev/concept_reference/units_invested_mga/index.html index e7b37d515e..01dd121e5f 100644 --- a/dev/concept_reference/units_invested_mga/index.html +++ b/dev/concept_reference/units_invested_mga/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.

+- · SpineOpt.jl

The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.

diff --git a/dev/concept_reference/units_on__stochastic_structure/index.html b/dev/concept_reference/units_on__stochastic_structure/index.html index 2f813d087d..e6e374ad97 100644 --- a/dev/concept_reference/units_on__stochastic_structure/index.html +++ b/dev/concept_reference/units_on__stochastic_structure/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.

The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

+- · SpineOpt.jl

The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.

The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.

diff --git a/dev/concept_reference/units_on__temporal_block/index.html b/dev/concept_reference/units_on__temporal_block/index.html index e1d0de7c81..1b7cf9086e 100644 --- a/dev/concept_reference/units_on__temporal_block/index.html +++ b/dev/concept_reference/units_on__temporal_block/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

+- · SpineOpt.jl

units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.

diff --git a/dev/concept_reference/units_on_coefficient/index.html b/dev/concept_reference/units_on_coefficient/index.html index 496e08d2ac..87cad75569 100644 --- a/dev/concept_reference/units_on_coefficient/index.html +++ b/dev/concept_reference/units_on_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/units_on_cost/index.html b/dev/concept_reference/units_on_cost/index.html index c81df62273..087e4a67e8 100644 --- a/dev/concept_reference/units_on_cost/index.html +++ b/dev/concept_reference/units_on_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.

+- · SpineOpt.jl

By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.

diff --git a/dev/concept_reference/units_on_non_anticipativity_time/index.html b/dev/concept_reference/units_on_non_anticipativity_time/index.html index 61fad88e3f..09b08455bd 100644 --- a/dev/concept_reference/units_on_non_anticipativity_time/index.html +++ b/dev/concept_reference/units_on_non_anticipativity_time/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.

This is intended to model "slow" units whose commitment decision needs to be taken in advance, e.g., in "day-ahead" mode, and cannot be changed afterwards.

+- · SpineOpt.jl

The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.

This is intended to model "slow" units whose commitment decision needs to be taken in advance, e.g., in "day-ahead" mode, and cannot be changed afterwards.

diff --git a/dev/concept_reference/units_started_up_coefficient/index.html b/dev/concept_reference/units_started_up_coefficient/index.html index 6d4ba1f351..89991d9306 100644 --- a/dev/concept_reference/units_started_up_coefficient/index.html +++ b/dev/concept_reference/units_started_up_coefficient/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/upward_reserve/index.html b/dev/concept_reference/upward_reserve/index.html index d0710a0735..6595b22ffa 100644 --- a/dev/concept_reference/upward_reserve/index.html +++ b/dev/concept_reference/upward_reserve/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.

+- · SpineOpt.jl

If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.

diff --git a/dev/concept_reference/user_constraint/index.html b/dev/concept_reference/user_constraint/index.html index a765b387bc..8eef89b192 100644 --- a/dev/concept_reference/user_constraint/index.html +++ b/dev/concept_reference/user_constraint/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.

Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.

For more information, see the dedicated article on User Constraints

+- · SpineOpt.jl

The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.

Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.

For more information, see the dedicated article on User Constraints

diff --git a/dev/concept_reference/variable_type_list/index.html b/dev/concept_reference/variable_type_list/index.html index 50281999aa..2398ce94a8 100644 --- a/dev/concept_reference/variable_type_list/index.html +++ b/dev/concept_reference/variable_type_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl
+- · SpineOpt.jl
diff --git a/dev/concept_reference/vom_cost/index.html b/dev/concept_reference/vom_cost/index.html index 5e03fa0825..c46ef0d70e 100644 --- a/dev/concept_reference/vom_cost/index.html +++ b/dev/concept_reference/vom_cost/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.

+- · SpineOpt.jl

By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.

diff --git a/dev/concept_reference/weight/index.html b/dev/concept_reference/weight/index.html index 3d9e06f25d..209706551f 100644 --- a/dev/concept_reference/weight/index.html +++ b/dev/concept_reference/weight/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so.

+- · SpineOpt.jl

The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so.

diff --git a/dev/concept_reference/weight_relative_to_parents/index.html b/dev/concept_reference/weight_relative_to_parents/index.html index 2b59b517c8..e755d90675 100644 --- a/dev/concept_reference/weight_relative_to_parents/index.html +++ b/dev/concept_reference/weight_relative_to_parents/index.html @@ -5,4 +5,4 @@ # If not a root `stochastic_scenario` -weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.

+weight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)

The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.

diff --git a/dev/concept_reference/window_weight/index.html b/dev/concept_reference/window_weight/index.html index 2a133d896c..6325abfb1d 100644 --- a/dev/concept_reference/window_weight/index.html +++ b/dev/concept_reference/window_weight/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.

To use weighted rolling representative periods Benders, do the following.

  • Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.
  • Specify window_weight as an array of n + 1 floating point values, representing the weight of each window.

Note that it the problem rolls n times, then you have n + 1 windows.

+- · SpineOpt.jl

The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.

To use weighted rolling representative periods Benders, do the following.

  • Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.
  • Specify window_weight as an array of n + 1 floating point values, representing the weight of each window.

Note that it the problem rolls n times, then you have n + 1 windows.

diff --git a/dev/concept_reference/write_lodf_file/index.html b/dev/concept_reference/write_lodf_file/index.html index a221ce4962..0e108c4a3f 100644 --- a/dev/concept_reference/write_lodf_file/index.html +++ b/dev/concept_reference/write_lodf_file/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.

+- · SpineOpt.jl

If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.

diff --git a/dev/concept_reference/write_mps_file/index.html b/dev/concept_reference/write_mps_file/index.html index e4c2bc4638..ea5b01b37c 100644 --- a/dev/concept_reference/write_mps_file/index.html +++ b/dev/concept_reference/write_mps_file/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter is deprecated and will be removed in a future version.

This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\_mps\_on\_no\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\_mps\_never, no file will be written

+- · SpineOpt.jl

This parameter is deprecated and will be removed in a future version.

This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\_mps\_on\_no\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\_mps\_never, no file will be written

diff --git a/dev/concept_reference/write_mps_file_list/index.html b/dev/concept_reference/write_mps_file_list/index.html index f5aeb784c9..9c37e8d86d 100644 --- a/dev/concept_reference/write_mps_file_list/index.html +++ b/dev/concept_reference/write_mps_file_list/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

This parameter value list is deprecated and will be removed in a future version.

Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\_mps\_on\_no\_solve, and write\_mps\_never.

+- · SpineOpt.jl

This parameter value list is deprecated and will be removed in a future version.

Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\_mps\_on\_no\_solve, and write\_mps\_never.

diff --git a/dev/concept_reference/write_ptdf_file/index.html b/dev/concept_reference/write_ptdf_file/index.html index 080d9bc3d4..5843b65352 100644 --- a/dev/concept_reference/write_ptdf_file/index.html +++ b/dev/concept_reference/write_ptdf_file/index.html @@ -1,2 +1,2 @@ -- · SpineOpt.jl

If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.

+- · SpineOpt.jl

If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.

diff --git a/dev/getting_started/archetypes/index.html b/dev/getting_started/archetypes/index.html index 138934376b..e9431d2aaa 100644 --- a/dev/getting_started/archetypes/index.html +++ b/dev/getting_started/archetypes/index.html @@ -1,2 +1,2 @@ -Archetypes · SpineOpt.jl

Archetypes

Archetypes are essentially ready-made templates for different aspects of SpineOpt.jl. They are intended to serve both as examples for how the data structure in SpineOpt.jl works, as well as pre-made modular parts that can be imported on top of existing model input data.

The templates/models/basic_model_template.json contains a ready-made template for simple energy system models, with uniform time resolution and deterministic stochastic structure. Essentially, it serves as a basis for testing how the modelled system is set up, without having to worry about setting up the temporal and stochastic structures.

The rest of the different archetypes are included under templates/archetypes in the SpineOpt.jl repository. Each archetype is stored as a .json file containing the necessary objects, relationships, and parameters to form a functioning pre-made part for a SpineOpt.jl model. The archetypes aren't completely plug-and-play, as there are always some relationships required to connect the archetype to the other input data correctly. Regardless, the following sections explain the different archetypes included in the SpineOpt.jl repository, as well as what steps the user needs to take to connect said archetype to their input data correctly.

Loading the SpineOpt Template and Archetypes into Your Model

To load the latest version of the SpineOpt template, in the Spine DB Editor, from the menu (three hirzontal bars in the top right), click on import as follows:

importing the SpineOpt Template

Change the file type to JSON and click on spineopt_template.json as follows:

importing the SpineOpt Template

Click on spineopttemplate.json and press Open. If you don't see spineopttemplate.json make sure you have navigated to Spine\SpineOpt.jl\templates.

Loading the latest version of the SpineOpt template in this way will update your datastore with the latest version of the data structure.

Branching Stochastic Tree

templates/archetypes/branching_stochastic_tree.json

This archetype contains the definitions required for an example stochastic_structure called branching, representing a branching scenario tree. The stochastic_structure starts out as a single stochastic_scenario called realistic, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. This archetype is the final product of following the steps in the Example of branching stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

Converging Stochastic Tree

templates/archetypes/converging_stochastic_tree.json

This archetype contains the definitions required for an example stochastic_structure called converging, representing a converging scenario tree (technically a directed acyclic graph DAG). The stochastic_structure starts out as a single stochastic_scenario called realization, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. Then, after 24 hours (1 day), these three forecasts converge into a single stochastic_scenario called converged_forecast. This archetype is the final product of following the steps in the Example of converging stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

Deterministic Stochastic Structure

templates/archetypes/deterministic_stochastic_structure.json

This archetype contains the definitions required for an example stochastic_structure called deterministic, representing a simple deterministic modelling case. The stochastic_structure contains only a single stochastic_scenario called realization, which continues indefinitely. This archetype is the final product of following the steps in the Example of deterministic stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

+Archetypes · SpineOpt.jl

Archetypes

Archetypes are essentially ready-made templates for different aspects of SpineOpt.jl. They are intended to serve both as examples for how the data structure in SpineOpt.jl works, as well as pre-made modular parts that can be imported on top of existing model input data.

The templates/models/basic_model_template.json contains a ready-made template for simple energy system models, with uniform time resolution and deterministic stochastic structure. Essentially, it serves as a basis for testing how the modelled system is set up, without having to worry about setting up the temporal and stochastic structures.

The rest of the different archetypes are included under templates/archetypes in the SpineOpt.jl repository. Each archetype is stored as a .json file containing the necessary objects, relationships, and parameters to form a functioning pre-made part for a SpineOpt.jl model. The archetypes aren't completely plug-and-play, as there are always some relationships required to connect the archetype to the other input data correctly. Regardless, the following sections explain the different archetypes included in the SpineOpt.jl repository, as well as what steps the user needs to take to connect said archetype to their input data correctly.

Loading the SpineOpt Template and Archetypes into Your Model

To load the latest version of the SpineOpt template, in the Spine DB Editor, from the menu (three hirzontal bars in the top right), click on import as follows:

importing the SpineOpt Template

Change the file type to JSON and click on spineopt_template.json as follows:

importing the SpineOpt Template

Click on spineopttemplate.json and press Open. If you don't see spineopttemplate.json make sure you have navigated to Spine\SpineOpt.jl\templates.

Loading the latest version of the SpineOpt template in this way will update your datastore with the latest version of the data structure.

Branching Stochastic Tree

templates/archetypes/branching_stochastic_tree.json

This archetype contains the definitions required for an example stochastic_structure called branching, representing a branching scenario tree. The stochastic_structure starts out as a single stochastic_scenario called realistic, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. This archetype is the final product of following the steps in the Example of branching stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

Converging Stochastic Tree

templates/archetypes/converging_stochastic_tree.json

This archetype contains the definitions required for an example stochastic_structure called converging, representing a converging scenario tree (technically a directed acyclic graph DAG). The stochastic_structure starts out as a single stochastic_scenario called realization, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. Then, after 24 hours (1 day), these three forecasts converge into a single stochastic_scenario called converged_forecast. This archetype is the final product of following the steps in the Example of converging stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

Deterministic Stochastic Structure

templates/archetypes/deterministic_stochastic_structure.json

This archetype contains the definitions required for an example stochastic_structure called deterministic, representing a simple deterministic modelling case. The stochastic_structure contains only a single stochastic_scenario called realization, which continues indefinitely. This archetype is the final product of following the steps in the Example of deterministic stochastics part of the Stochastic Framework section.

Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.

diff --git a/dev/getting_started/creating_your_own_model/index.html b/dev/getting_started/creating_your_own_model/index.html index 4ab32a32af..248126eb4a 100644 --- a/dev/getting_started/creating_your_own_model/index.html +++ b/dev/getting_started/creating_your_own_model/index.html @@ -1,2 +1,2 @@ -Creating Your Own Model · SpineOpt.jl

Creating Your Own Model

This part of the guide shows first an example how to insert objects and their parameter data. Then it shows what other objects, relationships and parameter data needs to be added for a very basic model. Lastly, the model instance is run.

This section explains the process of creating a SpineOpt.jl model from scratch in order to give you an understanding of the underlying principles of the data structure, etc. If you simply want to try something out quickly to see results, check out the Example Models section. Furthermore, if you're in a hurry, the Archetypes section provides you with some pre-made templates for the different parts of a SpineOpt.jl model to get you started quickly.

Creating a SpineOpt model instance

  • First, open the database editor by double-clicking the Input DB.
  • Right click on model in the Object tree.
  • Choose Add objects.
  • Then, add a model object by writing a name to the object name field. You can use e.g. instance.
  • Click ok.
  • The model object in SpineOpt is an abstraction that represents the model itself. Every SpineOpt database needs to have at least one model object.
  • The model object holds general information about the optimization. The whole range of functionalities is explained in Advanced Concepts chapter - in here a minimal set of parameters is used.

image

image

Add parameter values to the model instance

  • Select the model object instance from the object tree.
  • Go to the Object parameter value tab.
  • Every parameter value belongs to a specific alternative. This allows to hold multiple values for the same parameter of a particular object. The alternative values are used to create scenarios. Choose, Base for all parameter values (Base is required in Spine Toolbox - all other alternatives can be chosen freely).
  • Then define a model_start time and a model_end time.
    • Double-click on the empty row under parameter_name and select model_start.
    • A None should appear in value column.
    • To asign a start date value, right-click on None and open the editor (cannot be entered directly, since the datatype needs to be changed).
    • The parameter type of model_start is of type Datetime.
    • Set the value to e.g. 2019-01-01T00:00:00.
    • Proceed accordingly for the model_end.

image

Further reading on adding parameter values can be found here.

Add other necessary objects and parameter data for the objects.

  • Add all objects and their parameter data by replicating what has been done in the picture below. Do it the same way as explained above with the following caveats.
  • Whilst most object names can be freely defined by the user, there is one object name in the example below that needs to be written exactly since it is used internally by SpineOpt: unit_flow.
  • The parameter_name can be selected from a drop down menu.
  • The date time and time series parameter data can be added by using right-click to access the Edit... dialog. When creating the time series, use the fixed resolution with Start time of the model run and with 1h resolution. Then only values need to be entered (or copy pasted) and time stamps come automatically.
  • Parameter balance_type needs to have value balance_type_none in the gas node, since it allows the node to create energy (natural gas) against a price and therefore the energy balance is not maintained.

image

Define temporal and stochastic structures

  • To specify the temporal structure for SpineOpt, you need to define temporal_block objects. Think of a temporal_block as a distinctive way of 'slicing' time across the model horizon.
  • To link the temporal structure to the spatial structure, you need to specify node__temporal_block relationships, establishing which temporal__block applies to each node. This relationship is added by right-clicking the node__temporal_block in the relationship tree and then using the add relationships... dialog. Double clicking on an empty cell gives you the list of valid objects. The relationship name is automatically formed, but you can change it if that is desirable.
  • To keep things simple at this point, let's just define one temporal_block for our model and apply it to all nodes. We add the object hourly_temporal_block of type temporal_block following the same procedure as before and establish node__temporal_block relationships between node_gas and hourly_temporal_block, and electricity_node and hourly_temporal_block.
  • In practical terms, the above means that there energy flows over gas_node and electricity_node for each 'time-slice' comprised in hourly_temporal_block.
  • Similarly with the stochastic structure, each node is assigned a deterministic stochastic_structure.

Define the spatial structure

  • To specify the spatial structure for SpineOpt, you will need to use the node, unit, and connection objects added before.
  • Nodes can be understood as spatial aggregators. In combination with units and connections, they form the energy network.
  • Units in SpineOpt represent any kind of conversion process. As one example, a unit can represent a power plant that converts the flow of a commodity fuel into an electricity and/or heat flow.
  • Connections on the other hand describe the transport of goods from one location to another. Electricity lines and gas pipelines are examples of such connections. This example does not use connections.
  • The database should have an object gas_turbine for the unit object class and objects node_gas and node_elec for the node object class.
  • Next, define how the unit and the nodes interact with each other: create a unit__from_node relationship between gas_turbine and node_gas, and unit__to_node relationships between gas_turbine and node_elec.
  • In practical terms, the above means that there is an energy flow going from node_gas into node_elec, through the gas_turbine.

Add remaining relationships and parameter data for the relationships.

  • Similar to adding the objects and their parameter data, add the relationships and their parameter data based on the picture below.
  • The capacity of the gas_turbine has to be sufficient to meet the highest demand for electricity, otherwise the model will be infeasible (it is possible to set penalty values, but they are not included in this example).
  • The parameter fix_ratio_in_out_unit_flow forces the ratio between an input and output flow to be a constant. This is one way to establish an efficiency for a conversion process.

image

Run the model

  • Select SpineOpt
  • Press Execute selection.

image

If it fails

  • Double-check that the data is correct
  • Try to see what the problem might be
  • Ask help from the discussion forum

Explore the results

  • Double-clicking the Results database.

image

Create and run scenarios and build the model further

  • Create a new alternative
  • Add parameter data for the new alternative
  • Connect alternatives under a scenario. Toolbox modifies Base data with the data from the alternatives in the same scenario.
  • Execute multiple scenarios in parallel. First run in a new Julia instance will need to compile SpineOpt taking some time.

image

image

+Creating Your Own Model · SpineOpt.jl

Creating Your Own Model

This part of the guide shows first an example how to insert objects and their parameter data. Then it shows what other objects, relationships and parameter data needs to be added for a very basic model. Lastly, the model instance is run.

This section explains the process of creating a SpineOpt.jl model from scratch in order to give you an understanding of the underlying principles of the data structure, etc. If you simply want to try something out quickly to see results, check out the Example Models section. Furthermore, if you're in a hurry, the Archetypes section provides you with some pre-made templates for the different parts of a SpineOpt.jl model to get you started quickly.

Creating a SpineOpt model instance

  • First, open the database editor by double-clicking the Input DB.
  • Right click on model in the Object tree.
  • Choose Add objects.
  • Then, add a model object by writing a name to the object name field. You can use e.g. instance.
  • Click ok.
  • The model object in SpineOpt is an abstraction that represents the model itself. Every SpineOpt database needs to have at least one model object.
  • The model object holds general information about the optimization. The whole range of functionalities is explained in Advanced Concepts chapter - in here a minimal set of parameters is used.

image

image

Add parameter values to the model instance

  • Select the model object instance from the object tree.
  • Go to the Object parameter value tab.
  • Every parameter value belongs to a specific alternative. This allows to hold multiple values for the same parameter of a particular object. The alternative values are used to create scenarios. Choose, Base for all parameter values (Base is required in Spine Toolbox - all other alternatives can be chosen freely).
  • Then define a model_start time and a model_end time.
    • Double-click on the empty row under parameter_name and select model_start.
    • A None should appear in value column.
    • To asign a start date value, right-click on None and open the editor (cannot be entered directly, since the datatype needs to be changed).
    • The parameter type of model_start is of type Datetime.
    • Set the value to e.g. 2019-01-01T00:00:00.
    • Proceed accordingly for the model_end.

image

Further reading on adding parameter values can be found here.

Add other necessary objects and parameter data for the objects.

  • Add all objects and their parameter data by replicating what has been done in the picture below. Do it the same way as explained above with the following caveats.
  • Whilst most object names can be freely defined by the user, there is one object name in the example below that needs to be written exactly since it is used internally by SpineOpt: unit_flow.
  • The parameter_name can be selected from a drop down menu.
  • The date time and time series parameter data can be added by using right-click to access the Edit... dialog. When creating the time series, use the fixed resolution with Start time of the model run and with 1h resolution. Then only values need to be entered (or copy pasted) and time stamps come automatically.
  • Parameter balance_type needs to have value balance_type_none in the gas node, since it allows the node to create energy (natural gas) against a price and therefore the energy balance is not maintained.

image

Define temporal and stochastic structures

  • To specify the temporal structure for SpineOpt, you need to define temporal_block objects. Think of a temporal_block as a distinctive way of 'slicing' time across the model horizon.
  • To link the temporal structure to the spatial structure, you need to specify node__temporal_block relationships, establishing which temporal__block applies to each node. This relationship is added by right-clicking the node__temporal_block in the relationship tree and then using the add relationships... dialog. Double clicking on an empty cell gives you the list of valid objects. The relationship name is automatically formed, but you can change it if that is desirable.
  • To keep things simple at this point, let's just define one temporal_block for our model and apply it to all nodes. We add the object hourly_temporal_block of type temporal_block following the same procedure as before and establish node__temporal_block relationships between node_gas and hourly_temporal_block, and electricity_node and hourly_temporal_block.
  • In practical terms, the above means that there energy flows over gas_node and electricity_node for each 'time-slice' comprised in hourly_temporal_block.
  • Similarly with the stochastic structure, each node is assigned a deterministic stochastic_structure.

Define the spatial structure

  • To specify the spatial structure for SpineOpt, you will need to use the node, unit, and connection objects added before.
  • Nodes can be understood as spatial aggregators. In combination with units and connections, they form the energy network.
  • Units in SpineOpt represent any kind of conversion process. As one example, a unit can represent a power plant that converts the flow of a commodity fuel into an electricity and/or heat flow.
  • Connections on the other hand describe the transport of goods from one location to another. Electricity lines and gas pipelines are examples of such connections. This example does not use connections.
  • The database should have an object gas_turbine for the unit object class and objects node_gas and node_elec for the node object class.
  • Next, define how the unit and the nodes interact with each other: create a unit__from_node relationship between gas_turbine and node_gas, and unit__to_node relationships between gas_turbine and node_elec.
  • In practical terms, the above means that there is an energy flow going from node_gas into node_elec, through the gas_turbine.

Add remaining relationships and parameter data for the relationships.

  • Similar to adding the objects and their parameter data, add the relationships and their parameter data based on the picture below.
  • The capacity of the gas_turbine has to be sufficient to meet the highest demand for electricity, otherwise the model will be infeasible (it is possible to set penalty values, but they are not included in this example).
  • The parameter fix_ratio_in_out_unit_flow forces the ratio between an input and output flow to be a constant. This is one way to establish an efficiency for a conversion process.

image

Run the model

  • Select SpineOpt
  • Press Execute selection.

image

If it fails

  • Double-check that the data is correct
  • Try to see what the problem might be
  • Ask help from the discussion forum

Explore the results

  • Double-clicking the Results database.

image

Create and run scenarios and build the model further

  • Create a new alternative
  • Add parameter data for the new alternative
  • Connect alternatives under a scenario. Toolbox modifies Base data with the data from the alternatives in the same scenario.
  • Execute multiple scenarios in parallel. First run in a new Julia instance will need to compile SpineOpt taking some time.

image

image

diff --git a/dev/getting_started/installation/index.html b/dev/getting_started/installation/index.html index 7f134fe2f4..7fc808c682 100644 --- a/dev/getting_started/installation/index.html +++ b/dev/getting_started/installation/index.html @@ -2,4 +2,4 @@ Installation · SpineOpt.jl

Installation

Compatibility

This package requires Julia 1.2 or later.

Installation

If you haven't yet installed the tools yet, please follow the installation guides:

  • For Spine Toolbox: https://github.com/spine-tools/SpineOpt.jl#installation
  • For SpineOpt: https://github.com/spine-tools/Spine-Toolbox#installation

If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.

  • For Spine Toolbox:
- If installed with pipx, then use `python -m pipx upgrade spinetoolbox`
 - If installed from sources using git, then<br>
     `git pull`<br>
-	`python -m pip install -U -r requirements.txt`<br>
  • For SpineOpt: https://github.com/spine-tools/SpineOpt.jl#upgrading
+ `python -m pip install -U -r requirements.txt`<br> diff --git a/dev/getting_started/output_data/index.html b/dev/getting_started/output_data/index.html index efe983e369..974ed33b26 100644 --- a/dev/getting_started/output_data/index.html +++ b/dev/getting_started/output_data/index.html @@ -1,2 +1,2 @@ -Managing Outputs · SpineOpt.jl

Managing Output Data

Once a model is created and successfully run, it will hopefully produce results and output data. This section covers how the writing of output data is controlled and managed.

Specifying Your Output Data Store

In your workflow (for more details see Setting up a workflow for SpineOpt in Spine Toolbox) you will normally have a output datastore connected to your RunSpineOpt workflow tool. This is where your output data will be written. If no output datastore is specified, the results will be written by default to the input datastore. However, it is generally preferable to define a separate output data store for results. See Setting up a workflow for SpineOpt in Spine Toolbox for the steps to add an output datastore to your workflow)

Specifying Outputs to Write

Outputting of results to the output datastore is controlled using the output and report object classes. To output a specific variable to the output datastore, we need to create an output object of the same name. For example, to output the unit_flow variable, we must create an output object named unit_flow. The SpineOpt template contains output objects for most problem variables and importing or re-importing the SpineOpt template will add these to your input datastore. So it is probable these output objects will exist already in your input datastore. Once the output objects exist in your model, they must then be added to a report object by creating an report__output relationship

Creating Reports

Reports are essentially a collection of outputs that can be written to an output datastore. Any number of report objects can be created. We add output items to a report by creating report__output relationships between the output objects we want included and the desired report object. Finally, to write a specic report to the output database, we must create a model__report relationship for each report object we want included in the output datastore.

Reporting of Input Parameters

In addition to writing results as outputs to a datastore, SpineOpt can also report input parameter data. To allow specific input parameters to be included in a report, they must be first added as output objects with a name corresponding exactly to the parameter name. For example, to allow the demand parameter to be included in a report, there must be a correspondingly named output object called demand. Similarly to outputs, to include an input parameter in a report, we must create a report__output relationship between the output object representing the input parameter (e.g. demand) and the desired report object.

Reporting of Dual Values

To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's marginal value to be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.

To report the reduced_cost() for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of unitson in the final fixed LP to be written to the output db. Finally, if any constraint duals or reducedcost values are requested via a report, calculate_duals is set to true and the final fixed LP solve is triggered.

Output Data Temporal Resolution

To control the resolution of report data (both output data and input data appearing in reports), we use the output_resolution output parameter. For the specific output (or input), this indicates the resolution at which the values should be reported. If output_resolution is null (the default), results are reported at the highest available resolution that will follow from the temporal structure of the model. If output_resolution is a duration value, then the average value is reported.

Output Data Structure

The structure of the output data will follow the structure of the input data with the inclusion of additional dimensions as described below:

  • The report object to which the output data items belong will be added as a dimension
  • The relevant stochastic scenario will be added as a dimension to all output data items. This allows for stochastic data to be written to the output datastore. However, in deterministic models, the single deterministic scenario will still appear as an additional dimension
  • For unit flows, the flow direction is added as a dimension to the output.

Example: unit_flow

For example, consider the unit_flow) optimisation variable. This variable is dimensioned on the unit__to_node and unit__from_node relationships. In the output datastore, the report, stochastic_scenario and flow direction are added as additional dimensions. Therefore, unit__to_node values will appear in the output datastore as timeseries parameters associated with the report__unit__node__direction__stochastic_scenario relationship as shown below.

image

To view the data, simply double-click on the timeseries value

Example: units_on

Consider the units_on) optimisation variable. This variable is dimensioned on the unit object class. In the output datastore, the report and stochastic_scenario are added as additional dimensions. Therefore, units_on values will appear in the output datastore as timeseries parameters associated with the report__unit__stochastic_scenario relationship as shown below.

image

To view the data, simply double-click on the timeseries value

Alternatives and Multiple Model Runs

  • All outputs from a single run of a model will be tagged with a unique "alternative". Alternatives allow multiple values to be specified for the same parameter. If a model is run multiple times, the results will be appended to the output datastore with a new alternative which uniquely identifies the scenario and model run. This is convenient as it allows results from multiple runs and for multiple scenarios to be viewed and compared simultaneously. If a specific altnernative is not selected (the default condition) the results for all alternatives will be visible. If a single altnerative is selected or multiple alternatives are selected in the altnerative tree, then only the results for the selected alternatives will be shown.

In the example below, the relationship class report__unit__stochastic_scenario is selected in the relationship treem therefore results for that relationship class are showing in the relationship parameter pane. Furthermore, in the alternative tree, the alternative 10h TP Load _Reun SpineOpt... is selected, meaning only results for that alternative are being displayed.

image

Output Writing Summary

  • We need an output object in our intput datastore for each variable or marginal value we want included in a report
  • Inputs data can also be reported. As above, we need to create an output object named after the input parameter we want reported
  • We need to create a report object to contain our desired outputs (or input parameters) which are added to our report via report__output relationships
  • We need to create a model__report object to write a specific report to the output datastore.
  • The temporal resolution of outputs (which may also be input parameters) is controlled by the output_resolution output duration parameter. If null, the highest available resolution is reported, otherwise the average is reported over the desired duration.
  • Additional dimensions are added to the output data such as the report object, stochastic_scenario and, in the case of unit_flow, the flow direction.
  • Model outputs are tagged with altnernatives that are unique to the model run and scenario that generated them
+Managing Outputs · SpineOpt.jl

Managing Output Data

Once a model is created and successfully run, it will hopefully produce results and output data. This section covers how the writing of output data is controlled and managed.

Specifying Your Output Data Store

In your workflow (for more details see Setting up a workflow for SpineOpt in Spine Toolbox) you will normally have a output datastore connected to your RunSpineOpt workflow tool. This is where your output data will be written. If no output datastore is specified, the results will be written by default to the input datastore. However, it is generally preferable to define a separate output data store for results. See Setting up a workflow for SpineOpt in Spine Toolbox for the steps to add an output datastore to your workflow)

Specifying Outputs to Write

Outputting of results to the output datastore is controlled using the output and report object classes. To output a specific variable to the output datastore, we need to create an output object of the same name. For example, to output the unit_flow variable, we must create an output object named unit_flow. The SpineOpt template contains output objects for most problem variables and importing or re-importing the SpineOpt template will add these to your input datastore. So it is probable these output objects will exist already in your input datastore. Once the output objects exist in your model, they must then be added to a report object by creating an report__output relationship

Creating Reports

Reports are essentially a collection of outputs that can be written to an output datastore. Any number of report objects can be created. We add output items to a report by creating report__output relationships between the output objects we want included and the desired report object. Finally, to write a specic report to the output database, we must create a model__report relationship for each report object we want included in the output datastore.

Reporting of Input Parameters

In addition to writing results as outputs to a datastore, SpineOpt can also report input parameter data. To allow specific input parameters to be included in a report, they must be first added as output objects with a name corresponding exactly to the parameter name. For example, to allow the demand parameter to be included in a report, there must be a correspondingly named output object called demand. Similarly to outputs, to include an input parameter in a report, we must create a report__output relationship between the output object representing the input parameter (e.g. demand) and the desired report object.

Reporting of Dual Values

To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's marginal value to be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.

To report the reduced_cost() for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of unitson in the final fixed LP to be written to the output db. Finally, if any constraint duals or reducedcost values are requested via a report, calculate_duals is set to true and the final fixed LP solve is triggered.

Output Data Temporal Resolution

To control the resolution of report data (both output data and input data appearing in reports), we use the output_resolution output parameter. For the specific output (or input), this indicates the resolution at which the values should be reported. If output_resolution is null (the default), results are reported at the highest available resolution that will follow from the temporal structure of the model. If output_resolution is a duration value, then the average value is reported.

Output Data Structure

The structure of the output data will follow the structure of the input data with the inclusion of additional dimensions as described below:

  • The report object to which the output data items belong will be added as a dimension
  • The relevant stochastic scenario will be added as a dimension to all output data items. This allows for stochastic data to be written to the output datastore. However, in deterministic models, the single deterministic scenario will still appear as an additional dimension
  • For unit flows, the flow direction is added as a dimension to the output.

Example: unit_flow

For example, consider the unit_flow) optimisation variable. This variable is dimensioned on the unit__to_node and unit__from_node relationships. In the output datastore, the report, stochastic_scenario and flow direction are added as additional dimensions. Therefore, unit__to_node values will appear in the output datastore as timeseries parameters associated with the report__unit__node__direction__stochastic_scenario relationship as shown below.

image

To view the data, simply double-click on the timeseries value

Example: units_on

Consider the units_on) optimisation variable. This variable is dimensioned on the unit object class. In the output datastore, the report and stochastic_scenario are added as additional dimensions. Therefore, units_on values will appear in the output datastore as timeseries parameters associated with the report__unit__stochastic_scenario relationship as shown below.

image

To view the data, simply double-click on the timeseries value

Alternatives and Multiple Model Runs

  • All outputs from a single run of a model will be tagged with a unique "alternative". Alternatives allow multiple values to be specified for the same parameter. If a model is run multiple times, the results will be appended to the output datastore with a new alternative which uniquely identifies the scenario and model run. This is convenient as it allows results from multiple runs and for multiple scenarios to be viewed and compared simultaneously. If a specific altnernative is not selected (the default condition) the results for all alternatives will be visible. If a single altnerative is selected or multiple alternatives are selected in the altnerative tree, then only the results for the selected alternatives will be shown.

In the example below, the relationship class report__unit__stochastic_scenario is selected in the relationship treem therefore results for that relationship class are showing in the relationship parameter pane. Furthermore, in the alternative tree, the alternative 10h TP Load _Reun SpineOpt... is selected, meaning only results for that alternative are being displayed.

image

Output Writing Summary

  • We need an output object in our intput datastore for each variable or marginal value we want included in a report
  • Inputs data can also be reported. As above, we need to create an output object named after the input parameter we want reported
  • We need to create a report object to contain our desired outputs (or input parameters) which are added to our report via report__output relationships
  • We need to create a model__report object to write a specific report to the output datastore.
  • The temporal resolution of outputs (which may also be input parameters) is controlled by the output_resolution output duration parameter. If null, the highest available resolution is reported, otherwise the average is reported over the desired duration.
  • Additional dimensions are added to the output data such as the report object, stochastic_scenario and, in the case of unit_flow, the flow direction.
  • Model outputs are tagged with altnernatives that are unique to the model run and scenario that generated them
diff --git a/dev/getting_started/setup_workflow/index.html b/dev/getting_started/setup_workflow/index.html index 04c29d7763..679c43fe79 100644 --- a/dev/getting_started/setup_workflow/index.html +++ b/dev/getting_started/setup_workflow/index.html @@ -1,4 +1,4 @@ Setting up a workflow · SpineOpt.jl

Setting up a workflow for SpineOpt in Spine Toolbox

The next steps will set up a SpineOpt specific input database by creating a new Spine database, loading a blank SpineOpt template, connecting it to a SpineOpt instance and setting up a database for model results.

  • Create a new Spine Toolbox project in an empty folder of your choice: File –> New project...
  • Create the input database
    • Drag an empty Data store from the toolbar to the Design View.
    • Give it a name like "Input DB".
    • Select SQL database dialect (sqlite is a local file and works without a server).
    • Click New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite).
    • For more information about creating and managing Spine Toolbox database, see the documentation

image

image

  • Fill the Input DB with SpineOpt data format either by:
    • Drag a tool Load template from the SpineOpt ribbon to the Design View.
    • Connect an arrow from the Load template to the new Input DB.
    • Make sure the Load template item from the Design view is selected (then you can edit the properties of that workflow item in the Tool properties window.
    • Add the url link in Available resources to the Tool arguments - you are passing the database address as a command line argument to the load_template.jl script so that it knows where to store the output.
    • Then execute the Load template tool. Please note that this process uses SpineOpt to generate the data structure. It takes time, since everything is compiled when running a tool in Julia for the first time in each Julia session. You may also see lot of messages and warnings concernging the compilation, but they should be benign.

image

image

image

image

  • ...or by:
    • Start Julia (you can start a separate Julia console in Spine Toolbox: go to Consoles –> Start Julia Console).
    • Copy the URL address of the Data Store from the 'Data Store Properties' –> a copy icon at the bottom.
    • Then run the following script with the right URL address pasted. The process uses SpineOpt itself to build the database structure. Please note that 'using SpineOpt' for the first time for each Julia session takes time - everything is being compiled.
      • Known issue: On Windows, the backslash between directories need to be changed to a double forward slash.
julia> using SpineOpt
 
-julia> SpineOpt.import_data("copied URL address, inside these quotes", SpineOpt.template(), "Load SpineOpt template")
  • Drag SpineOpt tool icon to the Design view.
  • Connect an arrow from the Input DB to SpineOpt.

image

  • Create a database for results
    • Drag a new Data store from the toolbar to the Design View.
    • You can rename it to e.g. Results. Select SQL database dialect (sqlite is a local file and works without a server).
    • Click New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite).
    • Connect an arrow from the SpineOpt to Results.

image

  • Select SpineOpt tool in the Design view.
  • Add the url link for the input data store and the output data store from Available resources to the Tool arguments (in that order).

image

SpineOpt would be ready to run, but for the Input DB, which is empty of content (it's just a template that contains a SpineOpt specific data structure). The next step goes through setting up and running a simple toy model.

+julia> SpineOpt.import_data("copied URL address, inside these quotes", SpineOpt.template(), "Load SpineOpt template")

image

image

image

SpineOpt would be ready to run, but for the Input DB, which is empty of content (it's just a template that contains a SpineOpt specific data structure). The next step goes through setting up and running a simple toy model.

diff --git a/dev/how_to/change_the_solver/index.html b/dev/how_to/change_the_solver/index.html index 94771f382a..69c7147a31 100644 --- a/dev/how_to/change_the_solver/index.html +++ b/dev/how_to/change_the_solver/index.html @@ -1,2 +1,2 @@ -Change the solver · SpineOpt.jl

If you want to change the solver for your optimization problem in SpineOpt, here is some guidance:

  • You can change the solvers in your input datastore using the db_lp_solver and db_mip_solver parameter values of the model object.
  • You can specify solver options via the db_lp_solver_options and db_mip_solver_options parameters respectively. These are map parameters where the first key is the solver name exactly as the db_mip_solver or db_lp_solver name, the second key is the solver option name and the value is the option value.
  • You can get a head start by copying the default map values for db_lp_solver_options and db_mip_solver_options. You can access the default values by clicking on the 'Object parameter definition' tab.
  • If you were trying to change the solver using the arguments to run_spineopt(), this is not the recommended way and will soon be deprecated.
  • The solver name corresponds to the name of the Julia package that you will need to install. Some like HiGHs.jl are self contained and include the binaries. Others like CPLEX.jl and Gurobi.jl you will need to point the package to your locally installed binaries - the julia packages have the instructions to do this.

The first option is the easiest. The more advanced way of using the solver options is illustrated below.

Set the model parameter values to choose the solvers and set the solver options:

image

This is what the solver options map parameter value looks like:

image

To get a head start with solver options, you can copy their default map values from the parameter definition tab like this:

image

+Change the solver · SpineOpt.jl

If you want to change the solver for your optimization problem in SpineOpt, here is some guidance:

  • You can change the solvers in your input datastore using the db_lp_solver and db_mip_solver parameter values of the model object.
  • You can specify solver options via the db_lp_solver_options and db_mip_solver_options parameters respectively. These are map parameters where the first key is the solver name exactly as the db_mip_solver or db_lp_solver name, the second key is the solver option name and the value is the option value.
  • You can get a head start by copying the default map values for db_lp_solver_options and db_mip_solver_options. You can access the default values by clicking on the 'Object parameter definition' tab.
  • If you were trying to change the solver using the arguments to run_spineopt(), this is not the recommended way and will soon be deprecated.
  • The solver name corresponds to the name of the Julia package that you will need to install. Some like HiGHs.jl are self contained and include the binaries. Others like CPLEX.jl and Gurobi.jl you will need to point the package to your locally installed binaries - the julia packages have the instructions to do this.

The first option is the easiest. The more advanced way of using the solver options is illustrated below.

Set the model parameter values to choose the solvers and set the solver options:

image

This is what the solver options map parameter value looks like:

image

To get a head start with solver options, you can copy their default map values from the parameter definition tab like this:

image

diff --git a/dev/how_to/define_an_efficiency/index.html b/dev/how_to/define_an_efficiency/index.html index 079582c62b..ce9c46b313 100644 --- a/dev/how_to/define_an_efficiency/index.html +++ b/dev/how_to/define_an_efficiency/index.html @@ -1,2 +1,2 @@ -Define an efficiency · SpineOpt.jl

How to define an efficiency

relationships between the inputs and outputs of a unit

The image below shows an overview of the possible relationships between the inputs and outputs of a unit.

image

image

The key capability requirements are:

  • Easily define arbitrary numbers of input and output flows
  • Easily create piecewise affine linear relationships between any two flows
  • Anything more complicated can be done via user_constraints

unit__node__node relationship

image

The unit__node__node relationship allows you to constrain two nodes to each other via a number of different parameters.:

  • unit_incremental_heat_rate: Input_flow = unit_incremental_heat_rate * output_flow + unit_idle_heat_rate * units_on. It can be piecewise linear, used in conjunction with operating_points with monotonically increasing coefficients (not enforced). Used in conjunction with unit_idle_heat_rate triggers a fixed flow when the unit is online and unit_start_flow triggers a flow on a unit start (start fuel consumption)
  • fix_ratio_out_in_unit_flow: equivalent to an efficiency. Output_flow = fix_ratio_out_in_unit_flow x output_flow + fix_units_on_coefficient_out_in * units_on. Ordering of the nodes in the unit__node__node relationship matters. The first node will be the output flow and the second node will be treated as the input flow (consistently with the out_in in the parameter name. A units_on coefficient is added with fix_units_on_coefficient_out_in,
  • In addition to fix_ratio_out_in_unit_flow you have [constraint]_ratio_[direction1]_[direction2]_unit_flow where constraint can be min, max or fix and determines the sense of the constraint (max: <, min: >, fix: =) while direction1 and direction2 are used to interpret the direction of the flows involved. In signifies an input flow to the unit while out signifies an output flow from the unit. For each of these parameters, there is a corresponding [constraint]_[direction1]_[direction2]_units_on_coefficient. For example: max_ratio_in_out_unit_flow creates the following constraint:

input_flow < max_ratio_in_out_unit_flow * output_flow + max_units_on_coefficient_in_out * units_on

real world example: Compressed Air Energy Storage

To give a feeling for why these functionalities are useful, consider the following real world example for Compressed Air Energy Storage:

image

known issues

That does not mean that this implementation is perfect; there are some known issues:

  • Multiple ways to do the same thing (kind of)
  • The ordering of nodes in unit__node__node relationship matters and this can be confusing
  • When specifying a unit__node__node relationship, currently toolbox doesn’t constrain a user to choosing nodes that are connected to the unit. It’s possible to create a unit__node__node relationship between a unit and nodes where there are no flows. We actually need to define a relationship between two flows, which is really a relationship between a unit__[to/from]_node relationship and a unit__[to/from]_node relationship.
  • There is a long list of parameters (24 in total) [fix/max/min]_ratio_[in/out]_[in/out]_[unit_flow/units_on_coefficient]
  • Incremental_heat_rate supports piecewise linear but the ratio constraints don’t
+Define an efficiency · SpineOpt.jl

How to define an efficiency

relationships between the inputs and outputs of a unit

The image below shows an overview of the possible relationships between the inputs and outputs of a unit.

image

image

The key capability requirements are:

  • Easily define arbitrary numbers of input and output flows
  • Easily create piecewise affine linear relationships between any two flows
  • Anything more complicated can be done via user_constraints

unit__node__node relationship

image

The unit__node__node relationship allows you to constrain two nodes to each other via a number of different parameters.:

  • unit_incremental_heat_rate: Input_flow = unit_incremental_heat_rate * output_flow + unit_idle_heat_rate * units_on. It can be piecewise linear, used in conjunction with operating_points with monotonically increasing coefficients (not enforced). Used in conjunction with unit_idle_heat_rate triggers a fixed flow when the unit is online and unit_start_flow triggers a flow on a unit start (start fuel consumption)
  • fix_ratio_out_in_unit_flow: equivalent to an efficiency. Output_flow = fix_ratio_out_in_unit_flow x output_flow + fix_units_on_coefficient_out_in * units_on. Ordering of the nodes in the unit__node__node relationship matters. The first node will be the output flow and the second node will be treated as the input flow (consistently with the out_in in the parameter name. A units_on coefficient is added with fix_units_on_coefficient_out_in,
  • In addition to fix_ratio_out_in_unit_flow you have [constraint]_ratio_[direction1]_[direction2]_unit_flow where constraint can be min, max or fix and determines the sense of the constraint (max: <, min: >, fix: =) while direction1 and direction2 are used to interpret the direction of the flows involved. In signifies an input flow to the unit while out signifies an output flow from the unit. For each of these parameters, there is a corresponding [constraint]_[direction1]_[direction2]_units_on_coefficient. For example: max_ratio_in_out_unit_flow creates the following constraint:

input_flow < max_ratio_in_out_unit_flow * output_flow + max_units_on_coefficient_in_out * units_on

real world example: Compressed Air Energy Storage

To give a feeling for why these functionalities are useful, consider the following real world example for Compressed Air Energy Storage:

image

known issues

That does not mean that this implementation is perfect; there are some known issues:

  • Multiple ways to do the same thing (kind of)
  • The ordering of nodes in unit__node__node relationship matters and this can be confusing
  • When specifying a unit__node__node relationship, currently toolbox doesn’t constrain a user to choosing nodes that are connected to the unit. It’s possible to create a unit__node__node relationship between a unit and nodes where there are no flows. We actually need to define a relationship between two flows, which is really a relationship between a unit__[to/from]_node relationship and a unit__[to/from]_node relationship.
  • There is a long list of parameters (24 in total) [fix/max/min]_ratio_[in/out]_[in/out]_[unit_flow/units_on_coefficient]
  • Incremental_heat_rate supports piecewise linear but the ratio constraints don’t
diff --git a/dev/how_to/print_the_model/index.html b/dev/how_to/print_the_model/index.html index 879fb11231..64f94ab7b0 100644 --- a/dev/how_to/print_the_model/index.html +++ b/dev/how_to/print_the_model/index.html @@ -1,2 +1,2 @@ -Print the model · SpineOpt.jl

How to print the model

As the SpineOpt model formulation is quite complex and can change depending on a few parameters (some parts of the formulation can be activated or deactivated), it can be useful to print the model that SpineOpt sends to JuMP. There are a few ways to do this.

The model that SpineOpt sends to JuMP can be saved to a file. It is not the nicest file to read but at the very least you can find the used variables and parameter values.

To write that file you need to set the write_mps_file parameter of the model object to write_mps_always.

SpineOpt will write the file to the working directory. If you are using Spine Toolbox that working directory will be the Spine Toolbox work folder which is typically in your user directory e.g. C:\Users\username\.spinetoolbox\work\run_spineopt_gibberish_toolbox\model_diagnostics.mps

An alternative approach is to directly use the write_model_file(m, filename) command in which m is a reference to your model and filename is the filename you want the model file written to.

m can be obtained from the call to run_spineopt(). In Spine Toolbox, more particularly the run_SpineOpt tool, you will have m=run_spineopt(). That means that you can call write_model_file(m,filename) in the console once SpineOpt has finished executing and the console remains open.

In either case, here are some tips if you are using this file for debugging. The file can be very large so often it is helpful to create a minimum example of your model with only one or two timesteps. Also, in the call to run_spineopt() you can add the keyword argument optimize=false so it will just build the model and not attempt to solve it.

+Print the model · SpineOpt.jl

How to print the model

As the SpineOpt model formulation is quite complex and can change depending on a few parameters (some parts of the formulation can be activated or deactivated), it can be useful to print the model that SpineOpt sends to JuMP. There are a few ways to do this.

The model that SpineOpt sends to JuMP can be saved to a file. It is not the nicest file to read but at the very least you can find the used variables and parameter values.

To write that file you need to set the write_mps_file parameter of the model object to write_mps_always.

SpineOpt will write the file to the working directory. If you are using Spine Toolbox that working directory will be the Spine Toolbox work folder which is typically in your user directory e.g. C:\Users\username\.spinetoolbox\work\run_spineopt_gibberish_toolbox\model_diagnostics.mps

An alternative approach is to directly use the write_model_file(m, filename) command in which m is a reference to your model and filename is the filename you want the model file written to.

m can be obtained from the call to run_spineopt(). In Spine Toolbox, more particularly the run_SpineOpt tool, you will have m=run_spineopt(). That means that you can call write_model_file(m,filename) in the console once SpineOpt has finished executing and the console remains open.

In either case, here are some tips if you are using this file for debugging. The file can be very large so often it is helpful to create a minimum example of your model with only one or two timesteps. Also, in the call to run_spineopt() you can add the keyword argument optimize=false so it will just build the model and not attempt to solve it.

diff --git a/dev/implementation_details/documentation/index.html b/dev/implementation_details/documentation/index.html index 63c02d4b03..0116b185d2 100644 --- a/dev/implementation_details/documentation/index.html +++ b/dev/implementation_details/documentation/index.html @@ -24,4 +24,4 @@ expand_tags!(objective_function_lines, docstrings) open(joinpath(mathpath, "objective_function_automatically_generated.md"), "w") do file write(file, join(objective_function_lines, "\n")) -end

To deactivate the functionality, just remove the code and replace the tags in your .md file.

It is also possible to introduce this feature over time. Anytime you want to add the documentation of a constraint to the docstring you need to follow a few steps:

  1. For the docstring
    1. add @doc raw before the docstring (that allows to write latex in the docstring)
  2. For the .md file
    1. cut the description and mathematical formulation and paste them in the corresponding function's docstring
    2. add the tag to pull the above from the docstring

An example of both the docstring and the instruction file have already been shown above.

Drag and drop

There is also a drag-and-drop feature for select chapters (e.g. the how to section). For those chapters you can simply add your markdown file to the folder of the chapter and it will be automatically added to the documentation. To allow both manually composed chapters and automatically generated chapter, the functionality is only activated for empty chapters (of the structure "chapter name" => []).

The drag-and-drop function assumes a specific structure for the documentation files.

+end

To deactivate the functionality, just remove the code and replace the tags in your .md file.

It is also possible to introduce this feature over time. Anytime you want to add the documentation of a constraint to the docstring you need to follow a few steps:

  1. For the docstring
    1. add @doc raw before the docstring (that allows to write latex in the docstring)
  2. For the .md file
    1. cut the description and mathematical formulation and paste them in the corresponding function's docstring
    2. add the tag to pull the above from the docstring

An example of both the docstring and the instruction file have already been shown above.

Drag and drop

There is also a drag-and-drop feature for select chapters (e.g. the how to section). For those chapters you can simply add your markdown file to the folder of the chapter and it will be automatically added to the documentation. To allow both manually composed chapters and automatically generated chapter, the functionality is only activated for empty chapters (of the structure "chapter name" => []).

The drag-and-drop function assumes a specific structure for the documentation files.

diff --git a/dev/implementation_details/how_does_the_model_update_itself/index.html b/dev/implementation_details/how_does_the_model_update_itself/index.html index d63b19bc68..ce0551b0f3 100644 --- a/dev/implementation_details/how_does_the_model_update_itself/index.html +++ b/dev/implementation_details/how_does_the_model_update_itself/index.html @@ -1,3 +1,3 @@ How does the model update itself · SpineOpt.jl

How does the model update itself after rolling?

In SpineOpt, constraints, objective and bounds update themselves automatically whenever the model rolls. To picture this, imagine you have a rolling model with two windows, corresponding to the first and second days of 2023, and daily resolution. (In other words, each window consists of a single time-slice that covers the entire day.) Also, imagine you have a node where the demand is a time-series defined as follows:

timestampvalue
2023-01-015
2023-01-0210

To simplify things, let's say the nodal balance constraint in SpineOpt has the following form:

sum of flows entering the node - sum of flows leaving the node == node's demand
-(for each t in the current window)

You would expect the rhs of this constraint to be 5 for the first window, and 10 for the second window. That is indeed the case, but the way this works under the hood is quite 'magical' so to say.

In SpineOpt, the rhs of the above constraint would be written (roughly) using the following julia expression:

demand[(node=n, t=t, more arguments...)]

Notice the brackets ([]) around the named-tuple with the arguments. Without these (i.e., demand(node=n, t=t, more arguments...)) the expression would evaluate to a number, and the constraint would be static (non-self-updating). But with the brackets, instead of a number, the expression evaluates to a special object of type Call. The important thing about the Call is it remembers the arguments, including the t.

Right before the constraint is passed to the solver, SpineOpt 'realizes' the Call with the current value of t, and computes the actual rhs. So for the first window, where t is the first day in 2023, it will be 5.

Now, whenever SpineOpt rolls forward to solve the next window, it updates the value of t by adding the roll_forward value. (This allows SpineOpt to reuse the same time-slices in all the windows.) But when this happens, the Call is also checked to see if it would return something different now that t has been rolled. And if that's the case, the constraint is automatically updated to reflect the change. In our example, the rhs would become 10 because t is now the second day.

In sum, without the brackets, the constraint would be lhs == 5 (and it would never change), whereas with the brackets, the constraint becomes lhs == the demand at the current value of t.

And the above is valid not only for rhs, but also for any coefficient in any constraint or objective, and for any variable bound.

To see how all this is actually implemented, we suggest you to look at the code of SpineInterface. The starting point is the implementation of Base.getindex for the Parameter type so that writing, e.g., demand[...arguments...] returns a Call that remembers the arguments. From then, we proceed to extend JuMP.jl to handle our Call objects within constraints and objective. The last bit is perhaps the most complex, and consists in storing callbacks inside TimeSlice objects whenever they are used to retrieve the value of a Parameter to build a model. The callbacks are carefully crafted to update a specific part of that model (e.g., a variable coefficient, a variable bound, a constraint rhs). Whenever the TimeSlice rolls, depending on how much it rolls, the appropriate callbacks are called resulting in the model being properly updated. That's roughly it! Hopefully this brief introduction helps (but please contact us if you need more guidance).

+(for each t in the current window)

You would expect the rhs of this constraint to be 5 for the first window, and 10 for the second window. That is indeed the case, but the way this works under the hood is quite 'magical' so to say.

In SpineOpt, the rhs of the above constraint would be written (roughly) using the following julia expression:

demand[(node=n, t=t, more arguments...)]

Notice the brackets ([]) around the named-tuple with the arguments. Without these (i.e., demand(node=n, t=t, more arguments...)) the expression would evaluate to a number, and the constraint would be static (non-self-updating). But with the brackets, instead of a number, the expression evaluates to a special object of type Call. The important thing about the Call is it remembers the arguments, including the t.

Right before the constraint is passed to the solver, SpineOpt 'realizes' the Call with the current value of t, and computes the actual rhs. So for the first window, where t is the first day in 2023, it will be 5.

Now, whenever SpineOpt rolls forward to solve the next window, it updates the value of t by adding the roll_forward value. (This allows SpineOpt to reuse the same time-slices in all the windows.) But when this happens, the Call is also checked to see if it would return something different now that t has been rolled. And if that's the case, the constraint is automatically updated to reflect the change. In our example, the rhs would become 10 because t is now the second day.

In sum, without the brackets, the constraint would be lhs == 5 (and it would never change), whereas with the brackets, the constraint becomes lhs == the demand at the current value of t.

And the above is valid not only for rhs, but also for any coefficient in any constraint or objective, and for any variable bound.

To see how all this is actually implemented, we suggest you to look at the code of SpineInterface. The starting point is the implementation of Base.getindex for the Parameter type so that writing, e.g., demand[...arguments...] returns a Call that remembers the arguments. From then, we proceed to extend JuMP.jl to handle our Call objects within constraints and objective. The last bit is perhaps the most complex, and consists in storing callbacks inside TimeSlice objects whenever they are used to retrieve the value of a Parameter to build a model. The callbacks are carefully crafted to update a specific part of that model (e.g., a variable coefficient, a variable bound, a constraint rhs). Whenever the TimeSlice rolls, depending on how much it rolls, the appropriate callbacks are called resulting in the model being properly updated. That's roughly it! Hopefully this brief introduction helps (but please contact us if you need more guidance).

diff --git a/dev/index.html b/dev/index.html index 87245f2773..fe45881546 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Introduction · SpineOpt.jl

Introduction

SpineOpt.jl is an integrated energy systems optimization model, striving towards adaptability for a multitude of modelling purposes. The data-driven model structure allows for highly customizable energy system descriptions, as well as flexible temporal and stochastic structures, without the need to alter the model source code directly. The methodology is based on mixed-integer linear programming (MILP), and SpineOpt relies on JuMP.jl for interfacing with the different solvers.

While, in principle, it is possible to run SpineOpt by itself, it has been designed to be used through the Spine toolbox, and take maximum advantage of the data and modelling workflow management tools therein. Thus, we highly recommend installing Spine toolbox as well, as outlined in the Installation guide.

Getting Started

As the name implies, this chapter contains guides for starting to use SpineOpt.jl for the first time. The Installation links to the guides how to install SpineOpt.jl and Spine Toolbox on your computer. The Setting up a workflow for SpineOpt in Spine Toolbox section explains how to set up and run SpineOpt.jl from Spine Toolbox. The Creating Your Own Model section explains how to create a new model from scratch. This includes a list of the necessary Object Classes and Relationship Classes, but for more information, you will probably need to consult the Concept Reference chapter.

Tutorials

We learn a lot from examples and that is what you will find in the tutorial chapter. The tutorials come in different shapes: videos, written text and example files. The SpineOpt.jl repository includes a folder examples for ready-made example models. Each example is its own sub-folder, where the input data is provided as .json or .sqlite files. This way, you can easily get a feel for how SpineOpt works with pre-made datasets, either through Spine Toolbox, or directly from the Julia REPL.

How to

The other parts of the documentation are good as a reference when you know what you are looking for but this chapter adds explanations on how to do specific high-level things that might involve multiple elements (e.g. how to print the model).

Concept Reference

This chapter lists and explains all the important data and model structure related concepts to understand in SpineOpt.jl. For a mathematical modelling point of view, see the Mathematical Formulation chapter instead. The Basics of the model structure section briefly explains the general purpose of the most important concepts, like Object Classes and Relationship Classes. Meanwhile, the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections contain detailed explanations of each and every aspect of SpineOpt.jl, organized into the respective sections for clarity.

Mathematical Formulation

This chapter provides the mathematical view of SpineOpt.jl, as some of the methodology-related aspects of the model are more easily understood as math than Julia code. The Variables section explains the purpose of each variable in the model, as well as how the variables are related to the different Object Classes and Relationship Classes. The Constraints section contains the mathematical formulation of each constraint, as well as explanations to their purpose and how they are controlled via different Parameters. Finally, the Objective section explains the default objective function used in SpineOpt.jl.

Advanced Concepts

This chapter explains some of the more complicated aspects of SpineOpt.jl in more detail, hopefully making it easier for you to better understand and apply them in your own modelling. The first few sections focus on aspects of SpineOpt.jl that most users are likely to use, or which are more or less required to understand for advanced use. The Temporal Framework section explains how defining time works in SpineOpt.jl, and how it can be used for different purposes. The Stochastic Framework section details how different stochastic structures can be defined, how they interact with each other, and how this impacts writing Constraints in SpineOpt.jl. The Unit commitment section explains how clustered unit-commitment is defined, while the Ramping and Reserves sections explain how to enable these operational details in your model. The Investment Optimization section explains how to include investment variables in your models, while the User Constraints section details how to include generic data-driven custom constraints.

The last few sections focus on highly specialized use-cases for SpineOpt.jl, which are unlikely to be relevant for simple modelling tasks. The Decomposition section explains the Benders decomposition implementation included in SpineOpt.jl, as well as how to use it. The remaining sections, namely PTDF-Based Powerflow, Pressure driven gas transfer, Lossless nodal DC power flows, and Representative days with seasonal storages, explain various use-case specific modelling approaches supported by SpineOpt.jl.

Implementation details

For those who are interested in how things work under the hood, this chapter explains some parts of the code. Note that this chapter is particularly sensitive to changes in the code and as such might get out of sync. If you do notice a discrepancy, please create an issue in github. That is also the place to be if you don't find what you are looking for in this documentation.

+Introduction · SpineOpt.jl

Introduction

SpineOpt.jl is an integrated energy systems optimization model, striving towards adaptability for a multitude of modelling purposes. The data-driven model structure allows for highly customizable energy system descriptions, as well as flexible temporal and stochastic structures, without the need to alter the model source code directly. The methodology is based on mixed-integer linear programming (MILP), and SpineOpt relies on JuMP.jl for interfacing with the different solvers.

While, in principle, it is possible to run SpineOpt by itself, it has been designed to be used through the Spine toolbox, and take maximum advantage of the data and modelling workflow management tools therein. Thus, we highly recommend installing Spine toolbox as well, as outlined in the Installation guide.

Getting Started

As the name implies, this chapter contains guides for starting to use SpineOpt.jl for the first time. The Installation links to the guides how to install SpineOpt.jl and Spine Toolbox on your computer. The Setting up a workflow for SpineOpt in Spine Toolbox section explains how to set up and run SpineOpt.jl from Spine Toolbox. The Creating Your Own Model section explains how to create a new model from scratch. This includes a list of the necessary Object Classes and Relationship Classes, but for more information, you will probably need to consult the Concept Reference chapter.

Tutorials

We learn a lot from examples and that is what you will find in the tutorial chapter. The tutorials come in different shapes: videos, written text and example files. The SpineOpt.jl repository includes a folder examples for ready-made example models. Each example is its own sub-folder, where the input data is provided as .json or .sqlite files. This way, you can easily get a feel for how SpineOpt works with pre-made datasets, either through Spine Toolbox, or directly from the Julia REPL.

How to

The other parts of the documentation are good as a reference when you know what you are looking for but this chapter adds explanations on how to do specific high-level things that might involve multiple elements (e.g. how to print the model).

Concept Reference

This chapter lists and explains all the important data and model structure related concepts to understand in SpineOpt.jl. For a mathematical modelling point of view, see the Mathematical Formulation chapter instead. The Basics of the model structure section briefly explains the general purpose of the most important concepts, like Object Classes and Relationship Classes. Meanwhile, the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections contain detailed explanations of each and every aspect of SpineOpt.jl, organized into the respective sections for clarity.

Mathematical Formulation

This chapter provides the mathematical view of SpineOpt.jl, as some of the methodology-related aspects of the model are more easily understood as math than Julia code. The Variables section explains the purpose of each variable in the model, as well as how the variables are related to the different Object Classes and Relationship Classes. The Constraints section contains the mathematical formulation of each constraint, as well as explanations to their purpose and how they are controlled via different Parameters. Finally, the Objective section explains the default objective function used in SpineOpt.jl.

Advanced Concepts

This chapter explains some of the more complicated aspects of SpineOpt.jl in more detail, hopefully making it easier for you to better understand and apply them in your own modelling. The first few sections focus on aspects of SpineOpt.jl that most users are likely to use, or which are more or less required to understand for advanced use. The Temporal Framework section explains how defining time works in SpineOpt.jl, and how it can be used for different purposes. The Stochastic Framework section details how different stochastic structures can be defined, how they interact with each other, and how this impacts writing Constraints in SpineOpt.jl. The Unit commitment section explains how clustered unit-commitment is defined, while the Ramping and Reserves sections explain how to enable these operational details in your model. The Investment Optimization section explains how to include investment variables in your models, while the User Constraints section details how to include generic data-driven custom constraints.

The last few sections focus on highly specialized use-cases for SpineOpt.jl, which are unlikely to be relevant for simple modelling tasks. The Decomposition section explains the Benders decomposition implementation included in SpineOpt.jl, as well as how to use it. The remaining sections, namely PTDF-Based Powerflow, Pressure driven gas transfer, Lossless nodal DC power flows, and Representative days with seasonal storages, explain various use-case specific modelling approaches supported by SpineOpt.jl.

Implementation details

For those who are interested in how things work under the hood, this chapter explains some parts of the code. Note that this chapter is particularly sensitive to changes in the code and as such might get out of sync. If you do notice a discrepancy, please create an issue in github. That is also the place to be if you don't find what you are looking for in this documentation.

diff --git a/dev/library/index.html b/dev/library/index.html index 89a5d8f1e0..46240aee0d 100644 --- a/dev/library/index.html +++ b/dev/library/index.html @@ -5,14 +5,14 @@ raw"sqlite:///C:\path\to\your\outputdb.sqlite"; filters=Dict("tool" => "object_activity_control", "scenario" => "scenario_to_run"), alternative="your_results_alternative" -)source
SpineOpt.write_report_from_intermediate_resultsFunction
write_report_from_intermediate_results(intermediate_results_folder, default_url; <keyword arguments>)

Collect results generated on a previous, unsuccessful SpineOpt run from intermediate_results_folder, and write the corresponding report(s) to url_out. A new Spine database is created at url_out if one doesn't exist.

Arguments

  • alternative::String="": if non empty, write results to the given alternative in the output DB.

  • log_level::Int=3: an integer to control the log level.

source
SpineOpt.generate_forced_availability_factorFunction
generate_forced_availability_factor(url_in, url_out; <keyword arguments>)

Generate forced availability factors (due to outages) from the contents of url_in and write them to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.

To generate forced availability factors for an entity, specify mean_time_to_failure and optionally mean_time_to_repair for that entity as a duration in the input DB.

Parameter forced_availability_factor will be written for those entites in the output DB, holding a time series with the availability factor due to forced outages.

Arguments

  • alternative::String="": if non empty, write results to the given alternative in the output DB.

  • filters::Dict{String,String}=Dict("tool" => "object_activity_control"): a dictionary to specify filters. Possible keys are "tool" and "scenario". Values should be a tool or scenario name in the input DB.

Example

using SpineOpt
+)
source
SpineOpt.write_report_from_intermediate_resultsFunction
write_report_from_intermediate_results(intermediate_results_folder, default_url; <keyword arguments>)

Collect results generated on a previous, unsuccessful SpineOpt run from intermediate_results_folder, and write the corresponding report(s) to url_out. A new Spine database is created at url_out if one doesn't exist.

Arguments

  • alternative::String="": if non empty, write results to the given alternative in the output DB.

  • log_level::Int=3: an integer to control the log level.

source
SpineOpt.generate_forced_availability_factorFunction
generate_forced_availability_factor(url_in, url_out; <keyword arguments>)

Generate forced availability factors (due to outages) from the contents of url_in and write them to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.

To generate forced availability factors for an entity, specify mean_time_to_failure and optionally mean_time_to_repair for that entity as a duration in the input DB.

Parameter forced_availability_factor will be written for those entites in the output DB, holding a time series with the availability factor due to forced outages.

Arguments

  • alternative::String="": if non empty, write results to the given alternative in the output DB.

  • filters::Dict{String,String}=Dict("tool" => "object_activity_control"): a dictionary to specify filters. Possible keys are "tool" and "scenario". Values should be a tool or scenario name in the input DB.

Example

using SpineOpt
 m = generate_forced_availability_factor(
     raw"sqlite:///C:\path\to\your\inputputdb.sqlite", 
     raw"sqlite:///C:\path\to\your\outputdb.sqlite"
-)
source

TODO

Internals

Variable library

SpineOpt.unit_flow_indicesFunction
unit_flow_indices(
+)
source

TODO

Internals

Variable library

SpineOpt.unit_flow_indicesFunction
unit_flow_indices(
     unit=anything,
     node=anything,
     direction=anything,
     s=anything
     t=anything
-)

A list of NamedTuples corresponding to indices of the unit_flow variable where the keyword arguments act as filters for each dimension.

source

TODO

Constraint library

TODO

Objective

TODO

+)

A list of NamedTuples corresponding to indices of the unit_flow variable where the keyword arguments act as filters for each dimension.

source

TODO

Constraint library

TODO

Objective

TODO

diff --git a/dev/mathematical_formulation/constraints/index.html b/dev/mathematical_formulation/constraints/index.html index ac061e3745..d2db0532f0 100644 --- a/dev/mathematical_formulation/constraints/index.html +++ b/dev/mathematical_formulation/constraints/index.html @@ -65,4 +65,4 @@ \cdot \left( v^{connections\_invested\_available}_{(c,s,t)} - p^{connections\_invested\_available}_{(c,s,t)} \right) \\ & + \sum_{n,s,t} p^{storages\_invested\_available\_mv}_{(b,n,s,t)} \cdot \left( v^{storages\_invested\_available}_{(n,s,t)} - p^{storages\_invested\_available}_{(n,s,t)} \right) \\ -\end{aligned}\]

where

+\end{aligned}\]

where

diff --git a/dev/mathematical_formulation/constraints_automatically_generated/index.html b/dev/mathematical_formulation/constraints_automatically_generated/index.html index d5654dcc73..d47fdfbd7d 100644 --- a/dev/mathematical_formulation/constraints_automatically_generated/index.html +++ b/dev/mathematical_formulation/constraints_automatically_generated/index.html @@ -61,7 +61,7 @@ & p^{unit\_capacity}_{(u,ng,d,s,t)} \cdot p^{unit\_availability\_factor}_{(u,s,t)} \cdot p^{unit\_conv\_cap\_to\_flow}_{(u,ng,d,s,t)} \\ & \cdot ( \\ & \qquad v^{units\_on}_{(u,s,t)} \\ -& \qquad + \left(1 - p^{shut\_down\_limit}_{(u,ng,d,s,t)}\right) +& \qquad - \left(1 - p^{shut\_down\_limit}_{(u,ng,d,s,t)}\right) \cdot \left( v^{units\_shut\_down}_{(u,s,t+1)} + \sum_{ n \in ng @@ -560,4 +560,4 @@ \cdot \left( v^{connections\_invested\_available}_{(c,s,t)} - p^{connections\_invested\_available}_{(c,s,t)} \right) \\ & + \sum_{n,s,t} p^{storages\_invested\_available\_mv}_{(b,n,s,t)} \cdot \left( v^{storages\_invested\_available}_{(n,s,t)} - p^{storages\_invested\_available}_{(n,s,t)} \right) \\ -\end{aligned}\]

where

+\end{aligned}\]

where

diff --git a/dev/mathematical_formulation/objective_function/index.html b/dev/mathematical_formulation/objective_function/index.html index 8a99e7ec98..4c0812fad1 100644 --- a/dev/mathematical_formulation/objective_function/index.html +++ b/dev/mathematical_formulation/objective_function/index.html @@ -74,4 +74,4 @@ & v_{objective\_penalties} \\ & = \sum_{\substack{(u,s,t) \in node\_slack\_indices}} \left[v_{node\_slack\_neg}(n, s, t)-v_{node\_slack\_pos}(n, s, t) \right]\cdot p_{node\_slack\_penalty}(n,s,t)\cdot p_{weight}(n,s,t) \cdot p_{duration}(t)\\ -\end{aligned}\]

+\end{aligned}\]

diff --git a/dev/mathematical_formulation/sets/index.html b/dev/mathematical_formulation/sets/index.html index e394bec213..272c65c829 100644 --- a/dev/mathematical_formulation/sets/index.html +++ b/dev/mathematical_formulation/sets/index.html @@ -1,2 +1,2 @@ -Sets · SpineOpt.jl

Sets

ind(*parameter*)

Tuple of all objects, for which the parameter is defined

t_before_t(t_after=t')

Set of timeslices that are directly before timeslice t'.

t_before_t(t_before=t')

Set of timeslices that are directly after timeslice t'.

t_in_t(t_short=t')

Set of timeslices that contain timeslice t'

t_in_t(t_long=t')

Set of timeslices that are contained in timeslice t'

t_overlaps_t(t')

Set of timeslices that overlap with timeslice t'

full_stochastic_paths

Set of all possible scenario branches

active_stochastic_paths(s)

Set of all active scenario branches, based on active scenarios s

+Sets · SpineOpt.jl

Sets

ind(*parameter*)

Tuple of all objects, for which the parameter is defined

t_before_t(t_after=t')

Set of timeslices that are directly before timeslice t'.

t_before_t(t_before=t')

Set of timeslices that are directly after timeslice t'.

t_in_t(t_short=t')

Set of timeslices that contain timeslice t'

t_in_t(t_long=t')

Set of timeslices that are contained in timeslice t'

t_overlaps_t(t')

Set of timeslices that overlap with timeslice t'

full_stochastic_paths

Set of all possible scenario branches

active_stochastic_paths(s)

Set of all active scenario branches, based on active scenarios s

diff --git a/dev/mathematical_formulation/variables/index.html b/dev/mathematical_formulation/variables/index.html index a864c25f80..25372e06f8 100644 --- a/dev/mathematical_formulation/variables/index.html +++ b/dev/mathematical_formulation/variables/index.html @@ -1,2 +1,2 @@ -Variables · SpineOpt.jl

Variables

binary_gas_connection_flow

Math symbol: $v_{binary\_gas\_connection\_flow}$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: binary_gas_connection_flow_indices

Binary variable with the indices node $n$ over the connection $conn$ in the direction $to\_node$ for the stochastic scenario $s$ at timestep $t$ describing if the direction of gas flow for a pressure drive gastransfer is in the indicated direction.

connection_flow

Math symbol: $v_{connection\_flow }$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: connection_flow_indices

Commodity flow associated with node $n$ over the connection $conn$ in the direction $d$ for the stochastic scenario $s$ at timestep $t$

connection_intact_flow

Math symbol: $v_{connection\_intact\_flow}$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: connection_intact_flow_indices

???

connections_decommissioned

Math symbol: $v_{connections\_decommissioned}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of decomissioned connections $conn$ for the stochastic scenario $s$ at timestep $t$

connections_invested

Math symbol: $v_{connections\_invested}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of connections $conn$ invested at timestep $t$ in for the stochastic scenario $s$

connections_invested_available

Math symbol: $v_{connections\_invested\_available}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of invested connections $conn$ that are available still the stochastic scenario $s$ at timestep $t$

mp_objective_lowerbound_indices

Math symbol: $v_{mp\_objective\_lowerbound\_indices}$

Indices: (t=t)

Indices function: mp_objective_lowerbound_indices

Updating lowerbound for master problem of Benders decomposition

node_injection

Math symbol: $v_{node\_injection}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_injection_indices

Commodity injections at node $n$ for the stochastic scenario $s$ at timestep $t$

node_pressure

Math symbol: $v_{node\_pressure}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_pressure_indices

Pressue at a node $n$ for a specific stochastic scenario $s$ and timestep $t$. See also: has_pressure

node_slack_neg

Math symbol: $v_{node\_slack\_neg}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_slack_indices

Positive slack variable at node $n$ for the stochastic scenario $s$ at timestep $t$

node_slack_pos

Math symbol: $v_{node\_slack\_pos}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_slack_indices

Negative slack variable at node $n$ for the stochastic scenario $s$ at timestep $t$

node_state

Math symbol: $v_{node\_state}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_state_indices

Storage state at node $n$ for the stochastic scenario $s$ at timestep $t$

node_voltage_angle

Math symbol: $v_{node\_voltage\_angle}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_voltage_angle_indices

Voltage angle at a node $n$ for a specific stochastic scenario $s$ and timestep $t$. See also: has_voltage_angle

nonspin_units_shut_down

Math symbol: $v_{nonspin\_units\_shut\_down}$

Indices: (unit=u, node=n, stochastic_scenario=s, t=t)

Indices function: nonspin_units_shut_down_indices

Number of units $u$ held available for non-spinning downward reserve provision via shutdown to node $n$ for the stochastic scenario $s$ at timestep $t$

nonspin_units_started_up

Math symbol: $v_{nonspin\_units\_started\_up}$

Indices: (unit=u, node=n, stochastic_scenario=s, t=t)

Indices function: nonspin_units_started_up_indices

Number of units $u$ held available for non-spinning upward reserve provision via startup to node $n$ for the stochastic scenario $s$ at timestep $t$

storages_decommissioned

Math symbol: $v_{storages\_decommissioned}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of decomissioned storage nodes $n$ for the stochastic scenario $s$ at timestep $t$

storages_invested

Math symbol: $v_{storages\_invested}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of storage nodes $n$ invested in at timestep $t$ for the stochastic scenario $s$

storages_invested_available

Math symbol: $v_{storages\_invested\_available}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of invested storage nodes $n$ that are available still the stochastic scenario $s$ at timestep $t$

unit_flow

Math symbol: $v_{unit\_flow}$

Indices: (unit=u, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: unit_flow_indices

Commodity flow associated with node $n$ over the unit $u$ in the direction $d$ for the stochastic scenario $s$ at timestep $t$

unit_flow_op

Math symbol: $v_{unit\_flow\_op}$

Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t)

Indices function: unit_flow_op_indices

Contribution of the unit flow assocaited with operating point $i$

unit_flow_op_active

Math symbol: $v_{unit\_flow\_op\_active}$

Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t)

Indices function: unit_flow_op_indices

Control the activation of operating point $i$ of units

units_available

Math symbol: $v_{units\_available}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of available units $u$ for the stochastic scenario $s$ at timestep $t$

units_invested

Math symbol: $v_{units\_invested}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of units $u$ for the stochastic scenario $s$ invested in at timestep $t$

units_invested_available

Math symbol: $v_{units\_invested\_available}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of invested units $u$ that are available still the stochastic scenario $s$ at timestep $t$

units_mothballed

Math symbol: $v_{units\_mothballed}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of units $u$ for the stochastic scenariocenario $s$ mothballed at timestep $t$

units_on

Math symbol: $v_{units\_on}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of online units $u$ for the stochastic scenario $s$ at timestep $t$

units_shut_down

Math symbol: $v_{units\_shut\_down}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of units $u$ for the stochastic scenario $s$ that switched to offline status at timestep $t$

units_started_up

Math symbol: $v_{units\_started\_up}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of units $u$ for the stochastic scenario $s$ that switched to online status at timestep $t$

+Variables · SpineOpt.jl

Variables

binary_gas_connection_flow

Math symbol: $v_{binary\_gas\_connection\_flow}$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: binary_gas_connection_flow_indices

Binary variable with the indices node $n$ over the connection $conn$ in the direction $to\_node$ for the stochastic scenario $s$ at timestep $t$ describing if the direction of gas flow for a pressure drive gastransfer is in the indicated direction.

connection_flow

Math symbol: $v_{connection\_flow }$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: connection_flow_indices

Commodity flow associated with node $n$ over the connection $conn$ in the direction $d$ for the stochastic scenario $s$ at timestep $t$

connection_intact_flow

Math symbol: $v_{connection\_intact\_flow}$

Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: connection_intact_flow_indices

???

connections_decommissioned

Math symbol: $v_{connections\_decommissioned}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of decomissioned connections $conn$ for the stochastic scenario $s$ at timestep $t$

connections_invested

Math symbol: $v_{connections\_invested}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of connections $conn$ invested at timestep $t$ in for the stochastic scenario $s$

connections_invested_available

Math symbol: $v_{connections\_invested\_available}$

Indices: (connection=conn, stochastic_scenario=s, t=t)

Indices function: connections_invested_available_indices

Number of invested connections $conn$ that are available still the stochastic scenario $s$ at timestep $t$

mp_objective_lowerbound_indices

Math symbol: $v_{mp\_objective\_lowerbound\_indices}$

Indices: (t=t)

Indices function: mp_objective_lowerbound_indices

Updating lowerbound for master problem of Benders decomposition

node_injection

Math symbol: $v_{node\_injection}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_injection_indices

Commodity injections at node $n$ for the stochastic scenario $s$ at timestep $t$

node_pressure

Math symbol: $v_{node\_pressure}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_pressure_indices

Pressue at a node $n$ for a specific stochastic scenario $s$ and timestep $t$. See also: has_pressure

node_slack_neg

Math symbol: $v_{node\_slack\_neg}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_slack_indices

Positive slack variable at node $n$ for the stochastic scenario $s$ at timestep $t$

node_slack_pos

Math symbol: $v_{node\_slack\_pos}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_slack_indices

Negative slack variable at node $n$ for the stochastic scenario $s$ at timestep $t$

node_state

Math symbol: $v_{node\_state}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_state_indices

Storage state at node $n$ for the stochastic scenario $s$ at timestep $t$

node_voltage_angle

Math symbol: $v_{node\_voltage\_angle}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: node_voltage_angle_indices

Voltage angle at a node $n$ for a specific stochastic scenario $s$ and timestep $t$. See also: has_voltage_angle

nonspin_units_shut_down

Math symbol: $v_{nonspin\_units\_shut\_down}$

Indices: (unit=u, node=n, stochastic_scenario=s, t=t)

Indices function: nonspin_units_shut_down_indices

Number of units $u$ held available for non-spinning downward reserve provision via shutdown to node $n$ for the stochastic scenario $s$ at timestep $t$

nonspin_units_started_up

Math symbol: $v_{nonspin\_units\_started\_up}$

Indices: (unit=u, node=n, stochastic_scenario=s, t=t)

Indices function: nonspin_units_started_up_indices

Number of units $u$ held available for non-spinning upward reserve provision via startup to node $n$ for the stochastic scenario $s$ at timestep $t$

storages_decommissioned

Math symbol: $v_{storages\_decommissioned}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of decomissioned storage nodes $n$ for the stochastic scenario $s$ at timestep $t$

storages_invested

Math symbol: $v_{storages\_invested}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of storage nodes $n$ invested in at timestep $t$ for the stochastic scenario $s$

storages_invested_available

Math symbol: $v_{storages\_invested\_available}$

Indices: (node=n, stochastic_scenario=s, t=t)

Indices function: storages_invested_available_indices

Number of invested storage nodes $n$ that are available still the stochastic scenario $s$ at timestep $t$

unit_flow

Math symbol: $v_{unit\_flow}$

Indices: (unit=u, node=n, direction=d, stochastic_scenario=s, t=t)

Indices function: unit_flow_indices

Commodity flow associated with node $n$ over the unit $u$ in the direction $d$ for the stochastic scenario $s$ at timestep $t$

unit_flow_op

Math symbol: $v_{unit\_flow\_op}$

Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t)

Indices function: unit_flow_op_indices

Contribution of the unit flow assocaited with operating point $i$

unit_flow_op_active

Math symbol: $v_{unit\_flow\_op\_active}$

Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t)

Indices function: unit_flow_op_indices

Control the activation of operating point $i$ of units

units_available

Math symbol: $v_{units\_available}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of available units $u$ for the stochastic scenario $s$ at timestep $t$

units_invested

Math symbol: $v_{units\_invested}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of units $u$ for the stochastic scenario $s$ invested in at timestep $t$

units_invested_available

Math symbol: $v_{units\_invested\_available}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of invested units $u$ that are available still the stochastic scenario $s$ at timestep $t$

units_mothballed

Math symbol: $v_{units\_mothballed}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_invested_available_indices

Number of units $u$ for the stochastic scenariocenario $s$ mothballed at timestep $t$

units_on

Math symbol: $v_{units\_on}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of online units $u$ for the stochastic scenario $s$ at timestep $t$

units_shut_down

Math symbol: $v_{units\_shut\_down}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of units $u$ for the stochastic scenario $s$ that switched to offline status at timestep $t$

units_started_up

Math symbol: $v_{units\_started\_up}$

Indices: (unit=u, stochastic_scenario=s, t=t)

Indices function: units_on_indices

Number of units $u$ for the stochastic scenario $s$ that switched to online status at timestep $t$

diff --git a/dev/search_index.js b/dev/search_index.js index 874a1239b5..8cbee6e59a 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"concept_reference/write_mps_file/","page":"-","title":"-","text":"This parameter is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/write_mps_file/","page":"-","title":"-","text":"This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\\_mps\\_on\\_no\\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\\_mps\\_never, no file will be written","category":"page"},{"location":"concept_reference/demand/","page":"-","title":"-","text":"The demand parameter represents a \"demand\" or a \"load\" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as \"demand\" or \"load\" for the modelled system, while negative values provide the system with \"influx\" or \"gain\". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects","category":"page"},{"location":"concept_reference/demand/","page":"-","title":"-","text":"The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.","category":"page"},{"location":"tutorial/simple_system/#Simple-System-tutorial","page":"Simple system","title":"Simple System tutorial","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Welcome to Spine Toolbox's Simple System tutorial.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"This tutorial provides a step-by-step guide to setup a simple energy system on Spine Toolbox.","category":"page"},{"location":"tutorial/simple_system/#Introduction","page":"Simple system","title":"Introduction","text":"","category":"section"},{"location":"tutorial/simple_system/#Model-assumptions","page":"Simple system","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Two power plants take fuel from a source node and release electricity to another node in order to supply a demand.\nPower plant 'a' has a capacity of 100 MWh, a variable operating cost of 25 euro/fuel unit, and generates 0.7 MWh of electricity per unit of fuel.\nPower plant 'b' has a capacity of 200 MWh, a variable operating cost of 50 euro/fuel unit, and generates 0.8 MWh of electricity per unit of fuel.\nThe demand at the electricity node is 150 MWh.\nThe fuel node is able to provide infinite energy.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/#Installation-and-upgrades","page":"Simple system","title":"Installation and upgrades","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"If you haven't yet installed the tools yet, please follow the installation guides: ","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"For Spine Toolbox: Spine Toolbox installation guide\nFor SpineOpt: SpineOpt installation guide","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"For Spine Toolbox:\nIf installed with pipx, then use python -m pipx upgrade spinetoolbox\nIf installed from sources using git, then git pull, python -m pip install -U -r requirements.txt\nFor SpineOpt: SpineOpt upgrade guide","category":"page"},{"location":"tutorial/simple_system/#Guide","page":"Simple system","title":"Guide","text":"","category":"section"},{"location":"tutorial/simple_system/#Entering-input-data","page":"Simple system","title":"Entering input data","text":"","category":"section"},{"location":"tutorial/simple_system/#Importing-the-SpineOpt-database-template","page":"Simple system","title":"Importing the SpineOpt database template","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Download the SpineOpt database template and the basic SpineOpt model (right click on the links, then select Save link as...)\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB editor, looking similar to this:","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nThe Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Press Alt + F to display the main menu, select File -> Import..., and then select the template file you previously downloaded (spineopt_template.json). The contents of that file will be imported into the current database, and you should then see classes like 'commodity', 'connection' and 'model' under the root node in the Object tree (on the left). Then import the second file (basic_model_template.json).\nFrom the main menu, select Session -> Commit. Enter 'Import SpineOpt template' as message in the popup dialog, and click Commit.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nThe SpineOpt basic template contains (i) the fundamental entity classes and parameter definitions that SpineOpt recognizes and expects; and (ii) some predefined entities for a common deterministic model with a 'flat' temporal structure.","category":"page"},{"location":"tutorial/simple_system/#Creating-objects","page":"Simple system","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nRight click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.\nEnter the names for the system nodes as seen in the image below, then press Ok. This will create two objects of class node, called fuel_node and electricity_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the unit class, and select Add objects from the context menu. The Add objects dialog will pop up.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nIn SpineOpt, nodes are points where an energy balance takes place, whereas units are energy conversion devices that can take energy from nodes, and release energy to nodes.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Enter the names for the system units as seen in the image below, then press Ok. This will create two objects of class unit, called power_plant_a and power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nTo modify an object after you enter it, right click on it and select Edit... from the context menu.","category":"page"},{"location":"tutorial/simple_system/#Establishing-relationships","page":"Simple system","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the unit__from_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their sending nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b take energy from the fuel_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into the electricity_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and unit_flow under output, as seen in the image below; then press Ok. This will tell SpineOpt to write the value of the unit_flow optimization variable to the output database, as part of report1.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nIn SpineOpt, outputs represent optimization variables that can be written to the output database as part of a report.","category":"page"},{"location":"tutorial/simple_system/#Specifying-object-parameter-values","page":"Simple system","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Back to Object tree, expand the node class and select electricity_node.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table (typically at the top-center), select the demand parameter and the Base alternative, and enter the value 100 as seen in the image below. This will establish that there's a demand of '100' at the electricity node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select fuel_node in the Object tree.\nIn the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that the fuel node is not balanced, and thus provide as much fuel as needed.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/#Specifying-relationship-parameter-values","page":"Simple system","title":"Specifying relationship parameter values","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, expand the unit__from_node class and select power_plant_a | fuel_node.\nIn the Relationship parameter table (typically at the bottom-center), select the vom_cost parameter and the Base alternative, and enter the value 25 as seen in the image below. This will set the operating cost for power_plant_a.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select power_plant_b | fuel_node in the Relationship tree.\nIn the Relationship parameter table, select the vom_cost parameter and the Base alternative, and enter the value 50 as seen in the image below. This will set the operating cost for power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | electricity_node.\nIn the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity for power_plant_a.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select power_plant_b | electricity_node in the Relationship tree.\nIn the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity for power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, select the unit__node__node class, and come back to the Relationship parameter table.\nIn the Relationship parameter table, select power_plant_a | electricity_node | fuel_node under object name list, fix_ratio_out_in_unit_flow under parameter name, Base under alternative name, and enter 0.7 under value. Repeat the operation for power_plant_b, but this time enter 0.8 under value. This will set the conversion ratio from fuel to electricity for power_plant_a and power_plant_b to 0.7 and 0.8, respectively. It should like the image below.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/simple_system/#Executing-the-workflow","page":"Simple system","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt 1' Tool. You should see the output from SpineOpt in the Julia Console.","category":"page"},{"location":"tutorial/simple_system/#Examining-the-results","page":"Simple system","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select the output data store and open the Spine DB editor.\nPress Alt + F to display the main menu, and select Pivot -> Index.\nSelect report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.\nUnder alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.\nThe Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-renewable-energy-targets","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"This advanced concept illustrates how renewable targets can be realized in SpineOpt. ","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-lower-limits-on-renewable-production","page":"Imposing renewable energy targets","title":"Imposing lower limits on renewable production","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-a-lower-bound-on-the-cumulated-flow-of-a-unit-group-by-an-absolute-value","page":"Imposing renewable energy targets","title":"Imposing a lower bound on the cumulated flow of a unit group by an absolute value","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"In the current landscape of energy systems modeling, especially in investment models, it is a common idea to implement a lower limit on the amount of electricity that is generated by renewable sources. SpineOpt allows the user to implement such restrictions by means of the min_total_cumulated_unit_flow_to_node parameter. Which will trigger the creation of the constraint_total_cumulated_unit_flow.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To impose a limit on overall renewable generation over the entire optimization horizon, the following objects, relationships, and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. electricity generation from wind), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with renewable generation","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing electricity demand. (Note: To distinguish e.g. between regions there can also be more than one electricity node)\nunit__to_node: To associate electricity flows with a unit, the relationship between the unit and the electricity node needs to be imposed, to trigger the generation of a electricity-unit_flow variable.\nmin_total_cumulated_unit_flow_to_node: This parameter triggers a lower bound on all cumulated flows from a unit (or a group of units), e.g. the group of all renewable generators, to a node (or node group).","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Let's take a look at a simple example to see how this works. Suppose that we have a system with only one node, which represents the demand for electricity, and two units: a wind farm, and a conventional gas unit. To connect the wind farm to the electricity node, the unit__to_node relationship has to be defined.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"One can then simply define the min_total_cumulated_unit_flow_to_node parameter for the 'windfarm__toelectricity_node' relationship to impose a lower bound on the total generation origination from the wind farm.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Note that the value of this parameter is expected to be given as an absolute value, thus care has to be taken to make sure that the units match with the ones used for the unit_flow variable.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"The main source of flexibility in the use of this constraint lies in the possibility to define the parameter for relationships that link 'nodegroups' and/or 'unitgroups'. For example, by grouping multiple units that are considered renewable sources (e.g. PV, and wind), targets can be implemented across multiple renewable sources. Similarly, by defining multiple electricity nodes, generation targets can be spatially disagreggated.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Limiting-the-cumulated-flow-of-a-unit-group-by-a-share-of-the-demand","page":"Imposing renewable energy targets","title":"Limiting the cumulated flow of a unit group by a share of the demand","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"For convenience, we want to be able to define the min_total_cumulated_unit_flow_to_node, when used to set a renewable target, as a share of the demand. At the moment an absolute lower bound needs to be provided by the user, but we want to automate this preprocessing in SpineOpt. (to be implemented)","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-limit-on-carbon-emissions","page":"Imposing renewable energy targets","title":"Imposing an upper limit on carbon emissions","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-limit-on-carbon-emissions-over-the-entire-optimization-horizon","page":"Imposing renewable energy targets","title":"Imposing an upper limit on carbon emissions over the entire optimization horizon","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To impose a limit on overall carbon emissions over the entire optimization horizon, the following objects, relationships and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with carbon emissions","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. (Note: To distinguish e.g. between regions there can also be more than one carbon node)\nunit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.\nunit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)\nmax_total_cumulated_unit_flow_to_node (and unit__to_node): This parameter triggers a limit on all flows from a unit (or a group of units), e.g. the group of all conventional generators, to a node (or node groups), e.g. considering the atmosphere as a fictive CO2 node, over the entire modelling horizon (e.g. a carbon budget). For example this could be defined on a relationship between a gasplant and a Carbon node, but can also be defined a unit group of all conventional generators and a carbon node. See also: constraint_total_cumulated_unit_flow","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-bound-on-the-cumulated-flows-of-a-unit-group-for-a-specific-period-of-time-(advanced-method)","page":"Imposing renewable energy targets","title":"Imposing an upper bound on the cumulated flows of a unit group for a specific period of time (advanced method)","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"If the desired functionality is not to cap emissions over the entire modelling horizon, but rather for specific periods of time (e.g., to impose decreasing carbon caps over time), an alternative method can be used, which will be described in the following.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To illustrate this functionality, we will assume that there is a ficticious cap of 100 for a period of time 2025-2030, and a cap of 50 for the period of time 2030-2035. In this simple example, we will assume that one carbon-emitting unit carbon_unit is present with two outgoing commodity flows, e.g. here electricity and carbon.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Three nodes are required to represent this system: an electricity node, a carbon_cap_1 node (with has_state=true and node_state_cap=100), and a carbon_cap_2 node (with has_state=true and node_state_cap=50).","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Further we introduce the unit__node__node relationships between carbon_unit__carbon_cap1__electricity and carbon_unit__carbon_cap2__electricity. On these relationships, we will define the ratio between emissions and electricity production. In this fictious example, we will assume 0.5 units of emissions per unit of electricity.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"The fix_ratio_out_out parameter will now be defined as a time varying parameter in the following way (simplified representation of TimeSeries parameter):","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"fix_ratio_out_out(carbon_unit__carbon_cap1__electricity) = [2025: 0.5; 2030: 0] fix_ratio_out_out(carbon_unit__carbon_cap2__electricity) = [2025: 0; 2030: 0.5]","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"This way the first emission-cap node carbon_cap1 can only be \"filled\" during the 2025-2030, while carbon_cap2 can only be \"filled\" during the second period 2030-2035. ","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Note that it would also be possible to have, e.g., one node with time-varying node_state_cap. However, in this case, \"unused\" carbon emissions in the first period of time would be availble for the second period of time.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-a-carbon-tax","page":"Imposing renewable energy targets","title":"Imposing a carbon tax","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To include carbon pricing in a model, the following objects, relationships and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with carbon emissions","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node and tax_in_unit_flow: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. To associate a carbon-tax with all incoming unit_flows, the tax_in_unit_flow parameter can be defined on this node (Note: To distinguish e.g. between regions there can also be more than one carbon node)\nunit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.\nunit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (Gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)","category":"page"},{"location":"getting_started/setup_workflow/#Setting-up-a-workflow-for-SpineOpt-in-Spine-Toolbox","page":"Setting up a workflow","title":"Setting up a workflow for SpineOpt in Spine Toolbox","text":"","category":"section"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"The next steps will set up a SpineOpt specific input database by creating a new Spine database, loading a blank SpineOpt template, connecting it to a SpineOpt instance and setting up a database for model results. ","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Create a new Spine Toolbox project in an empty folder of your choice: File –> New project...\nCreate the input database\nDrag an empty Data store from the toolbar to the Design View. \nGive it a name like \"Input DB\". \nSelect SQL database dialect (sqlite is a local file and works without a server). \nClick New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite).\nFor more information about creating and managing Spine Toolbox database, see the documentation","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Fill the Input DB with SpineOpt data format either by:\nDrag a tool Load template from the SpineOpt ribbon to the Design View. \nConnect an arrow from the Load template to the new Input DB. \nMake sure the Load template item from the Design view is selected (then you can edit the properties of that workflow item in the Tool properties window. \nAdd the url link in Available resources to the Tool arguments - you are passing the database address as a command line argument to the load_template.jl script so that it knows where to store the output. \nThen execute the Load template tool. Please note that this process uses SpineOpt to generate the data structure. It takes time, since everything is compiled when running a tool in Julia for the first time in each Julia session. You may also see lot of messages and warnings concernging the compilation, but they should be benign.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"...or by:\nStart Julia (you can start a separate Julia console in Spine Toolbox: go to Consoles –> Start Julia Console). \nCopy the URL address of the Data Store from the 'Data Store Properties' –> a copy icon at the bottom. \nThen run the following script with the right URL address pasted. The process uses SpineOpt itself to build the database structure. Please note that 'using SpineOpt' for the first time for each Julia session takes time - everything is being compiled.\nKnown issue: On Windows, the backslash between directories need to be changed to a double forward slash.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"julia> using SpineOpt\n\njulia> SpineOpt.import_data(\"copied URL address, inside these quotes\", SpineOpt.template(), \"Load SpineOpt template\")","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Drag SpineOpt tool icon to the Design view. \nConnect an arrow from the Input DB to SpineOpt. ","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Create a database for results\nDrag a new Data store from the toolbar to the Design View. \nYou can rename it to e.g. Results. Select SQL database dialect (sqlite is a local file and works without a server). \nClick New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite). \nConnect an arrow from the SpineOpt to Results.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Select SpineOpt tool in the Design view. \nAdd the url link for the input data store and the output data store from Available resources to the Tool arguments (in that order).","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"SpineOpt would be ready to run, but for the Input DB, which is empty of content (it's just a template that contains a SpineOpt specific data structure). The next step goes through setting up and running a simple toy model.","category":"page"},{"location":"concept_reference/fix_nonspin_units_shut_down/","page":"-","title":"-","text":"The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/fix_nonspin_units_shut_down/","page":"-","title":"-","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/nodal_balance_sense/","page":"-","title":"-","text":"nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.","category":"page"},{"location":"tutorial/case_study_a5/#Case-Study-A5-tutorial","page":"Case Study A5","title":"Case Study A5 tutorial","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Welcome to this Spine Toolbox Case Study tutorial. Case Study A5 is one of the Spine Project case studies designed to verify Toolbox and Model capabilities. To this end, it reproduces an already existing study about hydropower on the Skellefte river, which models one week of operation of the fifteen power stations along the river.","category":"page"},{"location":"tutorial/case_study_a5/#Introduction","page":"Case Study A5","title":"Introduction","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Model-assumptions","page":"Case Study A5","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"For each power station in the river, the following information is known:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The capacity, or maximal electricity output. This datum also provides the maximal water discharge as per the efficiency curve (see next point).\nThe efficiency curve, or conversion rate from water to electricity. In this study, a piece-wise linear efficiency with two segments is assumed. Moreover, this curve is monotonically decreasing, i.e., the efficiency in the first segment is strictly greater than the efficiency in the second segment.\nThe maximal reservoir level (maximal amount of water that can be stored in the reservoir).\nThe reservoir level at the beginning of the simulation period and at the end.\nThe minimal amount of water that the plant must discharge at every hour. This is usually zero (except for one of the plants).\nThe downstream plant, or next plant in the river course.\nThe time that it takes for the water to reach the downstream plant. This time can be different depending on whether the water is discharged (goes through the turbine) or spilled.\nThe local inflow, or amount of water that naturally enters the reservoir at every hour. In this study, it is assumed constant over the entire simulation period.\nThe hourly average water discharge. It is assumed that before the beginning of the simulation, this amount of water has constantly been discharged at every hour.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The system is operated so as to maximize the total profit over the planning week, while respecting capacity constraints, maximal reservoir level constrains, etc. Hourly profit per plant is simply computed as the product of the electricity price and the production.","category":"page"},{"location":"tutorial/case_study_a5/#Modelling-choices","page":"Case Study A5","title":"Modelling choices","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The model of the electric system is fairly simple, only two elements are needed:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"A common electricity node.\nA load unit that takes electricity from that node.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"On the contrary, the model of the river system is more detailed. Each power station in the river is modelled using the following elements:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"An upper water node, located at the entrance of the station.\nA lower water node, located at the exit of the station.\nA power plant unit, that discharges water from the upper node into the lower node, and feeds electricity produced in the process to the common electricity node.\nA spillway connection, that takes spilled water from the upper node and releases it to the downstream upper node.\nA discharge connection, that takes water from the lower node and releases it to the downstream upper node.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Below is a schematic of the model. For clarity, only the Rebnis station is presented in full detail:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing the spineopt database template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nJust remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Case Study A5’) in the corresponding step, so to not mix up the Spine Toolbox projects!","category":"page"},{"location":"tutorial/case_study_a5/#Importing-the-SpineOpt-database-template","page":"Case Study A5","title":"Importing the SpineOpt database template","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Download the SpineOpt database template (right click on the link, then select Save link as...)\nSelect the input Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB Editor, looking similar to image below. (Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThe Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Press Alt + F to display the editor menu, select File -> Import..., and then select the template file you previously downloaded (in case it is not displayed in the folder where you saved it, double-check that you selected). The contents of that file will be imported into the current database, and you should then see classes like ‘commodity’, ‘connection’ and ‘model’ under the root node in the Object tree (on the left).\nFrom the editor menu (Alt + F), select Session -> Commit. Enter ‘Import SpineOpt template’ as message in the popup dialog, and click Commit.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThe SpineOpt template contains the fundamental object and relationship classes, as well as parameter definitions, that SpineOpt recognizes and expects. You can think of it as the generic structure of the model, as opposed to the specific data for a particular instance. In the remainder of this section, we will add that specific data for the Skellefte river.","category":"page"},{"location":"tutorial/case_study_a5/#Entering-data","page":"Case Study A5","title":"Entering data","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThere are two options in this tutorial to enter data in the Database. The first one is to enter data manually and the second to use the importer functionality. These are described in the next two subsections respectively and produce similar models. The model created when using the importer creates a model with two-segments efficiency curves for converting water to electricity (while the model created when entering the data manually assumes a simplified efficiency curve with a single segment).","category":"page"},{"location":"tutorial/case_study_a5/#Entering-data-manually","page":"Case Study A5","title":"Entering data manually","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Creating-objects","page":"Case Study A5","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To add power plants to the model, stay in the Spine DB Editor and create objects of class unit as follows:\nSelect the list of plant names from the text-box below and copy it to the clipboard (Ctrl+C)\n Rebnis_pwr_plant\n Sadva_pwr_plant\n Bergnäs_pwr_plant\n Slagnäs_pwr_plant\n Bastusel_pwr_plant\n Grytfors_pwr_plant\n Gallejaur_pwr_plant\n Vargfors_pwr_plant\n Rengård_pwr_plant\n Båtfors_pwr_plant\n Finnfors_pwr_plant\n Granfors_pwr_plant\n Krångfors_pwr_plant\n Selsfors_pwr_plant\n Kvistforsen_pwr_plant\nGo to Object tree (on the top left of the window, usually), right-click on unit and select Add objects from the context menu. This will open the Add objects dialog.\nSelect the first cell under the object name column and press Ctrl+V. This will paste the list of plant names from the clipboard into that column; the object class name column will be filled automatically with ‘unit‘. The form should now be looking similar to this: (Image: image)\nClick Ok.\nBack in the Spine DB Editor, under Object tree, double click on unit to confirm that the objects are effectively there.\nCommit changes with the message ‘Add power plants’.\nAdd discharge and spillway connections by creating objects of class connection with the following names:\nRebnistoBergnäsdisch SadvatoBergnäsdisch BergnästoSlagnäsdisch SlagnästoBastuseldisch BastuseltoGrytforsdisch GrytforstoGallejaurdisch GallejaurtoVargforsdisch VargforstoRengårddisch RengårdtoBåtforsdisch BåtforstoFinnforsdisch FinnforstoGranforsdisch GranforstoKrångforsdisch KrångforstoSelsforsdisch SelsforstoKvistforsendisch Kvistforsentodownstreamdisch RebnistoBergnässpill SadvatoBergnässpill BergnästoSlagnässpill SlagnästoBastuselspill BastuseltoGrytforsspill GrytforstoGallejaurspill GallejaurtoVargforsspill VargforstoRengårdspill RengårdtoBåtforsspill BåtforstoFinnforsspill FinnforstoGranforsspill GranforstoKrångforsspill KrångforstoSelsforsspill SelsforstoKvistforsenspill Kvistforsentodownstreamspill\nAdd water nodes by creating objects of class node with the following names:\nRebnisupper Sadvaupper Bergnäsupper Slagnäsupper Bastuselupper Grytforsupper Gallejaurupper Vargforsupper Rengårdupper Båtforsupper Finnforsupper Granforsupper Krångforsupper Selsforsupper Kvistforsenupper Rebnislower Sadvalower Bergnäslower Slagnäslower Bastusellower Grytforslower Gallejaurlower Vargforslower Rengårdlower Båtforslower Finnforslower Granforslower Krångforslower Selsforslower Kvistforsenlower\nNext, create the following objects (all names in lower-case):\ninstance of class model.\nwater and electricity of class commodity.\nelectricity_node of class node.\nelectricity_load of class unit.\nsome_week of class temporal_block.\ndeterministic of class stochastic_structure.\nrealization of class stochastic_scenario.\nFinally, create the following objects to get results back from SpineOpt (again, all names in lower-case):\nmy_report of class report.\nunit_flow, connection_flow, and node_state of class output.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nTo modify an object after you enter it, right click on it and select Edit... from the context menu.","category":"page"},{"location":"tutorial/case_study_a5/#Specifying-object-parameter-values","page":"Case Study A5","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To specify the general behaviour of our model, stay in the Spine DB Editor and enter model parameter values as follows:\nSelect the model parameter value data (i.e. select all, Ctrl+A) from the file below and copy it to the clipboard (Ctrl+C): cs-a5-model-parameter-values.txt\nSelect instance in the Object tree and inspect the table in Object parameter value (on the top-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order): \n object_class_name | object_name | parameter_name | alternative_name | value | database\nSelect the first cell under object_class_name and press Ctrl+V. This will paste the model parameter value data from the clipboard into the table. The form should be looking like this: (Image: image)\nSpecify the resolution of our temporal block some_week in the same way using the data below: cs-a5-temporal_block-parameter-values.txt\nSpecify the behaviour of all system nodes with the data below, where:\ndemand represents the local inflow (negative in most cases).\nfix_node_state represents fixed reservoir levels (at the beginning and the end).\nhas_state indicates whether or not the node is a reservoir (true for all the upper nodes).\nstate_coeff is the reservoir 'efficienty' (always 1, meaning that there aren't any loses).\nnode_state_cap is the maximum level of the reservoirs.\nTo do this in one single step, simply select node in the Object tree and paste the following values in the first empty cell: cs-a5-node-parameter-values.txt","category":"page"},{"location":"tutorial/case_study_a5/#Establishing-relationships","page":"Case Study A5","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"tip: Tip\nTo enter the same text on several cells, copy the text into the clipboard, then select all target cells and press Ctrl+V.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class unit__from_node to represent that a power plant receives water from the station's upper water node, and that the electricity load takes electricity from the common electricity node. Both the power plants and the electricity load belong to the class unit.\nSelect the list of unit and node names from below and copy it to the clipboard (Ctrl+C). cs-a5-unit__from_node.txt\nIn the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), right-click on unit__from_node and select Add relationships from the context menu. This will open the Add relationships dialog.\nSelect the first cell under the unit column and press Ctrl+V. This will paste the list of plant and node names from the clipboard into the table. The form should be looking like this: (Image: image) \nClick Ok.\nBack in the Spine DB Editor, under Relationship tree, double click on unit__from_node to confirm that the relationships are effectively there.\nFrom the main menu (Alt + F), select Session -> Commit to open the Commit changes dialog. Enter ‘Add from nodes of power plants‘ as the commit message and click Commit.\nCreate relationships of the class unit__to_node to represent that a power plant releases water to the station's lower water node, and that the power plants supply electricity to the common electricity node. Use the following data and do as before: cs-a5-unit__to_node.txt","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nAt this point, you might be wondering what's the purpose of the unit__node__node relationship class. Shouldn't it be enough to have unit__from_node and unit__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the conversion process that happens in the unit, where the water from one node is turned into electricty for another node. And for this purpose, we use a relationship parameter value on the unit__node__node relationships (see Specifying relationship parameter values).","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class connection__from_node to represent that water can be either discharged or spilled. If discharged, it is taken from the lower water node of the station, if spilled it is taken from the upper water node of the station. Use the following data and do as before: cs-a5-connection__from_node.txt\nCreate relationships of the class connection__to_node to represent that both discharge and spill are released into the upper node of the next downstream station. Use the following data and do as before: cs-a5-connection__to_node.txt","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nAt this point, you might be wondering what's the purpose of the connection__node__node relationship class. Shouldn't it be enough to have connection__from_node and connection__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the delay in the river branches. And for this purpose, we use a relationship parameter value on the connection__node__node relationships (see Specifying relationship parameter values).","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class node__commodity to represent that each node has to be in balance, for water nodes with respect to water, for electricity nodes with respect to electricity. This way, you link all nodes to either the commocity water or the commodity electricity. Use the following data and do as before: cs-a5-node__commodity.txt\nDefine that all nodes in our model have to be balanced at each time step. To do this, you create a relationship of the class model__default_temporal_block between the model instance and the temporalblock `someweek` in the same way as before.\nDefine that our model is deterministic. To do this, you create a relationship of the class model__default_stochastic_structure between the model instance and the stochastic structure deterministic, as well as a relationship of class stochastic_structure__stochastic_scenario between the stochastid structure deterministic and the stochastic scenario realization in the same way as before.\nIn order to get the results from running Spine Opt written to the ouput database, create relationships of the class report__output between the report my_report and each of the following output objects: unit_flow, connection_flow, and node_state. In addition, you also need to create a relationship of the class model__report between the model instance and the report my_report.","category":"page"},{"location":"tutorial/case_study_a5/#Specifying-parameter-values-of-the-relationships","page":"Case Study A5","title":"Specifying parameter values of the relationships","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Finally, the values of all parameters have to be entered. Specify the capacity of all hydropower plants, and their respective variable operating cost by entering unit__from_node parameter values as follows:\nSelect the data from the text-box below and copy it to the clipboard (Ctrl+C): cs-a5-unit__from_node-relationship-parameter-values.txt\nIn the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), and click on unit__from_node. Then, go to Relationship parameter value (on the bottom-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order): \n relationship_class_name | object_name_list | parameter_name | alternative_name | value | database\nSelect the first cell under relationship_class_name and press Ctrl+V. This will paste the parameter value data from the clipboard into the table.\nSpecify the conversion ratio between discharged water and generated electricity for each hydropower station as well as a similar conversion rate (set to 1) to represent that water cannot be lost between upper and lower water nodes. Use the following data to enter the parameter values unit__from_node: cs-a5-unit__node__node-relationship-parameter-values.txt\nSpecify the average discharge and spillage in the first hours of the simulation. Use the following data to enter the parameter values connection__from_node: cs-a5-connection__from_node-relationship-parameter-values.txt\nFinally, specify the delay (the time it takes for the water to run between water nodes) and the transfer ratio (being equal to 1) of different water connections. Use the following data to enter the parameter values connection__node_node: cs-a5-connection__node__node-relationship-parameter-values.txt\nWhen you're ready, commit all changes to the database via the main menu (Alt + F).","category":"page"},{"location":"tutorial/case_study_a5/#Using-the-Importer","page":"Case Study A5","title":"Using the Importer","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Additional-Steps-for-Project-Setup","page":"Case Study A5","title":"Additional Steps for Project Setup","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Drag the Data Connection icon (Image: image) from the tool bar and drop it into the Design View. This will open the Add Data connection dialogue. Type in ‘Data Connection’ and click on Ok.\nTo import the model into the Spine database, you need to create an Import specification. Create an Import specification by clicking on the small arrow next to the Importer item (in the Main section of the toolbar) and press New. The Importer specification editor will pop-up.\nType ‘Import Model’ as the name of the specification. Save the specification by using Ctrl+S and close the window.\nDrag the newly created Import Model Importer item icon (Image: image) from the tool bar and drop it into the Design View. This will open the Add Importer dialogue. Type in ‘Import Model’ and click on Ok.\nConnect ‘Data Connection’ with ‘Import Model’ by first clicking on one of the Data Connection’s connectors and then on one of the Importer’s connectors. Connect similarly the importer with the input database. Now the project should look similar to this: (Image: image)\nFrom the main menu, select File -> Save project.","category":"page"},{"location":"tutorial/case_study_a5/#Importing-the-model","page":"Case Study A5","title":"Importing the model","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Download the data and the accompanying mapping (right click on the links, then select Save link as...).\nAdd a reference to the file containing the model.\nSelect the Data Connection item in the Design View to show the Data Connection properties window (on the right side of the window usually).\nIn Data Connection Properties, click on , click on the icon furthest to the left Add file references and select the previously downloaded Excel file.\nNext, double click on the Import model in the Design view. A window called Select connector for Import Model will pop-up, select Excel and klick OK. Next, still in the Importer specification editor, click on the main menu icon in the top right (or Press Alt + F to automatically display it) and import the mappings previously downloaded (by clicking on Import mappings). Finally, save by clicking Ctrl+S and exit the Importer specification editor.","category":"page"},{"location":"tutorial/case_study_a5/#Executing-the-workflow","page":"Case Study A5","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Once the workflow is defined and input data is in place, the project is ready to be executed. Hit the Execute project button (Image: image) on the tool bar.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"You should see ‘Executing All Directed Acyclic Graphs’ printed in the Event log (on the lower left by default). SpineOpt output messages will appear in the Process Log panel in the middle. After some processing, ‘DAG 1/1 completed successfully’ appears and the execution is complete.","category":"page"},{"location":"tutorial/case_study_a5/#Examining-the-results","page":"Case Study A5","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Select the output data store and open the Spine DB editor.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To checkout the flow on the electricity load (i.e., the total electricity production in the system), go to Object tree, expand the unit object class, and select electricity_load, as illustrated in the picture above. Next, go to Relationship parameter value and double-click the first cell under value. The Parameter value editor will pop up. You should see something like this:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nIf you have used the importer to instantiate the model you can easily modify the parameters in the model worksheet, run the project and observe the differences in the results. If you need to make changes directly to the input database, in order for the importer not to overwrite them, you will need to dissassociate the importer from the input DB (right click in the connecting yellow arrow between the two items and click on remove).","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/#How-does-the-model-update-itself-after-rolling?","page":"How does the model update itself","title":"How does the model update itself after rolling?","text":"","category":"section"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In SpineOpt, constraints, objective and bounds update themselves automatically whenever the model rolls. To picture this, imagine you have a rolling model with two windows, corresponding to the first and second days of 2023, and daily resolution. (In other words, each window consists of a single time-slice that covers the entire day.) Also, imagine you have a node where the demand is a time-series defined as follows:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"timestamp value\n2023-01-01 5\n2023-01-02 10","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"To simplify things, let's say the nodal balance constraint in SpineOpt has the following form:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"sum of flows entering the node - sum of flows leaving the node == node's demand\n(for each t in the current window)","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"You would expect the rhs of this constraint to be 5 for the first window, and 10 for the second window. That is indeed the case, but the way this works under the hood is quite 'magical' so to say.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In SpineOpt, the rhs of the above constraint would be written (roughly) using the following julia expression:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"demand[(node=n, t=t, more arguments...)]","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Notice the brackets ([]) around the named-tuple with the arguments. Without these (i.e., demand(node=n, t=t, more arguments...)) the expression would evaluate to a number, and the constraint would be static (non-self-updating). But with the brackets, instead of a number, the expression evaluates to a special object of type Call. The important thing about the Call is it remembers the arguments, including the t.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Right before the constraint is passed to the solver, SpineOpt 'realizes' the Call with the current value of t, and computes the actual rhs. So for the first window, where t is the first day in 2023, it will be 5.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Now, whenever SpineOpt rolls forward to solve the next window, it updates the value of t by adding the roll_forward value. (This allows SpineOpt to reuse the same time-slices in all the windows.) But when this happens, the Call is also checked to see if it would return something different now that t has been rolled. And if that's the case, the constraint is automatically updated to reflect the change. In our example, the rhs would become 10 because t is now the second day.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In sum, without the brackets, the constraint would be lhs == 5 (and it would never change), whereas with the brackets, the constraint becomes lhs == the demand at the current value of t.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"And the above is valid not only for rhs, but also for any coefficient in any constraint or objective, and for any variable bound.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"To see how all this is actually implemented, we suggest you to look at the code of SpineInterface. The starting point is the implementation of Base.getindex for the Parameter type so that writing, e.g., demand[...arguments...] returns a Call that remembers the arguments. From then, we proceed to extend JuMP.jl to handle our Call objects within constraints and objective. The last bit is perhaps the most complex, and consists in storing callbacks inside TimeSlice objects whenever they are used to retrieve the value of a Parameter to build a model. The callbacks are carefully crafted to update a specific part of that model (e.g., a variable coefficient, a variable bound, a constraint rhs). Whenever the TimeSlice rolls, depending on how much it rolls, the appropriate callbacks are called resulting in the model being properly updated. That's roughly it! Hopefully this brief introduction helps (but please contact us if you need more guidance).","category":"page"},{"location":"concept_reference/unit__unit_constraint/","page":"-","title":"-","text":"unit__user_constraint is a two-dimensional relationship between a unit and a user_constraint. The relationship specifies that a variable or variable(s) associated only with the unit (not a unit_flow for example) are involved in the constraint. For example, the units_on_coefficient defined on unit__user_constraint specifies the coefficient of the unit's units_on variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/unit__unit_constraint/","page":"-","title":"-","text":"See also user_constraint","category":"page"},{"location":"concept_reference/max_gap/","page":"-","title":"-","text":"This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"To use representative periods in your model, do the following:","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.\nDefine a set of temporal_block objects, each corresponding to one representative period.\nSpecify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.\nAssociate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"See also Representative days with seasonal storages.","category":"page"},{"location":"concept_reference/operating_cost/","page":"-","title":"-","text":"By defining the operating_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for operating costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/connection_resistance/","page":"-","title":"-","text":"The per unit resistance of a transmission line. Currently unimplemented!","category":"page"},{"location":"concept_reference/db_mip_solver/","page":"-","title":"-","text":"Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_standard uses the standard algorithm.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_benders uses the Benders decomposition algorithm (see Decomposition.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_mga uses the Model to Generate Alternatives algorithm.","category":"page"},{"location":"concept_reference/units_on_cost/","page":"-","title":"-","text":"By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.","category":"page"},{"location":"concept_reference/compression_factor/","page":"-","title":"-","text":"This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.","category":"page"},{"location":"concept_reference/connection_type_list/","page":"-","title":"-","text":"connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details","category":"page"},{"location":"concept_reference/model__default_investment_stochastic_structure/","page":"-","title":"-","text":"The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/units_started_up_coefficient/","page":"-","title":"-","text":"The units_started_up_coefficient is an optional parameter that can be used to include the units_started_up variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_started_up_coefficient appears as a coefficient for the units_started_up variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/minimum_operating_point/","page":"-","title":"-","text":"The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.","category":"page"},{"location":"concept_reference/minimum_operating_point/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/units_on_coefficient/","page":"-","title":"-","text":"The units_on_coefficient is an optional parameter that can be used to include the units_on variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_on_coefficient appears as a coefficient for the units_on variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/curtailment_cost/","page":"-","title":"-","text":"By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"diff_coeff(node1=n1, node2=n2),","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/fix_storages_invested/","page":"-","title":"-","text":"Used primarily to fix the value of the storages_invested variable which represents the point-in-time storage investment decision variable at a node and how many candidate storages are invested-in in a particular timeslice at the corresponding node.","category":"page"},{"location":"concept_reference/fix_storages_invested/","page":"-","title":"-","text":"See also Investment Optimization, candidate_storages and storage_investment_variable_type","category":"page"},{"location":"concept_reference/shut_down_cost/","page":"-","title":"-","text":"By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/node__temporal_block/","page":"-","title":"-","text":"This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.","category":"page"},{"location":"concept_reference/node__temporal_block/","page":"-","title":"-","text":"For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.","category":"page"},{"location":"concept_reference/tax_in_unit_flow/","page":"-","title":"-","text":"By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/min_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_out/","page":"-","title":"-","text":"The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/unit__node__node/","page":"-","title":"-","text":"While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.","category":"page"},{"location":"concept_reference/unit__node__node/","page":"-","title":"-","text":"In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.","category":"page"},{"location":"concept_reference/fix_unit_flow_op/","page":"-","title":"-","text":"If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.","category":"page"},{"location":"concept_reference/connection__investment_stochastic_structure/","page":"-","title":"-","text":"The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.","category":"page"},{"location":"concept_reference/connection__investment_stochastic_structure/","page":"-","title":"-","text":"The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/upward_reserve/","page":"-","title":"-","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/fix_units_on/","page":"-","title":"-","text":"The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/unit_availability_factor/","page":"-","title":"-","text":"To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.","category":"page"},{"location":"concept_reference/fix_connections_invested_available/","page":"-","title":"-","text":"The fix_connections_invested_available parameter represents a forced connection investment.","category":"page"},{"location":"concept_reference/fix_connections_invested_available/","page":"-","title":"-","text":"In other words, it is the fix value of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/stochastic_scenario/","page":"-","title":"-","text":"Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.","category":"page"},{"location":"tutorial/webinars/#Webinars","page":"Webinars","title":"Webinars","text":"","category":"section"},{"location":"tutorial/webinars/","page":"Webinars","title":"Webinars","text":"SpinOpt tutorial covers the entire process from installing Spine Toolbox and SpineOpt, creating and running a model with these tools and manipulating databases.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_in/","page":"-","title":"-","text":"The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows. ","category":"page"},{"location":"concept_reference/Parameters/#Parameters","page":"Parameters","title":"Parameters","text":"","category":"section"},{"location":"concept_reference/Parameters/#balance_type","page":"Parameters","title":"balance_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for how the :nodal_balance constraint should be handled.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: balance_type_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: balance_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_connections_invested","page":"Parameters","title":"benders_starting_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of connections invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_storages_invested","page":"Parameters","title":"benders_starting_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of storages invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_units_invested","page":"Parameters","title":"benders_starting_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of units invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#big_m","page":"Parameters","title":"big_m","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Sufficiently large number used for linearization bilinear terms, e.g. to enforce bidirectional flow for gas pipielines","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1000000","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.","category":"page"},{"location":"concept_reference/Parameters/#block_end","page":"Parameters","title":"block_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The end time for the temporal_block. Can be given either as a DateTime for a static end point, or as a Duration for an end point relative to the start of the current optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.","category":"page"},{"location":"concept_reference/Parameters/#block_start","page":"Parameters","title":"block_start","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The start time for the temporal_block. Can be given either as a DateTime for a static start point, or as a Duration for an start point relative to the start of the current optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.","category":"page"},{"location":"concept_reference/Parameters/#candidate_connections","page":"Parameters","title":"candidate_connections","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The number of connections that may be invested in","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The candidate_connections parameter denotes the possibility of investing on a certain connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value of nothing means that the connection can't be invested in, because it's already in operation. An integer value represents the maximum investment possible at any point in time, as a factor of the connection_capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In other words, candidate_connections is the upper bound of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/Parameters/#candidate_storages","page":"Parameters","title":"candidate_storages","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the maximum number of new storages which may be invested in","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and storage_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#candidate_units","page":"Parameters","title":"candidate_units","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Number of units which may be additionally constructed","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#commodity_lodf_tolerance","page":"Parameters","title":"commodity_lodf_tolerance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum absolute value of the line outage distribution factor (LODF) that is considered meaningful.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/Parameters/#commodity_physics","page":"Parameters","title":"commodity_physics","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines if the commodity follows lodf or ptdf physics.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: commodity_physics_none","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: commodity_physics_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#commodity_physics_duration","page":"Parameters","title":"commodity_physics_duration","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For how long the commodity_physics should apply relative to the start of the window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#commodity_ptdf_threshold","page":"Parameters","title":"commodity_ptdf_threshold","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum absolute value of the power transfer distribution factor (PTDF) that is considered meaningful.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.001","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/Parameters/#compression_factor","page":"Parameters","title":"compression_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The compression factor establishes a compression from an origin node to a receiving node, which are connected through a connection. The first node corresponds to the origin node, the second to the (compressed) destination node. Typically the value is >=1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.","category":"page"},{"location":"concept_reference/Parameters/#connection_availability_factor","page":"Parameters","title":"connection_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability of the connection, acting as a multiplier on its connection_capacity. Typically between 0-1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.","category":"page"},{"location":"concept_reference/Parameters/#connection_capacity","page":"Parameters","title":"connection_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limits the connection_flow variable to the to_node. to_node can be a group of nodes, in which case the sum of the connection_flow is constrained.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.","category":"page"},{"location":"concept_reference/Parameters/#connection_contingency","page":"Parameters","title":"connection_contingency","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for defining a contingency connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#connection_conv_cap_to_flow","page":"Parameters","title":"connection_conv_cap_to_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for connection_capacity unit conversions in the case the connection_capacity value is incompatible with the desired connection_flow units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_conv_cap_to_flow can be used to perform the conversion between the measurement unit of the connection_capacity to the measurement unit of the connection_flow variable. The default of this parameter is 1, i.e. assuming that both are given in the same measurement unit.","category":"page"},{"location":"concept_reference/Parameters/#connection_emergency_capacity","page":"Parameters","title":"connection_emergency_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The maximum post-contingency flow on a monitored connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_emergency_capacity parameter represents the maximum post-contingency flow on a monitored connection if ptdf and lodf based security constrained unit commitment is enabled (commodity_physics is set to [commodity_physics_lodf]).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If you set this value, make sure that you also set connection_monitored to true for the involved connection.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_coefficient","page":"Parameters","title":"connection_flow_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"defines the user constraint coefficient on the connection flow variable in the to direction","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node__user_constraint and connection__to_node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_flow_coefficient is an optional parameter that can be used to include the connection_flow variable from or to a node in a user_constraint via the connection__from_node__user_constraint and connection__to_node__user_constraint relationships. Essentially, connection_flow_coefficient appears as a coefficient for the connection_flow variable from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_cost","page":"Parameters","title":"connection_flow_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable costs of a flow through a connection. E.g. EUR/MWh of energy throughput.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_delay","page":"Parameters","title":"connection_flow_delay","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Delays the connection_flows associated with the latter node in respect to the connection_flows associated with the first node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"0h\", \"type\" => \"duration\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_flow_delay parameter denotes the amount of time that it takes for the flow to go through a connection. In other words, the flow that enters the connection is only seen at the other side after connection_flow_delay units of time.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_non_anticipativity_margin","page":"Parameters","title":"connection_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which connection_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_non_anticipativity_time","page":"Parameters","title":"connection_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the connection_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_intact_flow_non_anticipativity_margin","page":"Parameters","title":"connection_intact_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which connection_intact_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_intact_flow_non_anticipativity_time","page":"Parameters","title":"connection_intact_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the connection_intact_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_cost","page":"Parameters","title":"connection_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit investment cost for the connection over the connection_investment_lifetime","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_lifetime","page":"Parameters","title":"connection_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the minimum investment lifetime of a connection. Once invested, it remains in service for this long","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_variable_type","page":"Parameters","title":"connection_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether the investment variable is integer variable_type_integer or continuous variable_type_continuous","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: variable_type_integer","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.","category":"page"},{"location":"concept_reference/Parameters/#connection_linepack_constant","page":"Parameters","title":"connection_linepack_constant","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The linepack constant is a property of gas pipelines and relates the linepack to the pressure of the adjacent nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.","category":"page"},{"location":"concept_reference/Parameters/#connection_monitored","page":"Parameters","title":"connection_monitored","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for defining a contingency connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When using ptdf-based load flow by setting commodity_physics to either commodity_physics_ptdf or commodity_physics_ptdf, a constraint is created for each connection for which connection_monitored = true. Thus, to monitor the ptdf-based flow on a particular connection connection_monitored must be set to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#connection_reactance","page":"Parameters","title":"connection_reactance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit reactance of a connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node. ","category":"page"},{"location":"concept_reference/Parameters/#connection_reactance_base","page":"Parameters","title":"connection_reactance_base","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If the reactance is given for a p.u. (e.g. p.u. = 100MW), the connection_reactance_base can be set to perform this conversion (e.g. *100).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"As the connection_reactance is often given on a per unit basis, often different than the units used elsewhere, the connection_reactance_base parameter serves as a conversion factor, scaling the connection_reactance with its p.u..","category":"page"},{"location":"concept_reference/Parameters/#connection_resistance","page":"Parameters","title":"connection_resistance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit resistance of a connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit resistance of a transmission line. Currently unimplemented!","category":"page"},{"location":"concept_reference/Parameters/#connection_type","page":"Parameters","title":"connection_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector between a normal and a lossless bidirectional connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: connection_type_normal","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: connection_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"relationship: connection__from_node\nrelationship: connection__to_node\nparameter: connection_capacity (defined on connection__from_node and/or connection__to_node)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"reciprocal connection__from_node and connection__to_node relationships are created if they don't exist\na new connection__node__node relationship is created if none exists already\nfix_ratio_out_in_connection_flow parameter is created with the value of 1 if no existing parameter found (therefore this value can be overridden)\nThe first connection_capacity parameter found is copied to connection__from_nodes and connection__to_nodes without a defined connection_capacity.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_available_coefficient","page":"Parameters","title":"connections_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of connections_invested_available in the specific user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_big_m_mga","page":"Parameters","title":"connections_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate connections.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_coefficient","page":"Parameters","title":"connections_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of connections_invested in the specific user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_coefficient is an optional parameter that can be used to include the connections_invested variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_coefficient appears as a coefficient for the connections_invested variable in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_mga","page":"Parameters","title":"connections_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: connections_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of connections_invested_mga is set to true, investment decisions in this connection, or group of connections, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_mga_weight","page":"Parameters","title":"connections_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weightd sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#constraint_sense","page":"Parameters","title":"constraint_sense","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for the sense of the user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: ==","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: constraint_sense_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The constraint_sense parameter determines the sense of a custom user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See User constraints for details.","category":"page"},{"location":"concept_reference/Parameters/#curtailment_cost","page":"Parameters","title":"curtailment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs for curtailing generation. Essentially, accrues costs whenever unit_flow not operating at its maximum available capacity. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#cyclic_condition","page":"Parameters","title":"cyclic_condition","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If the cyclic condition is set to true for a storage node, the node_state at the end of the optimization window has to be larger than or equal to the initial storage state.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The cyclic_condition parameter is used to enforce that the storage level at the end of the optimization window is higher or equal to the storage level at the beginning optimization. If the cyclic_condition parameter is set to true for a node__temporal_block relationship, and the has_state parameter of the corrresponding node is set to true, the constraint_cyclic_node_state will be triggered.","category":"page"},{"location":"concept_reference/Parameters/#db_lp_solver","page":"Parameters","title":"db_lp_solver","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Solver for MIP problems. Solver package must be added and pre-configured in Julia. Overrides lp_solver RunSpineOpt kwarg","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: HiGHS.jl","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: db_lp_solver_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/Parameters/#db_lp_solver_options","page":"Parameters","title":"db_lp_solver_options","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map parameter containing LP solver option name option value pairs. See solver documentation for supported solver options","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => Any[Any[\"HiGHS.jl\", Dict{String, Any}(\"data\" => Any[Any[\"presolve\", \"on\"], Any[\"timelimit\", 300.01]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"Clp.jl\", Dict{String, Any}(\"data\" => Any[Any[\"LogLevel\", 0.0]], \"type\" => \"map\", \"indextype\" => \"str\")]], \"type\" => \"map\", \"indextype\" => \"str\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_lp_solver_options map parameter)","category":"page"},{"location":"concept_reference/Parameters/#db_mip_solver","page":"Parameters","title":"db_mip_solver","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Solver for MIP problems. Solver package must be added and pre-configured in Julia. Overrides mip_solver RunSpineOpt kwarg","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: HiGHS.jl","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: db_mip_solver_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/Parameters/#db_mip_solver_options","page":"Parameters","title":"db_mip_solver_options","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map parameter containing MIP solver option name option value pairs for MIP. See solver documentation for supported solver options","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => Any[Any[\"HiGHS.jl\", Dict{String, Any}(\"data\" => Any[Any[\"presolve\", \"on\"], Any[\"miprelgap\", 0.01], Any[\"threads\", 0.0], Any[\"timelimit\", 300.01]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"Cbc.jl\", Dict{String, Any}(\"data\" => Any[Any[\"ratioGap\", 0.01], Any[\"logLevel\", 0.0]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"CPLEX.jl\", Dict{String, Any}(\"data\" => Any[Any[\"CPXPARAMEPGAP\", 0.01]], \"type\" => \"map\", \"indextype\" => \"str\")]], \"type\" => \"map\", \"index_type\" => \"str\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_mip_solver_options map parameter)","category":"page"},{"location":"concept_reference/Parameters/#demand","page":"Parameters","title":"demand","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Demand for the commodity of a node. Energy gains can be represented using negative demand.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand parameter represents a \"demand\" or a \"load\" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as \"demand\" or \"load\" for the modelled system, while negative values provide the system with \"influx\" or \"gain\". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.","category":"page"},{"location":"concept_reference/Parameters/#demand_coefficient","page":"Parameters","title":"demand_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of the specified node's demand in the specified user constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand_coefficient is an optional parameter that can be used to include the demand of the a node in a user_constraint via the node__user_constraint relationship. Essentially, demand_coefficient appears as a coefficient for the demand parameter of the connected node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#diff_coeff","page":"Parameters","title":"diff_coeff","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Commodity diffusion coefficient between two nodes. Effectively, denotes the diffusion power per unit of state from the first node to the second.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"diff_coeff(node1=n1, node2=n2),","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/Parameters/#downward_reserve","page":"Parameters","title":"downward_reserve","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Identifier for nodes providing downward reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/Parameters/#duration_unit","page":"Parameters","title":"duration_unit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the base temporal unit of the model. Currently supported values are either an hour or a minute.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: hour","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: duration_unit_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"concept_reference/Parameters/#equal_investments","page":"Parameters","title":"equal_investments","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether all entities in the group must have the same investment decision.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#fix_binary_gas_connection_flow","page":"Parameters","title":"fix_binary_gas_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_flow_binary variable, and hence pre-determine the direction of flow in the connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The binary flow of a gas pipelines for pressure driven gas transfer is enables through the binary variable binary_gas_connection_flow and the big_m constant. To fix this binary variable, i.e. pre-define the direction of gas through the pipelines, the fix_binary_gas_connection_flow parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_connection_flow","page":"Parameters","title":"fix_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connection_flow parameter fixes the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/#fix_connection_intact_flow","page":"Parameters","title":"fix_connection_intact_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_intact_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connection_intact_flow parameter can be used to fix the values of the connection_intact_flow variable to preset values. If set to a Scalar type value, the connection_intact_flow variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/Parameters/#fix_connections_invested","page":"Parameters","title":"fix_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connections_invested variable accordingly","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connections_invested parameter can be used to fix the values of the connections_invested variable to preset values. If set to a Scalar type value, the connections_invested variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See Investment Optimization for more information about the investment framework in SpineOpt.jl.","category":"page"},{"location":"concept_reference/Parameters/#fix_connections_invested_available","page":"Parameters","title":"fix_connections_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connectionsinvestedavailable variable accordingly","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connections_invested_available parameter represents a forced connection investment.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In other words, it is the fix value of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_pressure","page":"Parameters","title":"fix_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_pressure variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_state","page":"Parameters","title":"fix_node_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_state variable to the provided value. Can be used for e.g. fixing boundary conditions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_voltage_angle","page":"Parameters","title":"fix_node_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_voltage_angle variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_nonspin_units_shut_down","page":"Parameters","title":"fix_nonspin_units_shut_down","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the nonspin_units_shut_down variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_nonspin_units_started_up","page":"Parameters","title":"fix_nonspin_units_started_up","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the nonspin_units_started_up variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_in_in_unit_flow","page":"Parameters","title":"fix_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_in_out_unit_flow","page":"Parameters","title":"fix_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_in_connection_flow","page":"Parameters","title":"fix_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_in_unit_flow","page":"Parameters","title":"fix_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_out_unit_flow","page":"Parameters","title":"fix_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#fix_storages_invested","page":"Parameters","title":"fix_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to fix the value of the storages_invested variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the storages_invested variable which represents the point-in-time storage investment decision variable at a node and how many candidate storages are invested-in in a particular timeslice at the corresponding node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_storages and storage_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_storages_invested_available","page":"Parameters","title":"fix_storages_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to fix the value of the storagesinvestedavailable variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also candidate_storages and Investment Optimization","category":"page"},{"location":"concept_reference/Parameters/#fix_unit_flow","page":"Parameters","title":"fix_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.","category":"page"},{"location":"concept_reference/Parameters/#fix_unit_flow_op","page":"Parameters","title":"fix_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the unit_flow_op variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_invested","page":"Parameters","title":"fix_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_invested variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the units_invested variable which represents the point-in-time unit investment decision variable and how many candidate units are invested-in in a particular timeslice.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_units_invested_available","page":"Parameters","title":"fix_units_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_invested_available variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on","page":"Parameters","title":"fix_units_on","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_on variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_in_in","page":"Parameters","title":"fix_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_in_out","page":"Parameters","title":"fix_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_out_in","page":"Parameters","title":"fix_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_out_out","page":"Parameters","title":"fix_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#fixed_pressure_constant_0","page":"Parameters","title":"fixed_pressure_constant_0","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed pressure points for pipelines for the outer approximation of the Weymouth approximation. The direction of flow is the first node in the relationship to the second node in the relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/Parameters/#fixed_pressure_constant_1","page":"Parameters","title":"fixed_pressure_constant_1","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed pressure points for pipelines for the outer approximation of the Weymouth approximation. The direction of flow is the first node in the relationship to the second node in the relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/Parameters/#fom_cost","page":"Parameters","title":"fom_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed operation and maintenance costs of a unit. Essentially, a cost coefficient on the existing units (incl. number_of_units and units_invested_available) and unit_capacity parameters. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.","category":"page"},{"location":"concept_reference/Parameters/#forced_availability_factor","page":"Parameters","title":"forced_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability factor due to outages/deratings.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection and unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#frac_state_loss","page":"Parameters","title":"frac_state_loss","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Self-discharge coefficient for node_state variables. Effectively, represents the loss power per unit of state.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.","category":"page"},{"location":"concept_reference/Parameters/#fractional_demand","page":"Parameters","title":"fractional_demand","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fraction of a node group's demand applied for the node in question.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whenever a node is a member of a group, the fractional_demand parameter represents its share of the group's demand.","category":"page"},{"location":"concept_reference/Parameters/#fuel_cost","page":"Parameters","title":"fuel_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable fuel costs than can be attributed to a unit_flow. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#graph_view_position","page":"Parameters","title":"graph_view_position","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"An optional setting for tweaking the position of the different elements when drawing them via Spine Toolbox Graph View.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection, node and unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node, connection__to_node, unit__from_node__user_constraint, unit__from_node, unit__to_node__user_constraint and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.","category":"page"},{"location":"concept_reference/Parameters/#has_binary_gas_flow","page":"Parameters","title":"has_binary_gas_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter needs to be set to true in order to represent bidirectional pressure drive gas transfer.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.","category":"page"},{"location":"concept_reference/Parameters/#has_pressure","page":"Parameters","title":"has_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_pressure variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here","category":"page"},{"location":"concept_reference/Parameters/#has_state","page":"Parameters","title":"has_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.","category":"page"},{"location":"concept_reference/Parameters/#has_voltage_angle","page":"Parameters","title":"has_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_voltage_angle variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here","category":"page"},{"location":"concept_reference/Parameters/#initial_binary_gas_connection_flow","page":"Parameters","title":"initial_binary_gas_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_flow_binary variable, and hence pre-determine the direction of flow in the connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connection_flow","page":"Parameters","title":"initial_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connection_intact_flow","page":"Parameters","title":"initial_connection_intact_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_intact_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connections_invested","page":"Parameters","title":"initial_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connections_invested variable at the beginning","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connections_invested_available","page":"Parameters","title":"initial_connections_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connectionsinvestedavailable variable at the beginning","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_pressure","page":"Parameters","title":"initial_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_pressure variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_state","page":"Parameters","title":"initial_node_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_state variable to the provided value.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_voltage_angle","page":"Parameters","title":"initial_node_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_voltage_angle variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_nonspin_units_shut_down","page":"Parameters","title":"initial_nonspin_units_shut_down","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the nonspin_units_shut_down variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_nonspin_units_started_up","page":"Parameters","title":"initial_nonspin_units_started_up","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the nonspin_units_started_up variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_storages_invested","page":"Parameters","title":"initial_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to initialze the value of the storages_invested variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_storages_invested_available","page":"Parameters","title":"initial_storages_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to initialze the value of the storagesinvestedavailable variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_unit_flow","page":"Parameters","title":"initial_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_unit_flow_op","page":"Parameters","title":"initial_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the unit_flow_op variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_invested","page":"Parameters","title":"initial_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_invested variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_invested_available","page":"Parameters","title":"initial_units_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_invested_available variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_on","page":"Parameters","title":"initial_units_on","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_on variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#is_active","page":"Parameters","title":"is_active","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If false, the object is excluded from the model if the tool filter object activity control is specified","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: true","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity, connection, model, node, output, report, stochastic_scenario, stochastic_structure, temporal_block, unit and user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__stochastic_structure, node__temporal_block, unit__from_node, unit__to_node, units_on__stochastic_structure and units_on__temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not. ","category":"page"},{"location":"concept_reference/Parameters/#is_non_spinning","page":"Parameters","title":"is_non_spinning","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node is acting as a non-spinning reserve","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/Parameters/#is_renewable","page":"Parameters","title":"is_renewable","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether the unit is renewable - used in the minimum renewable generation constraint within the Benders master problem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.","category":"page"},{"location":"concept_reference/Parameters/#is_reserve_node","page":"Parameters","title":"is_reserve_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node is acting as a reserve_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/Parameters/#max_cum_in_unit_flow_bound","page":"Parameters","title":"max_cum_in_unit_flow_bound","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Set a maximum cumulative upper bound for a unit_flow","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)","category":"page"},{"location":"concept_reference/Parameters/#max_gap","page":"Parameters","title":"max_gap","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the maximum optimality gap for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.05","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.","category":"page"},{"location":"concept_reference/Parameters/#max_iterations","page":"Parameters","title":"max_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the maximum number of iterations for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 10.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.","category":"page"},{"location":"concept_reference/Parameters/#max_mga_iterations","page":"Parameters","title":"max_mga_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Define the number of mga iterations, i.e. how many alternative solutions will be generated.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.","category":"page"},{"location":"concept_reference/Parameters/#max_mga_slack","page":"Parameters","title":"max_mga_slack","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the maximum slack by which the alternative solution may differ from the original solution (e.g. 5% more than initial objective function value)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.05","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).","category":"page"},{"location":"concept_reference/Parameters/#max_node_pressure","page":"Parameters","title":"max_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum allowed gas pressure at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), an upper bound on the pressure can be introduced through the max_node_pressure parameter, which triggers the generation of the maxmimum node pressure constraint.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_in_in_unit_flow","page":"Parameters","title":"max_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_in_out_unit_flow","page":"Parameters","title":"max_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_in_connection_flow","page":"Parameters","title":"max_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_in_unit_flow","page":"Parameters","title":"max_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_out_unit_flow","page":"Parameters","title":"max_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#max_total_cumulated_unit_flow_from_node","page":"Parameters","title":"max_total_cumulated_unit_flow_from_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the maximum cumulated flows of a unit group from a node group e.g max consumption of certain commodity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#max_total_cumulated_unit_flow_to_node","page":"Parameters","title":"max_total_cumulated_unit_flow_to_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the maximum cumulated flows of a unit group to a node group, e.g. total GHG emissions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_in_in","page":"Parameters","title":"max_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_in_out","page":"Parameters","title":"max_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_out_in","page":"Parameters","title":"max_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_out_out","page":"Parameters","title":"max_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#max_voltage_angle","page":"Parameters","title":"max_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum allowed voltage angle at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), an upper bound on the voltage angle can be introduced through the max_voltage_angle parameter, which triggers the generation of the maximum node voltage angle constraint.","category":"page"},{"location":"concept_reference/Parameters/#maximum_capacity_invested_available","page":"Parameters","title":"maximum_capacity_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Upper bound on the capacity invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#maximum_entities_invested_available","page":"Parameters","title":"maximum_entities_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Upper bound on the number of entities invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_down_time","page":"Parameters","title":"min_down_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum downtime of a unit after it shuts down.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/Parameters/#min_iterations","page":"Parameters","title":"min_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the minimum number of iterations for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_node_pressure","page":"Parameters","title":"min_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum allowed gas pressure at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), a lower bound on the pressure can be introduced through the min_node_pressure parameter, which triggers the generation of the minimum node pressure constraint.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_in_in_unit_flow","page":"Parameters","title":"min_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_in_out_unit_flow","page":"Parameters","title":"min_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_in_connection_flow","page":"Parameters","title":"min_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_in_unit_flow","page":"Parameters","title":"min_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_out_unit_flow","page":"Parameters","title":"min_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#min_total_cumulated_unit_flow_from_node","page":"Parameters","title":"min_total_cumulated_unit_flow_from_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the minimum cumulated flows of a unit group from a node group.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows. ","category":"page"},{"location":"concept_reference/Parameters/#min_total_cumulated_unit_flow_to_node","page":"Parameters","title":"min_total_cumulated_unit_flow_to_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the minimum cumulated flows of a unit group to a node group, e.g. total renewable production.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#min_unit_flow","page":"Parameters","title":"min_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Set lower bound of the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_in_in","page":"Parameters","title":"min_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_in_out","page":"Parameters","title":"min_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_out_in","page":"Parameters","title":"min_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_out_out","page":"Parameters","title":"min_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#min_up_time","page":"Parameters","title":"min_up_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum uptime of a unit after it starts up.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/Parameters/#min_voltage_angle","page":"Parameters","title":"min_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum allowed voltage angle at node. ","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), a lower bound on the pressure can be introduced through the min_voltage_angle parameter, which triggers the generation of the minimum node voltage angle constraint.","category":"page"},{"location":"concept_reference/Parameters/#minimum_capacity_invested_available","page":"Parameters","title":"minimum_capacity_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Lower bound on the capacity invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#minimum_entities_invested_available","page":"Parameters","title":"minimum_entities_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Lower bound on the number of entities invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#minimum_operating_point","page":"Parameters","title":"minimum_operating_point","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum level for the unit_flow relative to the units_on online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/#minimum_reserve_activation_time","page":"Parameters","title":"minimum_reserve_activation_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration a certain reserve product needs to be online/available","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves","category":"page"},{"location":"concept_reference/Parameters/#model_end","page":"Parameters","title":"model_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the last timestamp to be modelled. Rolling optimization terminates after passing this point.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"2000-01-02T00:00:00\", \"type\" => \"date_time\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/Parameters/#model_start","page":"Parameters","title":"model_start","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the first timestamp to be modelled. Relative temporal_blocks refer to this value for their start and end.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"2000-01-01T00:00:00\", \"type\" => \"date_time\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/Parameters/#model_type","page":"Parameters","title":"model_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to identify model objects as relating to the master problem or operational sub problems (default)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: spineopt_standard","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: model_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_standard uses the standard algorithm.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_benders uses the Benders decomposition algorithm (see Decomposition.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_mga uses the Model to Generate Alternatives algorithm.","category":"page"},{"location":"concept_reference/Parameters/#mp_min_res_gen_to_demand_ratio","page":"Parameters","title":"mp_min_res_gen_to_demand_ratio","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio of renewable generation to demand for this commodity - used in the minimum renewable generation constraint within the Benders master problem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A unit can be marked as a renewable generation source by setting is_renewable to true.","category":"page"},{"location":"concept_reference/Parameters/#mp_min_res_gen_to_demand_ratio_slack_penalty","page":"Parameters","title":"mp_min_res_gen_to_demand_ratio_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Penalty for violating the minimum renewable generation to demand ratio.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.","category":"page"},{"location":"concept_reference/Parameters/#nodal_balance_sense","page":"Parameters","title":"nodal_balance_sense","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for nodal_balance constraint sense.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: ==","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: constraint_sense_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.","category":"page"},{"location":"concept_reference/Parameters/#node_opf_type","page":"Parameters","title":"node_opf_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for the reference node (slack bus) when PTDF-based DC load-flow is enabled.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: node_opf_type_normal","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: node_opf_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to identify the reference node (or slack bus) when ptdf based dc load flow is enabled (commodity_physics set to commodity_physics_ptdf or commodity_physics_lodf. To identify the reference node, set node_opf_type = :node_opf_type_reference","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow.","category":"page"},{"location":"concept_reference/Parameters/#node_slack_penalty","page":"Parameters","title":"node_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty cost for node_slack_pos and node_slack_neg variables. The slack variables won't be included in the model unless there's a cost defined for them.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.","category":"page"},{"location":"concept_reference/Parameters/#node_state_cap","page":"Parameters","title":"node_state_cap","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The maximum permitted value for a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.","category":"page"},{"location":"concept_reference/Parameters/#node_state_coefficient","page":"Parameters","title":"node_state_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's state variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_coefficient is an optional parameter that can be used to include the node_state variable of a node in a user_constraint via the node__user_constraint relationship. Essentially, node_state_coefficient appears as a coefficient for the node_state variable of the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#node_state_min","page":"Parameters","title":"node_state_min","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum permitted value for a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_min parameter sets the lower bound for the node_state variable, if one has been enabled by the has_state parameter. For reserve nodes with minimum_reserve_activation_time, the node_state_min is considered also via a special constraint.","category":"page"},{"location":"concept_reference/Parameters/#number_of_units","page":"Parameters","title":"number_of_units","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Denotes the number of 'sub units' aggregated to form the modelled unit.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value for this parameter is 1.","category":"page"},{"location":"concept_reference/Parameters/#online_variable_type","page":"Parameters","title":"online_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for how the units_on variable is represented within the model.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: unit_online_variable_type_linear","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: unit_online_variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values \"unit_online_variable_type_binary\", \"unit_online_variable_type_integer\", \"unit_online_variable_type_linear\" and \"unit_online_variable_type_none\".","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment). ","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\\_online\\_variable\\_type\\_integer.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.","category":"page"},{"location":"concept_reference/Parameters/#operating_points","page":"Parameters","title":"operating_points","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Decomposes the flow variable into a number of separate operating segment variables. Used to in conjunction with unit_incremental_heat_rate and/or user_constraints","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#ordered_unit_flow_op","page":"Parameters","title":"ordered_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether the segments of this unit flow are ordered as per the rank of their operating points.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.","category":"page"},{"location":"concept_reference/Parameters/#output_db_url","page":"Parameters","title":"output_db_url","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Database url for SpineOpt output.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: report","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.","category":"page"},{"location":"concept_reference/Parameters/#output_resolution","page":"Parameters","title":"output_resolution","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Temporal resolution of the output variables associated with this output.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: output","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The output_resolution parameter indicates the resolution at which output values should be reported.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.","category":"page"},{"location":"concept_reference/Parameters/#overwrite_results_on_rolling","page":"Parameters","title":"overwrite_results_on_rolling","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether or not results from further windows should overwrite results from previous ones.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: true","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: report__output","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.","category":"page"},{"location":"concept_reference/Parameters/#ramp_down_limit","page":"Parameters","title":"ramp_down_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limit the maximum ramp-down rate of an online unit, given as a fraction of the unitcapacity. [rampdown_limit] = %/t, e.g. 0.2/h","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/Parameters/#ramp_up_limit","page":"Parameters","title":"ramp_up_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limit the maximum ramp-up rate of an online unit, given as a fraction of the unitcapacity. [rampup_limit] = %/t, e.g. 0.2/h","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/Parameters/#representative_periods_mapping","page":"Parameters","title":"representative_periods_mapping","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map from date time to representative temporal block name","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To use representative periods in your model, do the following:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.\nDefine a set of temporal_block objects, each corresponding to one representative period.\nSpecify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.\nAssociate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Representative days with seasonal storages.","category":"page"},{"location":"concept_reference/Parameters/#reserve_procurement_cost","page":"Parameters","title":"reserve_procurement_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Procurement cost for reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#resolution","page":"Parameters","title":"resolution","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Temporal resolution of the temporal_block. Essentially, divides the period between block_start and block_end into TimeSlices with the input resolution.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"1h\", \"type\" => \"duration\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.","category":"page"},{"location":"concept_reference/Parameters/#right_hand_side","page":"Parameters","title":"right_hand_side","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The right-hand side, constant term in a user_constraint. Can be time-dependent and used e.g. for complicated efficiency approximations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to specify the right-hand-side, constant term in a user_constraint. See also user_constraint.","category":"page"},{"location":"concept_reference/Parameters/#roll_forward","page":"Parameters","title":"roll_forward","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines how much the model moves ahead in time between solves in a rolling optimization. Without this parameter, everything is solved in as a single optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.","category":"page"},{"location":"concept_reference/Parameters/#shut_down_cost","page":"Parameters","title":"shut_down_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs of shutting down a 'sub unit', e.g. EUR/shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#shut_down_limit","page":"Parameters","title":"shut_down_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ramp-down during shutdowns","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/#start_up_cost","page":"Parameters","title":"start_up_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs of starting up a 'sub unit', e.g. EUR/startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#start_up_limit","page":"Parameters","title":"start_up_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ramp-up during startups","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/#state_coeff","page":"Parameters","title":"state_coeff","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Represents the commodity content of a node_state variable in respect to the unit_flow and connection_flow variables. Essentially, acts as a coefficient on the node_state variable in the :node_injection constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.","category":"page"},{"location":"concept_reference/Parameters/#stochastic_scenario_end","page":"Parameters","title":"stochastic_scenario_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A Duration for when a stochastic_scenario ends and its child_stochastic_scenarios start. Values are interpreted relative to the start of the current solve, and if no value is given, the stochastic_scenario is assumed to continue indefinitely.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_cost","page":"Parameters","title":"storage_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the investment cost per unit state_cap over the investment life of a storage","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_lifetime","page":"Parameters","title":"storage_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum lifetime for storage investment decisions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_storages","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_variable_type","page":"Parameters","title":"storage_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether the storage investment variable is continuous (usually representing capacity) or integer (representing discrete units invested)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: variable_type_integer","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_storages.","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_available_coefficient","page":"Parameters","title":"storages_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's storages invested available variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_big_m_mga","page":"Parameters","title":"storages_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate storages.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_coefficient","page":"Parameters","title":"storages_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's storage investment variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_coefficient is an optional parameter that can be used to include the storages_invested variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_coefficient appears as a coefficient for the storages_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_mga","page":"Parameters","title":"storages_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: storages_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_mga_weight","page":"Parameters","title":"storages_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weighted-sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#tax_in_unit_flow","page":"Parameters","title":"tax_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for incoming unit_flows on this node. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#tax_net_unit_flow","page":"Parameters","title":"tax_net_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for net incoming and outgoing unit_flows on this node. Incoming flows accrue positive net taxes, and outgoing flows accrue negative net taxes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.","category":"page"},{"location":"concept_reference/Parameters/#tax_out_unit_flow","page":"Parameters","title":"tax_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for outgoing unit_flows from this node. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#unit_availability_factor","page":"Parameters","title":"unit_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability of the unit, acting as a multiplier on its unit_capacity. Typically between 0-1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.","category":"page"},{"location":"concept_reference/Parameters/#unit_capacity","page":"Parameters","title":"unit_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum unit_flow capacity of a single 'sub_unit' of the unit.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To set an upper bound on the commodity flow of a unit in a certain direction, the unit_capacity constraint needs to be defined on a unit__to_node or unit__from_node relationship. By defining the parameter, the unit_flow variables to or from a node or a group of nodes will be constrained by the capacity constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that if the unit_capacity parameter is defined on a node group, the sum of all unit_flows within the specified node group will be constrained by the unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#unit_conv_cap_to_flow","page":"Parameters","title":"unit_conv_cap_to_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for unit_capacity unit conversions in the case the unit_capacity value is incompatible with the desired unit_flow units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable. ","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_coefficient","page":"Parameters","title":"unit_flow_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a unit_flow variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node__user_constraint and unit__to_node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_non_anticipativity_margin","page":"Parameters","title":"unit_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which unit_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_non_anticipativity_time","page":"Parameters","title":"unit_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the unit_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#unit_idle_heat_rate","page":"Parameters","title":"unit_idle_heat_rate","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Flow from node1 per unit time and per units_on that results in no additional flow to node2","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/Parameters/#unit_incremental_heat_rate","page":"Parameters","title":"unit_incremental_heat_rate","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Standard piecewise incremental heat rate where node1 is assumed to be the fuel and node2 is assumed to be electriciy. Assumed monotonically increasing. Array type or single coefficient where the number of coefficients must match the dimensions of unit_operating_points","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_cost","page":"Parameters","title":"unit_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Investment cost per 'sub unit' built.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_lifetime","page":"Parameters","title":"unit_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum lifetime for unit investment decisions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_variable_type","page":"Parameters","title":"unit_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether investment variable is integer or continuous.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: unit_investment_variable_type_continuous","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: unit_investment_variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/Parameters/#unit_start_flow","page":"Parameters","title":"unit_start_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Flow from node1 that is incurred when a unit is started up.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/Parameters/#units_invested_available_coefficient","page":"Parameters","title":"units_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the units_invested_available variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_invested_big_m_mga","page":"Parameters","title":"units_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#units_invested_coefficient","page":"Parameters","title":"units_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the units_invested variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_coefficient is an optional parameter that can be used to include the units_invested variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_coefficient appears as a coefficient for the units_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/Parameters/#units_invested_mga","page":"Parameters","title":"units_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: units_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#units_invested_mga_weight","page":"Parameters","title":"units_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weightd sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_on_coefficient","page":"Parameters","title":"units_on_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a units_on variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_on_coefficient is an optional parameter that can be used to include the units_on variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_on_coefficient appears as a coefficient for the units_on variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#units_on_cost","page":"Parameters","title":"units_on_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Objective function coefficient on units_on. An idling cost, for example","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.","category":"page"},{"location":"concept_reference/Parameters/#units_on_non_anticipativity_margin","page":"Parameters","title":"units_on_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which units_on variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_on_non_anticipativity_time","page":"Parameters","title":"units_on_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the units_on variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This is intended to model \"slow\" units whose commitment decision needs to be taken in advance, e.g., in \"day-ahead\" mode, and cannot be changed afterwards.","category":"page"},{"location":"concept_reference/Parameters/#units_started_up_coefficient","page":"Parameters","title":"units_started_up_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a units_started_up variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_started_up_coefficient is an optional parameter that can be used to include the units_started_up variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_started_up_coefficient appears as a coefficient for the units_started_up variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#upward_reserve","page":"Parameters","title":"upward_reserve","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Identifier for nodes providing upward reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/Parameters/#user_constraint_slack_penalty","page":"Parameters","title":"user_constraint_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty for violating a user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#version","page":"Parameters","title":"version","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 9","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: settings","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#vom_cost","page":"Parameters","title":"vom_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable operating costs of a unit_flow variable. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#weight","page":"Parameters","title":"weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Weighting factor of the temporal block associated with the objective function","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so. ","category":"page"},{"location":"concept_reference/Parameters/#weight_relative_to_parents","page":"Parameters","title":"weight_relative_to_parents","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight of the stochastic_scenario in the objective function relative to its parents.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight_relative_to_parents parameter defines how much weight the stochastic_scenario gets in the Objective function. As a stochastic_structure__stochastic_scenario relationship parameter, different stochastic_structures can use different weights for the same stochastic_scenario. Note that every stochastic_scenario that appears in the model must have a weight_relative_to_parents defined for it related to the used stochastic_structure! See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Since the Stochastic Framework in SpineOpt.jl supports stochastic directed acyclic graphs instead of simple stochastic trees, it is possible to define stochastic_structures with converging stochastic_scenarios. In these cases, the child stochastic_scenarios inherint the weight of all of their parents, and the final weight that will appear in the Objective function is calculated as shown below:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.","category":"page"},{"location":"concept_reference/Parameters/#window_duration","page":"Parameters","title":"window_duration","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The duration of the window in case it differs from roll_forward","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#window_weight","page":"Parameters","title":"window_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight of the window in the rolling subproblem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To use weighted rolling representative periods Benders, do the following.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.\nSpecify window_weight as an array of n + 1 floating point values, representing the weight of each window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that it the problem rolls n times, then you have n + 1 windows.","category":"page"},{"location":"concept_reference/Parameters/#write_lodf_file","page":"Parameters","title":"write_lodf_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether the LODF values should be written to a results file.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/Parameters/#write_mps_file","page":"Parameters","title":"write_mps_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for writing an .mps file of the model.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: write_mps_file_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\\_mps\\_on\\_no\\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\\_mps\\_never, no file will be written","category":"page"},{"location":"concept_reference/Parameters/#write_ptdf_file","page":"Parameters","title":"write_ptdf_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether the LODF values should be written to a results file.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/unit__to_node__unit_constraint/","page":"-","title":"-","text":"unit__to_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable from the specified unit to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__to_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"relationship: connection__from_node\nrelationship: connection__to_node\nparameter: connection_capacity (defined on connection__from_node and/or connection__to_node)","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"reciprocal connection__from_node and connection__to_node relationships are created if they don't exist\na new connection__node__node relationship is created if none exists already\nfix_ratio_out_in_connection_flow parameter is created with the value of 1 if no existing parameter found (therefore this value can be overridden)\nThe first connection_capacity parameter found is copied to connection__from_nodes and connection__to_nodes without a defined connection_capacity.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"If you want to change the solver for your optimization problem in SpineOpt, here is some guidance:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"You can change the solvers in your input datastore using the db_lp_solver and db_mip_solver parameter values of the model object.\nYou can specify solver options via the db_lp_solver_options and db_mip_solver_options parameters respectively. These are map parameters where the first key is the solver name exactly as the db_mip_solver or db_lp_solver name, the second key is the solver option name and the value is the option value.\nYou can get a head start by copying the default map values for db_lp_solver_options and db_mip_solver_options. You can access the default values by clicking on the 'Object parameter definition' tab.\nIf you were trying to change the solver using the arguments to run_spineopt(), this is not the recommended way and will soon be deprecated.\nThe solver name corresponds to the name of the Julia package that you will need to install. Some like HiGHs.jl are self contained and include the binaries. Others like CPLEX.jl and Gurobi.jl you will need to point the package to your locally installed binaries - the julia packages have the instructions to do this.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"The first option is the easiest. The more advanced way of using the solver options is illustrated below.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"Set the model parameter values to choose the solvers and set the solver options:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"This is what the solver options map parameter value looks like:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"To get a head start with solver options, you can copy their default map values from the parameter definition tab like this:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/connection_investment_cost/","page":"-","title":"-","text":"By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/min_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/","page":"-","title":"-","text":"A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#Representative-days-with-seasonal-storages","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In order to reduce the problem size, representative periods are often used in optimization models. However, this often limits the ability to properly account for seasonal storages.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In SpineOpt, we provide functionality to use representative days with seasonal storages.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#general_idea_rep_period_seasonal_Storage","page":"Representative days with seasonal storages","title":"General idea","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"The general idea is to mimick the seasonal effects throughout a non-representative period, e.g. a year of optimization, by introducing a specific sequence of the representative periods.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#Usage_rep_period_seasonal_Storage","page":"Representative days with seasonal storages","title":"Usage of representative days and seasonal storages for investment problems","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"Assuming you already have an investment model with a certain temporal structure that works, you can turn it into a representative periods model with the following steps.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"Identify the nodes and units whose flows and statuses you want to model using representative periods, as well as their associated temporal_blocks.\nSelect the representative periods. For example if you are modelling a year, you can select a few weeks (one in summer, one in winder, and one in mid season).\nFor each representative period, create a temporal_block specifying block_start, block_end and resolution.\nAssociate these temporal_blocks to the nodes and units identified in step 1, via node__temporal_block and units_on__temporal_block relationships.\nFinally, for each original temporal_block associated to these nodes and units (those identified in step 1), specify the value of the representative_periods_mapping parameter. This should be a map where each entry associates a date-time to the name of one of the representative period temporal_blocks created in step 3. More specifically, an entry with t as the key and b as the value means that time slices from the original block starting at t, are 'represented' by time slices from the b block. In other words, time slices between t and t plus the duration of b are represented by b.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In SpineOpt, this will be interpreted in the following way:","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"All operational variables, with the exception of the node_state variable, will be created only for the representative periods. For the non-representative periods, SpineOpt will use the variable of the corresponding representative period according to the value of the representative_periods_mapping parameter.\nThe node_state variable and the investment variables will be created for all periods, representative and non-representative.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"The SpinePeriods.jl package provides an alternative, perhaps simpler way to setup a representative periods model based on the automatic selection and ordering of periods.","category":"page"},{"location":"concept_reference/unit_investment_cost/","page":"-","title":"-","text":"By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/number_of_units/","page":"-","title":"-","text":"Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization","category":"page"},{"location":"concept_reference/number_of_units/","page":"-","title":"-","text":"The default value for this parameter is 1.","category":"page"},{"location":"concept_reference/is_renewable/","page":"-","title":"-","text":"A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.","category":"page"},{"location":"concept_reference/_example/","page":"-","title":"-","text":"AN EXAMPLE DESCRIPTION FOR HOW THE AUTOGENERATION OF CONCEPT REFERENCE BASED ON SPINEOPT TEMPLATE WORKS","category":"page"},{"location":"concept_reference/_example/","page":"-","title":"-","text":"References to other sections, e.g. node are handled like this. Don't use the grave accents around the reference name, as it breaks the reference! Grave accents in Documenter.jl refer to docstrings in the code instead of sections in the documentation.","category":"page"},{"location":"concept_reference/start_up_cost/","page":"-","title":"-","text":"By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/report__output/","page":"-","title":"-","text":"The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/storages_invested_coefficient/","page":"-","title":"-","text":"The storages_invested_coefficient is an optional parameter that can be used to include the storages_invested variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_coefficient appears as a coefficient for the storages_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/output_db_url/","page":"-","title":"-","text":"The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.","category":"page"},{"location":"concept_reference/connection_reactance_base/","page":"-","title":"-","text":"As the connection_reactance is often given on a per unit basis, often different than the units used elsewhere, the connection_reactance_base parameter serves as a conversion factor, scaling the connection_reactance with its p.u..","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"concept_reference/units_on__stochastic_structure/","page":"-","title":"-","text":"The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.","category":"page"},{"location":"concept_reference/units_on__stochastic_structure/","page":"-","title":"-","text":"The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/is_non_spinning/","page":"-","title":"-","text":"By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/node__stochastic_structure/","page":"-","title":"-","text":"The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.","category":"page"},{"location":"concept_reference/node__stochastic_structure/","page":"-","title":"-","text":"The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/tax_net_unit_flow/","page":"-","title":"-","text":"By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.","category":"page"},{"location":"concept_reference/report/","page":"-","title":"-","text":"A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/model_start/","page":"-","title":"-","text":"Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.","category":"page"},{"location":"concept_reference/model_start/","page":"-","title":"-","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/constraint_sense/","page":"-","title":"-","text":"The constraint_sense parameter determines the sense of a custom user constraint.","category":"page"},{"location":"concept_reference/constraint_sense/","page":"-","title":"-","text":"See User constraints for details.","category":"page"},{"location":"concept_reference/connection_flow_coefficient/","page":"-","title":"-","text":"The connection_flow_coefficient is an optional parameter that can be used to include the connection_flow variable from or to a node in a user_constraint via the connection__from_node__user_constraint and connection__to_node__user_constraint relationships. Essentially, connection_flow_coefficient appears as a coefficient for the connection_flow variable from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.","category":"page"},{"location":"concept_reference/fix_connection_flow/","page":"-","title":"-","text":"The fix_connection_flow parameter fixes the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/connection_contingency/","page":"-","title":"-","text":"Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).","category":"page"},{"location":"concept_reference/connection_contingency/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/output_resolution/","page":"-","title":"-","text":"The output_resolution parameter indicates the resolution at which output values should be reported.","category":"page"},{"location":"concept_reference/output_resolution/","page":"-","title":"-","text":"If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.","category":"page"},{"location":"concept_reference/max_node_pressure/","page":"-","title":"-","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), an upper bound on the pressure can be introduced through the max_node_pressure parameter, which triggers the generation of the maxmimum node pressure constraint.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_in/","page":"-","title":"-","text":"The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/unit_investment_lifetime/","page":"-","title":"-","text":"Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/unit_investment_lifetime/","page":"-","title":"-","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"To use weighted rolling representative periods Benders, do the following.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.\nSpecify window_weight as an array of n + 1 floating point values, representing the weight of each window.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"Note that it the problem rolls n times, then you have n + 1 windows.","category":"page"},{"location":"concept_reference/connection_monitored/","page":"-","title":"-","text":"When using ptdf-based load flow by setting commodity_physics to either commodity_physics_ptdf or commodity_physics_ptdf, a constraint is created for each connection for which connection_monitored = true. Thus, to monitor the ptdf-based flow on a particular connection connection_monitored must be set to true.","category":"page"},{"location":"concept_reference/connection_monitored/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/min_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/fix_nonspin_units_started_up/","page":"-","title":"-","text":"The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/fix_nonspin_units_started_up/","page":"-","title":"-","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"getting_started/creating_your_own_model/#Creating-Your-Own-Model","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"This part of the guide shows first an example how to insert objects and their parameter data. Then it shows what other objects, relationships and parameter data needs to be added for a very basic model. Lastly, the model instance is run.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"This section explains the process of creating a SpineOpt.jl model from scratch in order to give you an understanding of the underlying principles of the data structure, etc. If you simply want to try something out quickly to see results, check out the Example Models section. Furthermore, if you're in a hurry, the Archetypes section provides you with some pre-made templates for the different parts of a SpineOpt.jl model to get you started quickly.","category":"page"},{"location":"getting_started/creating_your_own_model/#Creating-a-SpineOpt-model-instance","page":"Creating Your Own Model","title":"Creating a SpineOpt model instance","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"First, open the database editor by double-clicking the Input DB. \nRight click on model in the Object tree. \nChoose Add objects. \nThen, add a model object by writing a name to the object name field. You can use e.g. instance. \nClick ok.\nThe model object in SpineOpt is an abstraction that represents the model itself. Every SpineOpt database needs to have at least one model object.\nThe model object holds general information about the optimization. The whole range of functionalities is explained in Advanced Concepts chapter - in here a minimal set of parameters is used.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-parameter-values-to-the-model-instance","page":"Creating Your Own Model","title":"Add parameter values to the model instance","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Select the model object instance from the object tree.\nGo to the Object parameter value tab.\nEvery parameter value belongs to a specific alternative. This allows to hold multiple values for the same parameter of a particular object. The alternative values are used to create scenarios. Choose, Base for all parameter values (Base is required in Spine Toolbox - all other alternatives can be chosen freely).\nThen define a model_start time and a model_end time. \nDouble-click on the empty row under parameter_name and select model_start. \nA None should appear in value column. \nTo asign a start date value, right-click on None and open the editor (cannot be entered directly, since the datatype needs to be changed). \nThe parameter type of model_start is of type Datetime. \nSet the value to e.g. 2019-01-01T00:00:00. \nProceed accordingly for the model_end. ","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image) ","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Further reading on adding parameter values can be found here.","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-other-necessary-objects-and-parameter-data-for-the-objects.","page":"Creating Your Own Model","title":"Add other necessary objects and parameter data for the objects.","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Add all objects and their parameter data by replicating what has been done in the picture below. Do it the same way as explained above with the following caveats.\nWhilst most object names can be freely defined by the user, there is one object name in the example below that needs to be written exactly since it is used internally by SpineOpt: unit_flow. \nThe parameter_name can be selected from a drop down menu.\nThe date time and time series parameter data can be added by using right-click to access the Edit... dialog. When creating the time series, use the fixed resolution with Start time of the model run and with 1h resolution. Then only values need to be entered (or copy pasted) and time stamps come automatically.\nParameter balance_type needs to have value balance_type_none in the gas node, since it allows the node to create energy (natural gas) against a price and therefore the energy balance is not maintained.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Define-temporal-and-stochastic-structures","page":"Creating Your Own Model","title":"Define temporal and stochastic structures","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"To specify the temporal structure for SpineOpt, you need to define temporal_block objects. Think of a temporal_block as a distinctive way of 'slicing' time across the model horizon.\nTo link the temporal structure to the spatial structure, you need to specify node__temporal_block relationships, establishing which temporal__block applies to each node. This relationship is added by right-clicking the node__temporal_block in the relationship tree and then using the add relationships... dialog. Double clicking on an empty cell gives you the list of valid objects. The relationship name is automatically formed, but you can change it if that is desirable.\nTo keep things simple at this point, let's just define one temporal_block for our model and apply it to all nodes. We add the object hourly_temporal_block of type temporal_block following the same procedure as before and establish node__temporal_block relationships between node_gas and hourly_temporal_block, and electricity_node and hourly_temporal_block.\nIn practical terms, the above means that there energy flows over gas_node and electricity_node for each 'time-slice' comprised in hourly_temporal_block.\nSimilarly with the stochastic structure, each node is assigned a deterministic stochastic_structure. ","category":"page"},{"location":"getting_started/creating_your_own_model/#Define-the-spatial-structure","page":"Creating Your Own Model","title":"Define the spatial structure","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"To specify the spatial structure for SpineOpt, you will need to use the node, unit, and connection objects added before.\nNodes can be understood as spatial aggregators. In combination with units and connections, they form the energy network.\nUnits in SpineOpt represent any kind of conversion process. As one example, a unit can represent a power plant that converts the flow of a commodity fuel into an electricity and/or heat flow.\nConnections on the other hand describe the transport of goods from one location to another. Electricity lines and gas pipelines are examples of such connections. This example does not use connections.\nThe database should have an object gas_turbine for the unit object class and objects node_gas and node_elec for the node object class.\nNext, define how the unit and the nodes interact with each other: create a unit__from_node relationship between gas_turbine and node_gas, and unit__to_node relationships between gas_turbine and node_elec.\nIn practical terms, the above means that there is an energy flow going from node_gas into node_elec, through the gas_turbine.","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-remaining-relationships-and-parameter-data-for-the-relationships.","page":"Creating Your Own Model","title":"Add remaining relationships and parameter data for the relationships.","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Similar to adding the objects and their parameter data, add the relationships and their parameter data based on the picture below. \nThe capacity of the gas_turbine has to be sufficient to meet the highest demand for electricity, otherwise the model will be infeasible (it is possible to set penalty values, but they are not included in this example).\nThe parameter fix_ratio_in_out_unit_flow forces the ratio between an input and output flow to be a constant. This is one way to establish an efficiency for a conversion process.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Run-the-model","page":"Creating Your Own Model","title":"Run the model","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Select SpineOpt \nPress Execute selection.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#If-it-fails","page":"Creating Your Own Model","title":"If it fails","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Double-check that the data is correct\nTry to see what the problem might be\nAsk help from the discussion forum","category":"page"},{"location":"getting_started/creating_your_own_model/#Explore-the-results","page":"Creating Your Own Model","title":"Explore the results","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Double-clicking the Results database.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image) ","category":"page"},{"location":"getting_started/creating_your_own_model/#Create-and-run-scenarios-and-build-the-model-further","page":"Creating Your Own Model","title":"Create and run scenarios and build the model further","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Create a new alternative\nAdd parameter data for the new alternative\nConnect alternatives under a scenario. Toolbox modifies Base data with the data from the alternatives in the same scenario.\nExecute multiple scenarios in parallel. First run in a new Julia instance will need to compile SpineOpt taking some time.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"concept_reference/unit__investment_temporal_block/","page":"-","title":"-","text":"unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.","category":"page"},{"location":"concept_reference/unit__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/write_ptdf_file/","page":"-","title":"-","text":"If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/max_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/connection_investment_lifetime/","page":"-","title":"-","text":"connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.","category":"page"},{"location":"concept_reference/fix_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/fix_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/has_binary_gas_flow/","page":"-","title":"-","text":"This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.","category":"page"},{"location":"concept_reference/max_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/min_node_pressure/","page":"-","title":"-","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), a lower bound on the pressure can be introduced through the min_node_pressure parameter, which triggers the generation of the minimum node pressure constraint.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastic-Framework","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Scenario-based stochastics in unit commitment and economic dispatch models typically only consider branching scenario trees. However, sometimes the available stochastic data doesn't span over the entire desired modelling horizon, or all the modelled phenomena. Especially with increasing interest in energy system integration and sector coupling, stochastic data of consistent quality and/or length might be hard to come by.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"While these data issues can be circumvented by either cloning stochastic data across multiple scenario branches or generating dummy forecasts, they can result in inflated problem sizes. Furthermore, Ensuring realistic correlations between generated forecasts is extremely difficult, especially across multiple energy sectors.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The stochastic framework in SpineOpt.jl aims to support stochastic directed acyclic graphs (DAGs) instead of only branching trees, allowing for scenarios to converge later on in the modelled horizon. In addition, the framework allows for slightly different stochastic scenario graphs for different variables, making it easier to define e.g. variables common between all stochastic scenarios.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Key-concepts","page":"Stochastic Framework","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we briefly describe the key concepts required to understand the stochastic framework:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario is essentially just a label for an alternative period of time, describing one possiblity of what may come to pass. Even in deterministic modelling with SpineOpt.jl, a single stochastic_scenario is required for labelling the deterministic timeline.\nStochastic DAG is the directed acyclic graph describing the parent_stochastic_scenario__child_stochastic_scenario relationships between the stochastic scenarios. The key difference between a stochastic DAG and a traditional stochastic tree is that the scenarios are allowed to have multiple parents, making it possible to converge scenarios into each other in addition to branching.\nStochastic path is a unique sequence of stochastic scenarios for traversing the stochastic DAG. Every (finite) stochastic DAG has a limited number of full stochastic paths that traverse it from roots (scenarios without parents) to leaves (scenarios without children). Here, we use the term stochastic path to refer to any subset of scenarios within a full stochastic path.\nstochastic_structure is essentially a \"realization\" of the stochastic DAG, with additional information like the stochastic_scenario_end and weight_relative_to_parents Parameters. These become relevant when we start discussing interactions between different stochastic structures.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above figure presents an example stochastic DAG with the individual stochastic scenarios labelled from s0-s8. An example full stochastic path [s0, s1, s5, s8] is highlighted in red, while an example stochastic path [s2, s4, s7] is highlighted in blue.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#General-idea-in-brief","page":"Stochastic Framework","title":"General idea in brief","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The major issue with stochastic DAGs compared to stochastic trees, is that indexing constraints that include variables from multiple time steps (henceforth referred to as \"dynamic constraints\") needs rethinking. With stochastic trees, constraints can always be unambiguously indexed using (stochastic_scenario, last_time_step), since all stochastic scenarios only have a single parent. However, this is no longer the case for stochastic DAGs, as illustrated in the figures below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"\n","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The example on the left illustrates the \"traditional\" indexing in branching stochastic trees, where backtracking through the tree always leads to unambiguous (stochastic_scenario, time_step) indices. The example on the right shows a similar situation in a stochastic DAG, where backtracking through the DAG leads to four different (stochastic_scenario, time_step) indices, and thus requires four constraints to be generated and indexed.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastic-path-indexing","page":"Stochastic Framework","title":"Stochastic path indexing","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"As discussed in the previous section, dynamic constraints in stochastic DAGs cannot be unambiguously indexed using a single (stochastic_scenario, time_step). However, they can be unambiguously indexed using (stochastic_path, time_step), where the stochastic path is the unique sequence of stochastic scenarios traversing the DAG. Since there are only a limited number of ways to traverse the DAG, represented by the full stochastic paths, we can identify the number of unique paths necessary for constraint generation as follows:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG from roots to leaves.\nFind all the stochastic scenarios that are active on all the time steps included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active stochastic scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-dynamic-constraint-generation","page":"Stochastic Framework","title":"Example dynamic constraint generation","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above figure shows examples of two different dynamic constraints generated in a stochastic DAG: the red constraint including variables from timesteps t4-t5 and the blue constraint including variables from timesteps t1, t3. The full stochastic paths for traversing the above DAG are as follows:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s0, s1, s5, s8]\n[s0, s2, s3, s5, s8]\n[s0, s2, s4, s6, s8]\n[s0, s2, s4, s7, s8]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"For the red constraint, the stochastic scenarios s5-s8 are active on the time steps t4-t5. All the above full stochastic paths include at least two of the active stochastic scenarios, but full paths 1 and 2 both produce an identical path [s5, s8], so the set of unique stochastic paths for the red constraint becomes:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s5, s8]\n[s6, s8]\n[s7, s8]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"There are no paths [s5, s6], [s5, s7], [s6, s7] since following the DAG one cannot start from s5 and end up in s6, even though these stochastic scenarios are active.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The blue constraint illustrates a case where the time step range is non-continuous. The active stochastic scenarios on t1, t3 are s1, s2, s4, s5, so again by comparing these to the full stochastic paths we get:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s1, s5]\n[s2, s5]\n[s2, s4]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"In this case, the full stochastic paths 3 and 4 both produce the path [s2, s4], so only three unique constraints need to be generated. Again, the path [s1, s4] is invalid, since the DAG cannot be traversed from s1 to s4.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Interaction-between-different-stochastic-structures","page":"Stochastic Framework","title":"Interaction between different stochastic structures","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Stochastic path indexing in constraints also allows for \"distorting\" the stochastic DAG in different parts of the model. As long as the stochastic DAG itself isn't changed, meaning the parent_stochastic_scenario__child_stochastic_scenario relationships and the resulting full stochastic paths, we can actually define different stochastic structures and still be able to handle constraint generation between them. This is due to the fact that when determining the stochastic paths, it makes no difference whether we're looking at the same stochastic_structure at different time steps, or at two stochastic structures, one of which has been delayed, on the same time step. This is illustrated by the figure below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above represents constraint generation over two stochastic structures, where the lower stochastic_structure has been delayed in respect to the one above. Nevertheless, the procedure for finding the stochastic paths for the constraints remains identical to the previous example:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. As long as the DAG remains the same between all the involved stochastic structures, the pathing remains the same.\nFind all the stochastic scenarios that are active on all the stochastic structures and time steps included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastics-in-the-model-data-structure","page":"Stochastic Framework","title":"Stochastics in the model data structure","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"While the Key concepts and General idea in brief sections go over the stochastic framework in SpineOpt.jl in a more general sense, here we'll go over how to set up stochastics using SpineOpt.jl data structure. Simple step-by-step examples are also provided in the Example of deterministic stochastics, Example of branching stochastics, and Example of converging stochastics sections further below. We won't go into too much detail about the related Object Classes, Relationship Classes, or Parameters, since those can be found in their respective sections. Introductions to these concepts can also be found in the Structural object classes and Structural relationship classes sections, if necessary.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Setting-up-the-stochastic-framework","page":"Stochastic Framework","title":"Setting up the stochastic framework","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"As with all things in SpineOpt.jl, you'll want to start with adding the desired number of objects to the relevant Object Classes, as one cannot define relationships over objects that don't exist. For the stochastic framework, this means creating at least one stochastic_scenario and stochastic_structure object each. This needs to be done even if your model is fully deterministic, as even the deterministic structure needs to be labelled for SpineOpt.jl to recognize that it exists.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Next, if your model has multiple stochastic_scenario objects, you'll want to define how they are related using the parent_stochastic_scenario__child_stochastic_scenario relationship. This relationship essentially defines the stochastic DAG, as well as all the possible stochastic paths, explained in the Key concepts section. Unless the parent_stochastic_scenario__child_stochastic_scenario relationship is defined, there won't be a stochastic DAG, and all stochastic_scenario objects will be assumed to be completely independent of each other.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Now that you've set up the desired stochastic_scenario and stochastic_structure objects, as well as defined the stochastic DAG using the parent_stochastic_scenario__child_stochastic_scenario relationship, it's time to define the properties of the stochastic_structure objects using the stochastic_structure__stochastic_scenario relationship, and the stochastic_scenario_end and weight_relative_to_parents Parameters therein. You'll always have to define at least one stochastic_structure__stochastic_scenario relationship, as the stochastic_structure object is what connects the Systemic object classes to the stochastic framework. stochastic_structure__stochastic_scenario relationship holds two key Parameters:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"weight_relative_to_parents defines the coefficient the corresponding stochastic_scenario has in the Objective function, and needs to be defined for each stochastic_scenario included in the stochastic_structure. The weight is relative to the parents of the [stochastic_scenario], and is calculated as presented below.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario_end is a Duration type parameter that tells when the stochastic_scenario ends in relation to the start of the current optimization. When defined, the stochastic_scenario ends at the defined point in time, and spawns its children according to parent_stochastic_scenario__child_stochastic_scenario, if any. Note that this means the children are included in the stochastic_structure, even without an explicit relationship! If stochastic_scenario_end isn't defined, the stochastic_scenario is assumed to go on indefinetely.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Finally, with all the pieces in place, we'll need to connect the defined stochastic_structure objects to the desired objects in the Systemic object classes using the Structural relationship classes like node__stochastic_structure etc. Here, we essentially tell which parts of the modelled system use which stochastic_structure. Since creating each of these relationships individually can be a bit of a pain, there are a few Meta relationship classes like the model__default_stochastic_structure, that can be used to set model-wide defaults that are used if specific relationships are missing.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-deterministic-stochastics","page":"Stochastic Framework","title":"Example of deterministic stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create the simplest possible stochastic frame: the fully deterministic one. See the Deterministic Stochastic Structure archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model. ","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Create a stochastic_scenario called e.g. realization and a stochastic_structure called e.g. deterministic.\nWe can skip the parent_stochastic_scenario__child_stochastic_scenario relationship, since there isn't a stochastic DAG in this example, and the default behaviour of each stochastic_scenario being independent works for our purposes (only one stochastic_scenario anyhow).\nCreate the stochastic_structure__stochastic_scenario relationship for (deterministic, realization), and set its weight_relative_to_parents parameter to 1. We don't need to define the stochastic_scenario_end parameter, as we want the realization to go on indefinitely.\nRelate the deterministic stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-branching-stochastics","page":"Stochastic Framework","title":"Example of branching stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create a simple branching stochastic tree, where one scenario branches into three at a specific point in time. See the Branching Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Create four stochastic_scenario objects called e.g. realization, forecast1, forecast2, and forecast3, and a stochastic_structure called e.g. branching.\nDefine the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (realization, forecast1), (realization, forecast2), and (realization, forecast3).\nCreate the stochastic_structure__stochastic_scenario relationship for (branching, realization), (branching, forecast1), (branching, forecast2), and (branching, forecast3).\nSet the weight_relative_to_parents parameter to 1 and the stochastic_scenario_end parameter e.g. to 6h for the stochastic_structure__stochastic_scenario relationship (branching, realization). Now, the realization stochastic_scenario will end after 6 hours of time steps, and its children (forecast1, forecast2, and forecast3) will become active.\nSet the weight_relative_to_parents Parameters for the (branching, forecast1), (branching, forecast2), and (branching, forecast3) stochastic_structure__stochastic_scenario relationships to whatever you desire, e.g. 0.33 for equal probabilities across all forecasts.\nRelate the branching stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-converging-stochastics","page":"Stochastic Framework","title":"Example of converging stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create a simple stochastic DAG, where both branching and converging occurs. This example relies on the previous Example of branching stochastics, but adds another stochastic_scenario at the end, which is a child of the forecast1, forecast2, and forecast3 scenarios. See the Converging Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Follow the steps 1-5 in the previous Example of branching stochastics, except call the stochastic_structure something different, e.g. converging.\nCreate a new stochastic_scenario called e.g. converged_forecast.\nAlter the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (forecast1, converged_forecast), (forecast2, converged_forecast), and (forecast3, converged_forecast). Now all three forecasts will converge into a single converged_forecast.\nAdd the stochastic_structure__stochastic_scenario relationship for (converging, converged_forecast), and set its weight_relative_to_parents parameter to 1. Now, all the probability mass in forecast1, forecast2, and forecast3 will be summed up back to the converged_forecast.\nSet the stochastic_scenario_end Parameters of the stochastic_structure__stochastic_scenario relationships (converging, forecast1), (converging, forecast2), and (converging, forecast3) to e.g. 1D, so that all three scenarios end at the same time and the converged_forecast becomes active.\nRelate the converging stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Working-with-stochastic-updating-data","page":"Stochastic Framework","title":"Working with stochastic updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Now that we've discussed how to set up stochastics for SpineOpt, let's focus on stochastic data. The most complex form of input data SpineOpt can currently handle is both stochastic and updating, meaning that the values the parameter takes can depend on both the stochastic_scenario, and the analysis time (first time step) of each solve. However, just stochastic or just updating cases are supported as well, using the same input data format.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"In SpineOpt, stochastic data uses the Map data type from SpineInterface.jl. Essentially, Maps are general indexed data containers, which SpineOpt tries to interpret as stochastic data. Every time SpineOpt calls a parameter, it passes the stochastic_scenario and analysis time as keyword arguments to the parameter, but depending on the parameter type, it doesn't necessarily do anything with that information. For Map type parameters, those keyword arguments are used for navigating the indices of the Map to try and find the corresponding value. If the Map doesn't include the stochastic_scenario index it's looking for, it assumes there's no stochastic information in the Map and carries on to search for analysis time indices. This logic is useful for defining both stochastic and updating data, as well as either case by itself, as shown in the following examples.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-stochastic-data","page":"Stochastic Framework","title":"Example of stochastic data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By stochastic data, we mean parameter values that depend only on the stochastic_scenario. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario value\nscenario1 value1\nscenario2 value2","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 in scenario1, and value2 in scenario2. Note that since there's no analysis time index in this example, the values are used regardless of the analysis time.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-updating-data","page":"Stochastic Framework","title":"Example of updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By updating data, we mean parameter values that depend only on the analysis time. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"analysis time value\n2000-01-01T00:00:00 value1\n2000-01-01T12:00:00 value2","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00, and value2 if the first time step of the simulation is after 2000-01-01T12:00:00. Note that since there's no stochastic_scenario index in this example, the values are used regardless of the stochastic_scenario.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-stochastic-updating-data","page":"Stochastic Framework","title":"Example of stochastic updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By stochastic updating data, we mean parameter values that depend on both the stochastic_scenario and the analysis time. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario analysis time value\nscenario1 2000-01-01T00:00:00 value1\nscenario1 2000-01-01T12:00:00 value2\nscenario2 2000-01-01T00:00:00 value3\nscenario2 2000-01-01T12:00:00 value4","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where the stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects, and the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00 and the parameter is called in scenario1, and value3 in scenario2. If the first time step of the current simulation is after 2000-01-01T12:00:00, the parameter will take value2 in scenario1, and value4 in scenario2.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Constraint-generation-with-stochastic-path-indexing","page":"Stochastic Framework","title":"Constraint generation with stochastic path indexing","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Every time a constraint might refer to variables either on different time steps or on different stochastic scenarios (meaning different nodes or units), the constraint needs to use stochastic path indexing in order to be correctly generated for arbitrary stochastic DAGs. In practise, this means following the procedure outlined below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. This is done along with generating the stochastic structure, so no real impact on constraint generation.\nFind all the stochastic scenarios that are active on all the stochastic structures and time slices included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Steps 2 and 3 are the crucial ones, and are currently handled by separate constraint__indices functions. Essentially, these functions go through all the variables on all the time steps included in the constraint, collect the set of active stochastic_scenarios on each time step, and then determine the unique active stochastic paths on each time step. The functions pre-form the index set over which the constraint is then generated in the add_constraint_ functions.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Unit-commitment","page":"Unit Commitment","title":"Unit commitment","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To incorporate technical detail about (clustered) unit-commitment statuses of units, the online, started and shutdown status of units can be tracked and constrained in SpineOpt. In the following, relevant relationships and parameters are introduced and the general working principle is described.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Key-concepts-for-unit-commitment","page":"Unit Commitment","title":"Key concepts for unit commitment","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Here, we briefly describe the key concepts involved in the representation of (clustered) unit commitment models:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"units_on is an optimization variable that holds information about the on- or offline status of a unit. Unit commitment restrictions will govern how this variable can change through time.\nunits_on__temporal_block is a relationship linking the units_on variable of this unit to a specific temporal_block object. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.\nonline_variable_type is a method parameter and can take the values unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear. If the binary value is chosen, the units status is modelled as a binary (classic UC). For clustered unit commitment units, the integer type is applicable. Note that if the parameter is not defined, the default will be linear. If the units status is not crucial, this can reduce the computational burden.\nnumber_of_units defines how many units of a certain unit type are available. Typically this parameter takes a binary (UC) or integer (clustered UC) value. To avoid confusion the following distinction will be made in this document: unit will be used to identify a Spine unit object, which can have multiple members. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). The default value for this parameter is 1. It is possible to allow the model to increase the number_of_units itself, through Investment Optimization\nunit_availability_factor: (number value or time series). Is the fraction of the time that this unit is considered to be available, by acting as a multiplier on the capacity. A time series can be used to indicate the intermittent character of renewable generation technologies.\nmin_up_time: (duration value). Sets the minimum time that a unit has to stay online after a startup. Inclusion of this parameter will trigger the creation of the constraint on Minimum up time (basic version)\nmin_down_time: (duration value). Sets the minimum time that a unit has to stay offline after a shutdown. Inclusion of this parameter will trigger the creation of the constraint on Minimum down time (basic version)\nminimum_operating_point: (number value) limits the minimum value of the unit_flow variable for a unit which is currently online. Inclusion of this parameter will trigger the creation of the Constraint on minimum operating point\nstart_up_cost: \"number value\". Cost associated with starting up a unit.\nshut_down_cost: \"number value\". Cost associated with shutting down a unit.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Illustrative-unit-commitment-examples","page":"Unit Commitment","title":"Illustrative unit commitment examples","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/#Step-1:-defining-the-number-of-members-of-a-unit-type","page":"Unit Commitment","title":"Step 1: defining the number of members of a unit type","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"A spine unit can represent multiple members. This can be incorporated in a model by setting the number_of_units parameter to a specific value. For example, if we define a single unit in a model as follows:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"And we link the unit to a certain node_1 with a unit__to_node relationship.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1_to__node_1","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The single Spine unit defined here, now represents two members. This means that a single unit_flow variable will be created for this unit, but the restrictions as imposed by the Ramping and Reserves framework will be adapted to reflect the fact that there are two members present, thus doubling the total capacity.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-2:-choosing-the-online_variable_type","page":"Unit Commitment","title":"Step 2: choosing the online_variable_type","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Next, we have to decide the online_variable_type for this unit, which will restrict the kind of values that the units_on variable can take. This basically comes down to deciding if we are working in a classical UC framework (unit_online_variable_type_binary), a clustered UC framework (unit_online_variable_type_integer), or a relaxed clustered UC framework (unit_online_variable_type_linear), in which a non-integer number of units can be online.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The classical UC framework can only be applied when the number_of_units equals 1.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-3:-imposing-a-minimum-operating-point","page":"Unit Commitment","title":"Step 3: imposing a minimum operating point","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The output of an online unit to a specific node can be restricted to be above a certain minimum by choosing a value for the minimum_operating_point parameter. This parameter is defined for the unit__to_node relationship, and is given as a fraction of the unit_capacity. If we continue with the example above, and define the following objects, relationships, and parameters:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2\nunit_online_variable_type: \"unit_online_variable_type_integer\"\nunit_1_to__node_1\nminimum_operating_point: 0.2\nunit_capacity: 200","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"It can be seen that in this case the unit_flow form unit_1 to node_1 must for any timestep t be larger than units_on(t) * 02 * 200","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-4:-imposing-a-minimum-up-or-down-time","page":"Unit Commitment","title":"Step 4: imposing a minimum up or down time","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Spine units can also be restricted in their commitment status with minimum up- or down times by choosing a value for the min_up_time or min_down_time respectively. These parameters are defined for the unit object, and should be duration values. We can continue the example and add a minimum up time for the unit:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2\nunit_online_variable_type: \"unit_online_variable_type_integer\"\nmin_up_time: 2h\nunit_1_to__node_1\nminimum_operating_point: 0.2\nunit_capacity: 200","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Whereas the units_on variable was restricted (before inclusion of the min_up_time parameter) to be smaller than or equal to the number_of_units for any timestep t, it now has to be smaller than or equal to the number_of_units decremented with the units_started_up summed over the timesteps that include t - min_up_time. This implies that a unit which has started up, has to stay online for at least the min_up_time","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To consider a simple example let's assume that we have a model with a resolution of 1h. Suppose that before t, there is no member of the unit online and in timestep t -> t + 1h, one member starts up. Another member starts up in timestep t + 1h \\-> t + 2h. The first startup, along with the minimum up time of 2 hours implies that the units_on variable of this unit has now changed to 1 in timestep t -> t + 1h and can not go back to 0 in timestep t-> t + 1h -> t + 2h. The second startup further restricts the number of units that are allowed to be online, it can be seen that the following restrictions apply when both startups are combined with the minimum up time of 2h:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"t-> t + 1h : units_on = 1\nt + 1h -> t + 2h: units_on = 2\nt + 2h-> t + 3h: units_on in 12\nt + 3h-> t + 4h: units_on in 012","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The minimum down time restrictions operate in very much the same way, they simply impose that units that have been shut down, have to stay offline for the chosen period of time.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-5:-allocationg-a-cost-to-startups-or-shutdowns","page":"Unit Commitment","title":"Step 5: allocationg a cost to startups or shutdowns","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Costs can be allocated to startups or shutdowns by choosing a value for the start_up_cost or shut_down_cost respectively.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-6:-defining-unit-availabilities","page":"Unit Commitment","title":"Step 6: defining unit availabilities","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"By defining a unit_availability_factor, the fact that typical members are not available all the time can be reflected in the model.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Typically, units are not available 100% of the time, due to scheduled maintenance, unforeseen outages, or other things. This can be incorporated in the model by setting the unit_availability_factor to a fractional value. For each timestep in the model, an upper bound is then imposed on the units_on variable, equal to number_of_units * unit_availability_factor. This parameter can not be used when the online_variable_type is binary. It should also be noted that when the online_variable_type is of integer type, the aforementioned product must be integer as well, since it will determine the value of the units_available parameter which is restricted to integer values. The default value for this parameter is 1.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The unit_availability_factor can also be taken as a timeseries. By allowing a different availability factor for each timestep in the model, it can perfectly be used to represent intermittent technologies of which the output cannot be fully controlled.","category":"page"},{"location":"concept_reference/commodity_physics/","page":"-","title":"-","text":"This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.","category":"page"},{"location":"concept_reference/commodity_physics/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/connections_invested_big_m_mga/","page":"-","title":"-","text":"The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)","category":"page"},{"location":"concept_reference/big_m/","page":"-","title":"-","text":"The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.","category":"page"},{"location":"concept_reference/is_active/","page":"-","title":"-","text":"is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not. ","category":"page"},{"location":"concept_reference/vom_cost/","page":"-","title":"-","text":"By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"See also Investment Optimization and storage_investment_variable_type","category":"page"},{"location":"how_to/define_an_efficiency/#How-to-define-an-efficiency","page":"Define an efficiency","title":"How to define an efficiency","text":"","category":"section"},{"location":"how_to/define_an_efficiency/#relationships-between-the-inputs-and-outputs-of-a-unit","page":"Define an efficiency","title":"relationships between the inputs and outputs of a unit","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The image below shows an overview of the possible relationships between the inputs and outputs of a unit.","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The key capability requirements are:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"Easily define arbitrary numbers of input and output flows\nEasily create piecewise affine linear relationships between any two flows\nAnything more complicated can be done via user_constraints","category":"page"},{"location":"how_to/define_an_efficiency/#unit__node__node-relationship","page":"Define an efficiency","title":"unit__node__node relationship","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The unit__node__node relationship allows you to constrain two nodes to each other via a number of different parameters.:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"unit_incremental_heat_rate: Input_flow = unit_incremental_heat_rate * output_flow + unit_idle_heat_rate * units_on. It can be piecewise linear, used in conjunction with operating_points with monotonically increasing coefficients (not enforced). Used in conjunction with unit_idle_heat_rate triggers a fixed flow when the unit is online and unit_start_flow triggers a flow on a unit start (start fuel consumption)\nfix_ratio_out_in_unit_flow: equivalent to an efficiency. Output_flow = fix_ratio_out_in_unit_flow x output_flow + fix_units_on_coefficient_out_in * units_on. Ordering of the nodes in the unit__node__node relationship matters. The first node will be the output flow and the second node will be treated as the input flow (consistently with the out_in in the parameter name. A units_on coefficient is added with fix_units_on_coefficient_out_in, \nIn addition to fix_ratio_out_in_unit_flow you have [constraint]_ratio_[direction1]_[direction2]_unit_flow where constraint can be min, max or fix and determines the sense of the constraint (max: <, min: >, fix: =) while direction1 and direction2 are used to interpret the direction of the flows involved. In signifies an input flow to the unit while out signifies an output flow from the unit. For each of these parameters, there is a corresponding [constraint]_[direction1]_[direction2]_units_on_coefficient. For example: max_ratio_in_out_unit_flow creates the following constraint:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"input_flow < max_ratio_in_out_unit_flow * output_flow + max_units_on_coefficient_in_out * units_on","category":"page"},{"location":"how_to/define_an_efficiency/#real-world-example:-Compressed-Air-Energy-Storage","page":"Define an efficiency","title":"real world example: Compressed Air Energy Storage","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"To give a feeling for why these functionalities are useful, consider the following real world example for Compressed Air Energy Storage:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/#known-issues","page":"Define an efficiency","title":"known issues","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"That does not mean that this implementation is perfect; there are some known issues:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"Multiple ways to do the same thing (kind of)\nThe ordering of nodes in unit__node__node relationship matters and this can be confusing\nWhen specifying a unit__node__node relationship, currently toolbox doesn’t constrain a user to choosing nodes that are connected to the unit. It’s possible to create a unit__node__node relationship between a unit and nodes where there are no flows. We actually need to define a relationship between two flows, which is really a relationship between a unit__[to/from]_node relationship and a unit__[to/from]_node relationship.\nThere is a long list of parameters (24 in total) [fix/max/min]_ratio_[in/out]_[in/out]_[unit_flow/units_on_coefficient]\nIncremental_heat_rate supports piecewise linear but the ratio constraints don’t","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_out/","page":"-","title":"-","text":"The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/unit_investment_variable_type/","page":"-","title":"-","text":"Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.","category":"page"},{"location":"concept_reference/unit_investment_variable_type/","page":"-","title":"-","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/storages_invested_big_m_mga/","page":"-","title":"-","text":"The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)","category":"page"},{"location":"concept_reference/fix_node_state/","page":"-","title":"-","text":"The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.","category":"page"},{"location":"concept_reference/db_lp_solver_options/","page":"-","title":"-","text":"LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_lp_solver_options map parameter)","category":"page"},{"location":"concept_reference/fix_connections_invested/","page":"-","title":"-","text":"The fix_connections_invested parameter can be used to fix the values of the connections_invested variable to preset values. If set to a Scalar type value, the connections_invested variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/fix_connections_invested/","page":"-","title":"-","text":"See Investment Optimization for more information about the investment framework in SpineOpt.jl.","category":"page"},{"location":"concept_reference/has_voltage_angle/","page":"-","title":"-","text":"For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_out/","page":"-","title":"-","text":"The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio/","page":"-","title":"-","text":"For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio/","page":"-","title":"-","text":"A unit can be marked as a renewable generation source by setting is_renewable to true.","category":"page"},{"location":"advanced_concepts/user_constraints/#User-Constraints","page":"User Constraints","title":"User Constraints","text":"","category":"section"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"User constraints allow the user to define arbitrary linear constraints involving most of the problem variables. This section describes this function and how to use it.","category":"page"},{"location":"advanced_concepts/user_constraints/#Key-User-Constraint-Concepts","page":"User Constraints","title":"Key User Constraint Concepts","text":"","category":"section"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"The basic principle: The basic steps involved in forming a user constraint are:","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Creating a user constraint object: One creates a new user_constraint object which will be used as a unique handle for the specific constraint and on which constraint-level parameters will be defined.\nSpecify which variables are involved in the constraint: this generally involves creating a relationship involving the user_constraint object. For example, specifying the relationship unit__from_node__user_constraint specifies that the corresponding unit_flow variable is involved in the constraint. The table below contains a complete list of variables and the corresponding relationships to set.\nSpecify the variable coefficients: this will generally involve specifying a parameter named *_coefficient on the relationship defined above to specify the coefficient on that particular variable in the constraint. For example, to define the coefficient on the unit_flow variable, one specifies the unit_flow_coefficient parameter on the approrpriate unit__from_node__user_constraint relationship. The table below contains a complete list of variables and the corresponding coefficient parameters to set.\nSpecify the right-hand-side constant term: The constraint should be formed in conventional form with all constant terms moved to the right-hand side. The right-hand-side constant term is specified by setting the right_hand_side user_constraint parameter.\nSpecify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are ==, >= and <=.\nCoefficients can be defined on some parameters themselves. For example, one may specify a coefficient on a node's demand parameter. This is done by specifying the relationship node__user_constraint and specifying the demand_coefficient parameter on that relationship","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Piecewise unit_flow coefficients: As described in operating_points, specifying this parameter decomposes the unit_flow variable into a number of sub operating segment variables named unit_flow_op in the model and with an additional index, i for the operating segment. The intention of this functionality is to allow unit_flow coefficients to be defined individually per segment to define a piecewise linear function. To accomplish this, the steps are as described above with the exception that one must define operating_points on the appropriate unit__from_node or unit__to_node as an array type with the dimension corresponding to the number of operating points and then set the unit_flow_coefficient for the appropriate unit__from_node__user_constraint relationship, also as an array type with the same number of elements. Note that if operating points is defined as an array type with more than one elements, unit_flow_coefficient may be defined as either an array or non-array type. However, if operating_points is of non-array type, corresponding unit_flow_coefficients must also be of non-array types.\nVariables, relationships and coefficient guide for user constraints The table below provides guidance regarding what relationships and coefficients to set for various problem variables and parameters.","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Problem variable / Parameter Name Relationship Parameter\nunit_flow (direction=from_node) unit__from_node__user_constraint unit_flow_coefficient (non-array type)\nunit_flow (direction=to_node) unit__to_node__user_constraint unit_flow_coefficient (non-array type)\nunit_flow_op (direction=from_node) unit__from_node__user_constraint unit_flow_coefficient (array type)\nunit_flow_op (direction=to_node) unit__to_node__user_constraint unit_flow_coefficient (array type)\nconnection_flow (direction=from_node) connection__from_node__user_constraint connection_flow_coefficient\nconnection_flow (direction=to_node) connection__to_node__user_constraint connection_flow_coefficient\nnode_state node__user_constraint node_state_coefficient\nstorages_invested node__user_constraint storages_invested_coefficient\nstorages_invested_available node__user_constraint storages_invested_available_coefficient\ndemand node__user_constraint demand_coefficient\nunits_on unit__user_constraint units_on_coefficient\nunits_started_up unit__user_constraint units_started_up_coefficient\nunits_invested unit__user_constraint units_invested_coefficient\nunits_invested_available unit__user_constraint units_invested_available_coefficient\nconnections_invested connection__user_constraint connections_invested_coefficient\nconnections_invested_available connection__user_constraint connections_invested_available_coefficient","category":"page"},{"location":"concept_reference/storage_investment_variable_type/","page":"-","title":"-","text":"Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.","category":"page"},{"location":"concept_reference/storage_investment_variable_type/","page":"-","title":"-","text":"See also Investment Optimization and candidate_storages.","category":"page"},{"location":"concept_reference/the_basics/#Basics-of-the-model-structure","page":"Basics of the model structure","title":"Basics of the model structure","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"In SpineOpt.jl, the model structure is generated based on the input data, allowing it to be used for a multitude of different problems. Here, we aim to provide you with a basic understanding of the SpineOpt.jl model and data structure, while the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections provide more in-depth explanations of each concept.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-object-classes","page":"Basics of the model structure","title":"Introduction to object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Essentially, Object Classes represents different types of objects or entities that make up the model. For example, every power plant in the model is represented as an object of the object class unit, every power line as an object of the object class connection, and so forth. In order to add any new entity to a model, a new object has to be added to desired object class in the input data.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Each object class has a very specific purpose in SpineOpt.jl, so understanding their differences is key. The Object Classes can be roughly divided into three distinctive groups, namely Systemic object classes, Structural object classes, and Meta object classes.","category":"page"},{"location":"concept_reference/the_basics/#Systemic-object-classes","page":"Basics of the model structure","title":"Systemic object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"As the name implies, system Object Classes are used to describe the system to be modelled. Essentially, they define what you want to model. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"commodity represents different goods to be generated, consumed, transported, etc.\nconnection handles the transfer of commodities between nodes.\nnode ensures the balance of the commodity flows, and can be used to store commodities as well.\nunit handles the generation and consumption of commodities.","category":"page"},{"location":"concept_reference/the_basics/#Structural-object-classes","page":"Basics of the model structure","title":"Structural object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Structural Object Classes are used to define the temporal and stochastic structure of the modelled problem, as well as custom User Constraints. Unlike the above system Object Classes, the structural Object Classes are more about how you want to model, instead of strictly what you want to model. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"stochastic_scenario represents a different forecast or another type of an alternative time period.\nstochastic_structure acts as a handle for a group of stochastic_scenarios with set properties.\ntemporal_block defines a period of time with the desired temporal resolution.\nuser_constraint is an optional custom constraint generated based on the input data.","category":"page"},{"location":"concept_reference/the_basics/#Meta-object-classes","page":"Basics of the model structure","title":"Meta object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Meta Object Classes are used for defining things on the level of models or above, like model output and even multiple models for problem decompositions. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"model represents an individual model, grouping together all the things relevant for itself.\noutput defines which Variables are output from the model.\nreport groups together multiple output objects.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-relationship-classes","page":"Basics of the model structure","title":"Introduction to relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"While Object Classes define all the objects or entities that make up a model, Relationship Classes define how those entities are related to each other. Thus, Relationship Classes hold no meaning on their own, and always include at least one object class.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Similar to Object Classes, each relationship class has a very specific purpose in SpineOpt.jl, and understanding the purpose of each relationship class is paramount. The Relationship Classes can be roughly divided into Systemic relationship classes, Structural relationship classes, and Meta relationship classes, again similar to Object Classes.","category":"page"},{"location":"concept_reference/the_basics/#Systemic-relationship-classes","page":"Basics of the model structure","title":"Systemic relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Systemic Relationship Classes define how Systemic object classes are related to each other, thus helping define the system to be modelled. Most of these relationships deal with which units and connections interact with which nodes, and how those interactions work. This essentially defines the possible commodity flows to be modelled. Systemic Relationship Classes include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__from_node defines which node the connection can transfer a commodity from.\nconnection__to_node defines which node the connection can transfer a commodity to.\nconnection__node__node holds Parameters for connections between two nodes.\nnode__commodity defines which node holds which commodity.\nnode__node holds parameters for direct node-node interactions, like diffusion of commodities.\nunit__commodity defines which commodity the unit handles.\nunit__from_node defines which node the unit can take an input commodity from.\nunit__to_node defines which node the unit can output a commodity to.\nunit__node__node holds parameters for unit interactions between two nodes.","category":"page"},{"location":"concept_reference/the_basics/#Structural-relationship-classes","page":"Basics of the model structure","title":"Structural relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Structural Relationship Classes primarily relate Structural object classes to Systemic object classes, defining what structures the individual parts of the system use. These are mostly used to determine the temporal and stochastic structures to be used in different parts of the modelled system, or custom User Constraints.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"SpineOpt.jl has a very flexible temporal and stochastic structure, explained in detail in the Temporal Framework and Stochastic Framework sections of the documentation. Unfortunately, this flexibility requires quite a few different structural Relationship Classes, the most important of which are the following basic structural Relationship Classes:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"node__stochastic_structure defines the stochastic_structure used for the node balance.\nnode__temporal_block defines the temporal blocks used for the node balance.\nparent_stochastic_scenario__child_stochastic_scenario defines the stochastic directed acyclic graph (DAG) of the Stochastic Framework.\nstochastic_structure__stochastic_scenario holds parameters for stochastic scenarios in the stochastic_structure.\nunits_on__stochastic_structure defines the stochastic_structure used for the online variable of the unit.\nunits_on__temporal_block defines the temporal blocks used for the online variable of the unit.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Furthermore, there are also a number of advanced structural Relationship Classes, which are only necessary when using some of the optional features of SpineOpt.jl. For Investment Optimization, the following relationships control the stochastic and temporal structures of the investment variables:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the connection.\nconnection__investment_temporal_block defines the temporal blocks used for the investment Variables for the connection.user_constraint.\nnode__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the node.\nnode__investment_temporal_block defines the stochastic_structure used for the investment Variables for the node.\nunit__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the unit.\nunit__investment_temporal_block defines the temporal blocks used for the investment Variables for the unit.(@ref).","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"For User Constraints, which are essentially generic data-driven custom constraints, the following relationships are used to control which variables are included and with what coefficients: ","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__from_node__user_constraint holds Parameters for the connection_flow variable from the node in question in the custom user_constraint.\nconnection__to_node__user_constraint holds Parameters for the connection_flow variable to the node in question in the custom user_constraint.\nnode__user_constraint holds Parameters for the node_state variable in the custom user_constraint.\nunit__from_node__user_constraint holds Parameters for the unit_flow variable from the node in question in the custom user_constraint.\nunit__to_node__user_constraint holds Parameters for the unit_flow variable to the node in question in the custom user_constraint.","category":"page"},{"location":"concept_reference/the_basics/#Meta-relationship-classes","page":"Basics of the model structure","title":"Meta relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Meta Relationship Classes are used for defining model-level settings, like which temporal blocks or stochastic structures are active, and what the model output is. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"model__default_investment_stochastic_structure defines a default stochastic_structure to be used for investment Variables when no other definitions exist.\nmodel__default_investment_temporal_block defines a default temporal_block to be used for investment Variables when no other definitions exist.\nmodel__default_stochastic_structure defines a default stochastic_structure to be used for nodes and units when no other definitions exist.\nmodel__default_temporal_block defines a default temporal_block to be used for nodes and units when no other definitions exist.\nmodel__report connects each report to the desired model.\nmodel__stochastic_structure defines which stochastic structures are active in which models.\nmodel__temporal_block defines which temporal blocks are active in which models.\nreport__output defines which outputs are part of which report.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-parameters","page":"Basics of the model structure","title":"Introduction to parameters","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"While the primary function of Object Classes and Relationship Classes is to define the system to be modelled and it's structure, Parameters exist to constrain them. Every parameter is attributed to at least one object class or relationship class, but some appear in many classes whenever they serve a similar purpose.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Parameters accept different types of values depending on their purpose, e.g. whether they act as a flag for some specific functionality or appear as a coefficient in Constraints, so understanding each parameter is key. Most coefficient-type Parameters accept constant, time series, and even stochastic time series form input, but there are some exceptions. Most flag-type Parameters, on the other hand, have a restricted list of acceptable values defined by their Parameter Value Lists.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"The existence of some Constraints is controlled based on if the relevant Parameters are defined. As a rule-of-thumb, a constraint only gets generated if at least one of the Parameters appearing in it is defined, but one should refer to the appropriate Constraints and Parameters sections when in doubt.","category":"page"},{"location":"concept_reference/the_basics/#Introduction-to-groups-of-objects","page":"Basics of the model structure","title":"Introduction to groups of objects","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Groups of objects are used within SpineOpt for different purposes. To create a group of objects, simply right-click the corresponding Object Class in the Spine Toolbox database editor and select Add object group. Groups are essentially special objects, that act as a single handle for all of its members.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"On the one hand, groups can be used in order to impose constraints on the aggregation of a variable, e.g. on the sum of multiple unit_flow variables. Constraints based on parameters associated with the unit__node__node, unit__to_node, unit__from_node, connection__node__node, connection__to_node, connection__from_node can generally be used for this kind of flow aggregation by defining the parameters on groups of objects, typically node groups. (with the exception of variable fixing parameters, e.g. fix_unit_flow, fix_connection_flow etc.). See for instance constraint_unit_flow_capacity.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"On the other hand, a node group can be used to for PTDF based powerflows. Here a node group is used to enforce a nodal balance on system level, while suppressing the node balances at individual nodes. See also balance_type and the node balance constraint.","category":"page"},{"location":"concept_reference/model__default_investment_temporal_block/","page":"-","title":"-","text":"model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.","category":"page"},{"location":"concept_reference/model__default_investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/unit_online_variable_type_list/","page":"-","title":"-","text":"unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear. ","category":"page"},{"location":"concept_reference/units_on__temporal_block/","page":"-","title":"-","text":"units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized. ","category":"page"},{"location":"concept_reference/fix_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/weight/","page":"-","title":"-","text":"The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so. ","category":"page"},{"location":"concept_reference/unit_idle_heat_rate/","page":"-","title":"-","text":"Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"library/#Library","page":"Library","title":"Library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"Documentation for SpineOpt.jl.","category":"page"},{"location":"library/#Contents","page":"Library","title":"Contents","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"Pages = [\"library.md\"]\nDepth = 3","category":"page"},{"location":"library/#Index","page":"Library","title":"Index","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"","category":"page"},{"location":"library/#Public-interface","page":"Library","title":"Public interface","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"run_spineopt\nwrite_report_from_intermediate_results\ngenerate_forced_availability_factor","category":"page"},{"location":"library/#SpineOpt.run_spineopt","page":"Library","title":"SpineOpt.run_spineopt","text":"run_spineopt(url_in, url_out; )\n\nRun SpineOpt using the contents of url_in and write report(s) to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.\n\nArguments\n\nupgrade::Bool=false: whether or not to automatically upgrade the data structure in url_in to latest.\nmip_solver=nothing: a MIP solver to use if no MIP solver specified in the DB.\nlp_solver=nothing: a LP solver to use if no LP solver specified in the DB.\nadd_constraints=m -> nothing: a function that receives the Model object as argument and adds custom user constraints.\nlog_level::Int=3: an integer to control the log level.\noptimize::Bool=true: whether or not to optimise the model (useful for running tests).\nupdate_names::Bool=false: whether or not to update variable and constraint names after the model rolls (expensive).\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nwrite_as_roll::Int=0: if greater than 0 and the run has a rolling horizon, then write results every that many windows.\nuse_direct_model::Bool=false: whether or not to use JuMP.direct_model to build the Model object.\nfilters::Dict{String,String}=Dict(\"tool\" => \"object_activity_control\"): a dictionary to specify filters. Possible keys are \"tool\" and \"scenario\". Values should be a tool or scenario name in the input DB.\nlog_file_path::String=nothing: if not nothing, log all console output to a file at the given path. The file is overwritten at each call.\nresume_file_path::String=nothing: only relevant in rolling horizon optimisations with write_as_roll greater or equal than one. If the file at given path contains resume data from a previous run, start the run from that point. Also, save resume data to that same file as the model rolls and results are written to the output database.\n\nExample\n\nusing SpineOpt\nm = run_spineopt(\n raw\"sqlite:///C:\\path\\to\\your\\inputputdb.sqlite\", \n raw\"sqlite:///C:\\path\\to\\your\\outputdb.sqlite\";\n filters=Dict(\"tool\" => \"object_activity_control\", \"scenario\" => \"scenario_to_run\"),\n alternative=\"your_results_alternative\"\n)\n\n\n\n\n\n","category":"function"},{"location":"library/#SpineOpt.write_report_from_intermediate_results","page":"Library","title":"SpineOpt.write_report_from_intermediate_results","text":"write_report_from_intermediate_results(intermediate_results_folder, default_url; )\n\nCollect results generated on a previous, unsuccessful SpineOpt run from intermediate_results_folder, and write the corresponding report(s) to url_out. A new Spine database is created at url_out if one doesn't exist.\n\nArguments\n\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nlog_level::Int=3: an integer to control the log level.\n\n\n\n\n\n","category":"function"},{"location":"library/#SpineOpt.generate_forced_availability_factor","page":"Library","title":"SpineOpt.generate_forced_availability_factor","text":"generate_forced_availability_factor(url_in, url_out; )\n\nGenerate forced availability factors (due to outages) from the contents of url_in and write them to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.\n\nTo generate forced availability factors for an entity, specify mean_time_to_failure and optionally mean_time_to_repair for that entity as a duration in the input DB.\n\nParameter forced_availability_factor will be written for those entites in the output DB, holding a time series with the availability factor due to forced outages.\n\nArguments\n\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nfilters::Dict{String,String}=Dict(\"tool\" => \"object_activity_control\"): a dictionary to specify filters. Possible keys are \"tool\" and \"scenario\". Values should be a tool or scenario name in the input DB.\n\nExample\n\nusing SpineOpt\nm = generate_forced_availability_factor(\n raw\"sqlite:///C:\\path\\to\\your\\inputputdb.sqlite\", \n raw\"sqlite:///C:\\path\\to\\your\\outputdb.sqlite\"\n)\n\n\n\n\n\n","category":"function"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Internals","page":"Library","title":"Internals","text":"","category":"section"},{"location":"library/#Variable-library","page":"Library","title":"Variable library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"unit_flow_indices","category":"page"},{"location":"library/#SpineOpt.unit_flow_indices","page":"Library","title":"SpineOpt.unit_flow_indices","text":"unit_flow_indices(\n unit=anything,\n node=anything,\n direction=anything,\n s=anything\n t=anything\n)\n\nA list of NamedTuples corresponding to indices of the unit_flow variable where the keyword arguments act as filters for each dimension.\n\n\n\n\n\n","category":"function"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Constraint-library","page":"Library","title":"Constraint library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Objective","page":"Library","title":"Objective","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"concept_reference/fix_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/fix_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"mathematical_formulation/constraints/#Constraints","page":"Constraints","title":"Constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Balance-constraint","page":"Constraints","title":"Balance constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_nodal_balance","page":"Constraints","title":"Nodal balance","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodal_balance!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_injection","page":"Constraints","title":"Node injection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnode_injection!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_state_capacity","page":"Constraints","title":"Node state capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodestatecapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_cyclic_node_state","page":"Constraints","title":"Cyclic condition on node state variable","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcyclicnodestate!","category":"page"},{"location":"mathematical_formulation/constraints/#Unit-operation","page":"Constraints","title":"Unit operation","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In the following, the operational constraints on the variables associated with units will be elaborated on. The static constraints, in contrast to the dynamic constraints, are addressing constraints without sequential time-coupling. It should however be noted that static constraints can still perform temporal aggregation.","category":"page"},{"location":"mathematical_formulation/constraints/#static-constraints-unit","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The fundamental static constraints for units within SpineOpt relate to the relationships between commodity flows from and to units and to limits on the unit flow capacity.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_unit_flow","page":"Constraints","title":"Conversion constraint / limiting flow shares inprocess / relationship in process","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"A unit can have different commodity flows associated with it. The most simple relationship between these flows is a linear relationship between input and/or output nodes/node groups. SpineOpt holds constraints for each combination of flows and also for the type of relationship, i.e. whether it is a maximum, minimum or fixed ratio between commodity flows. Note that node groups can be used in order to aggregate flows, i.e. to give a ratio between a combination of units flows.","category":"page"},{"location":"mathematical_formulation/constraints/#ratio_unit_flow","page":"Constraints","title":"Ratios between flows of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiounitflow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_flow_capacity","page":"Constraints","title":"Bounds on the unit capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowcapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_minimum_operating_point","page":"Constraints","title":"Constraint on minimum operating point","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminimumoperatingpoint!","category":"page"},{"location":"mathematical_formulation/constraints/#Dynamic-constraints","page":"Constraints","title":"Dynamic constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Commitment-constraints","page":"Constraints","title":"Commitment constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For modeling certain technologies/units, it is important to not only have unit_flow variables of different commodities, but also model the online (\"commitment\") status of the unit/technology at every time step. Therefore, an additional variable units_on is introduced. This variable represents the number of online units of that technology (for a normal unit commitment model, this variable might be a binary, for investment planning purposes, this might also be an integer or even a continuous variable). To define the type of a commitment variable, see online_variable_type. Commitment variables will be introduced by the following constraints (with corresponding parameters):","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"constraint on units_on\nconstraint on units_available\nconstraint on the unit state transition\nconstraint on minimum down time\nconstraint on minimum up time\nconstraint on ramp rates\nconstraint on reserve provision","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_available","page":"Constraints","title":"Bound on available units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunits_available!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_on","page":"Constraints","title":"Bound on online units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunits_on!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_state_transition","page":"Constraints","title":"Unit state transition","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitstatetransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_down_time","page":"Constraints","title":"Minimum down time","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmindowntime!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_up_time","page":"Constraints","title":"Minimum up time","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminuptime!","category":"page"},{"location":"mathematical_formulation/constraints/#Ramping-constraints","page":"Constraints","title":"Ramping constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"To include ramping and reserve constraints, it is a pre requisite that minimum operating points and capacity constraints are enforced as described.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For dispatchable units, additional ramping constraints can be introduced. For setting up ramping characteristics of units see Ramping.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ramp_up","page":"Constraints","title":"Ramp up limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintramp_up!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ramp_down","page":"Constraints","title":"Ramp down limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintramp_down!","category":"page"},{"location":"mathematical_formulation/constraints/#Reserve-constraints","page":"Constraints","title":"Reserve constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_res_minimum_node_state","page":"Constraints","title":"Constraint on minimum node state for reserve provision","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-11-20: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Operating-segments","page":"Constraints","title":"Operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_operating_point_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintoperatingpointbounds!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_operating_point_rank","page":"Constraints","title":"Rank operating segments as per the index of operating points","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintoperatingpointrank!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_bounds!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_rank","page":"Constraints","title":"Bounding operating segments to use up its own capacity for activating the next segment","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_rank!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_sum","page":"Constraints","title":"Bounding unit flows by summing over operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_sum!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_pw_heat_rate","page":"Constraints","title":"Unit piecewise incremental heat rate","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitpwheat_rate!","category":"page"},{"location":"mathematical_formulation/constraints/#Bounds-on-commodity-flows","page":"Constraints","title":"Bounds on commodity flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_total_cumulated_unit_flow","page":"Constraints","title":"Bound on cumulated unit flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstrainttotalcumulatedunit_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#Network-constraints","page":"Constraints","title":"Network constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#static-constraints-connection","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_capacity","page":"Constraints","title":"Capacity constraint on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowcapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_out_in_connection_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiooutinconnectionflow!","category":"page"},{"location":"mathematical_formulation/constraints/#Specific-network-representation","page":"Constraints","title":"Specific network representation","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In the following, the different specific network representations are introduced. While the Static constraints find application in any of the different networks, the following equations are specific to the discussed use cases. Currently, SpineOpt incorporated equations for pressure driven gas networks, nodal lossless DC power flows and PTDF based lossless DC power flow.","category":"page"},{"location":"mathematical_formulation/constraints/#pressure-driven-gas-transfer-math","page":"Constraints","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For gas pipelines it can be relevant a pressure driven gas transfer can be modelled, i.e. to account for linepack flexibility. Generally speaking, the main challenges related to pressure driven gas transfers are the non-convexities associated with the Weymouth equation. In SpineOpt, a convexified MILP representation has been implemented, which as been presented in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. The approximation approach is based on the Taylor series expansion around fixed pressure points.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In addition to the already known variables, such as connection_flow and node_state, the start and end points of a gas pipeline connection are associated with the variable node_pressure. The variable is triggered by the has_pressure parameter. For more details on how to set up a gas pipeline, see also the advanced concept section on pressure driven gas transfer.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_max_node_pressure","page":"Constraints","title":"Maximum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmaxnodepressure!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_node_pressure","page":"Constraints","title":"Minimum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminnodepressure!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_compression_factor","page":"Constraints","title":"Constraint on the pressure ratio between two nodes","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcompression_ratio!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_fixed_node_pressure_point","page":"Constraints","title":"Outer approximation through fixed pressure points","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintfixnodepressure_point!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_unitary_gas_flow","page":"Constraints","title":"Enforcing unidirectional flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionunitarygas_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_gas_capacity","page":"Constraints","title":"Gas connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowgas_capacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storage_line_pack","page":"Constraints","title":"Linepack storage flexibility","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragelinepack!","category":"page"},{"location":"mathematical_formulation/constraints/#nodal-lossless-DC","page":"Constraints","title":"Node-based lossless DC power flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For the implementation of the nodebased loss DC powerflow model, a new variable node_voltage_angle is introduced. See also has_voltage_angle. For further explanation on setting up a database for nodal lossless DC power flow, see the advanced concept chapter on Lossless nodal DC power flows.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_max_node_voltage_angle","page":"Constraints","title":"Maximum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmaxnodevoltage_angle!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_node_voltage_angle","page":"Constraints","title":"Minimum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminnodevoltage_angle!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_voltage_angle","page":"Constraints","title":"Voltage angle to connection flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodevoltageangle!","category":"page"},{"location":"mathematical_formulation/constraints/#PTDF-lossless-DC","page":"Constraints","title":"PTDF based DC lossless powerflow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connection_intact_flow_ptdf","page":"Constraints","title":"Connection intact flow PTDF","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionintactflow_ptdf!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_lodf","page":"Constraints","title":"N-1 post contingency connection flow limits","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowlodf!","category":"page"},{"location":"mathematical_formulation/constraints/#Investments","page":"Constraints","title":"Investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Investments-in-units","page":"Constraints","title":"Investments in units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_unit_lifetime","page":"Constraints","title":"Economic lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-03: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-unit","page":"Constraints","title":"Technical lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_invested_available","page":"Constraints","title":"Available Investment Units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitsinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_invested_transition","page":"Constraints","title":"Investment transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitsinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#Investments-in-connections","page":"Constraints","title":"Investments in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connections_invested_available","page":"Constraints","title":"Available invested-in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionsinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connections_invested_transition","page":"Constraints","title":"Transfer of previous investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionsinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_intact_flow","page":"Constraints","title":"Intact network ptdf-based flows on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowintact_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_intact_flow_capacity","page":"Constraints","title":"Intact connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionintactflow_capacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_out_in_connection_intact_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming intact flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiooutinconnectionintact_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_candidate_connection_flow_lb","page":"Constraints","title":"Lower bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcandidateconnectionflow_lb!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_candidate_connection_flow_ub","page":"Constraints","title":"Upper bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcandidateconnectionflow_ub!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_lifetime","page":"Constraints","title":"Economic lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-connection","page":"Constraints","title":"Technical lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Investments-in-storages","page":"Constraints","title":"Investments in storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Note: can we actually invest in nodes that are not storages? (e.g. new location)","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storages_invested_available","page":"Constraints","title":"Available invested storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragesinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storages_invested_transition","page":"Constraints","title":"Storage capacity transfer ","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragesinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storage_lifetime","page":"Constraints","title":"Economic lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-storage","page":"Constraints","title":"Technical lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Capacity-transfer","page":"Constraints","title":"Capacity transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Early-retirement-of-capacity","page":"Constraints","title":"Early retirement of capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#User-constraints","page":"Constraints","title":"User constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_user_constraint","page":"Constraints","title":"User constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintuser_constraint!","category":"page"},{"location":"mathematical_formulation/constraints/#benders_decomposition","page":"Constraints","title":"Benders decomposition","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This section describes the high-level formulation of the benders-decomposed problem.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Taking the simple example of minimising capacity and operating cost for a fleet of units with a linear cost coefficient p^operational_cost:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sum_ust left( p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ sum_nd p^operational_cost_(undst) cdot v^unit_flow_(u n d s t) right) \nst \n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + v^units_invested_available_(u s t)\nright) quad forall u in unit n in node s t\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"So this is a single problem that can't be decoupled over t because the investment variables units_invested_available couple the timesteps together. If units_invested_available were a constant in the problem, then all t's could be solved individually. This is the basic idea in Benders decomposition. We decompose the problem into a master problem and sub problems with the master problem optimising the coupling investment variables which are treated as constants in the sub problems.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The master problem is built by replacing the operational costs (which will be minimised in the sub problem) by a new decision variable, v^sp_objective:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust) + v^sp_objective \nst \n v^sp_objective geq 0\nendaligned\n","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The solution to this problem yields values for the investment variables which are fixed as p^units_invested_available in the sub problem and will be zero in the first iteration.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The sub problem for benders iteration b then becomes :","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sp_obj_b = sum_undst p^operational_cost_(undst) cdot v^unit_flow_(u n d s t)\nst\n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + p^units_invested_available_(b u s t)\nright) \n qquad forall u in unit n in node st qquad mu_(bust)\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This sub problem can be solved individually for each t. This is pretty trivial in this small example but if we consider a single t to be a single rolling horizon instead, decoupling the investment variables means that each rolling horizon can be solved individually rather than having to solve the entire model horizon as a single problem.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"mu_(bust) is the marginal value of the capacity constraint for benders iteration b and can be interpreted as the decrease in the objective function for an additional MW of flow from unit u (in scenario s at time t). Thus, an upper bound on the sub problem objective function is obtained as follows:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"sp_obj_b + sum_undst mu_(bust) cdot p^unit_capacity_(undst) \ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right)","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The above is added to the master problem for the next iteration as a new constraint, called a Benders cut, thus becoming:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ v^sp_objective \n\nst \n\n v^sp_objective geq sp_obj_b \n quad + sum_undst mu_(bust) cdot p^unit_capacity_(undst)\ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right) quad forall b \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Note the benders cuts are added as inequalities because they represent an upper bound on the value we are going to get for the sub problem objective function by adjusting the master problem variables in that benders iteration. If we consider the example of renewable generation - because it's marginal cost is zero, on the first benders iteration, it could look like there would be a lot of value in increasing the capacity because of the marginal values from the sub problems. However, when the capacity variables are increased accordingly and curtailment occurs in the sub-problems, the marginal values will be zero when curtailment occurs and so, other resources may become optimal in subsequent iterations.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This is a simple example but it illustrates the general strategy. The algorithm pseudo code looks something like this:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":" initialise master problem\n initialise sub problem\n solve first master problem\n create master problem variable time series\n solve rolling spine opt model\n save zipped marginal values\n while master problem not converged\n update master problem\n solve master problem\n update master problem variable timeseries for benders iteration b\n rewind sub problem\n update sub problem\n solve rolling spine opt model\n save zipped marginal values\n test for convergence\n end","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_mp_any_invested_cuts","page":"Constraints","title":"Benders cuts","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The benders cuts for the problem including all investments in candidate connections, storages and units is given below.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^sp_objective \n geq \n p^sp_obj_(b) + \n sum_ust p^units_invested_available_mv_(bust)\ncdot left( v^units_invested_available_(ust) - p^units_invested_available_(ust) right) \n + sum_cst p^connections_invested_available_mv_(bcst)\ncdot left( v^connections_invested_available_(cst) - p^connections_invested_available_(cst) right) \n + sum_nst p^storages_invested_available_mv_(bnst)\ncdot left( v^storages_invested_available_(nst) - p^storages_invested_available_(nst) right) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"p^sp_obj_(b) is the sub problem objective function value in benders iteration b,\np^units_invested_available_mv is the reduced cost of the units_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a unit of this type, \np^connections_invested_available_mv is the reduced cost of the connections_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a connection of this type, \np^storages_invested_available_mv is the reduced cost of the storages_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a storage node of this type, \np^units_invested_available is the value of the fixed sub problem variable units_invested_available in benders iteration b, \np^connections_invested_available is the value of the fixed sub problem variable connections_invested_available in benders iteration b and \np^storages_invested_available is the value of the fixed sub problem variable storages_invested_available in benders iteration b","category":"page"},{"location":"concept_reference/Object Classes/#Object-Classes","page":"Object Classes","title":"Object Classes","text":"","category":"section"},{"location":"concept_reference/Object Classes/#commodity","page":"Object Classes","title":"commodity","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A good or product that can be consumed, produced, traded. E.g., electricity, oil, gas, water...","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: commodity_lodf_tolerance, commodity_physics_duration, commodity_physics, commodity_ptdf_threshold, is_active, mp_min_res_gen_to_demand_ratio_slack_penalty and mp_min_res_gen_to_demand_ratio","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: node__commodity and unit__commodity","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)","category":"page"},{"location":"concept_reference/Object Classes/#connection","page":"Object Classes","title":"connection","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A transfer of commodities between nodes. E.g. electricity line, gas pipeline...","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: benders_starting_connections_invested, candidate_connections, connection_availability_factor, connection_contingency, connection_investment_cost, connection_investment_lifetime, connection_investment_variable_type, connection_monitored, connection_reactance_base, connection_reactance, connection_resistance, connection_type, connections_invested_big_m_mga, connections_invested_mga_weight, connections_invested_mga, fix_connections_invested_available, fix_connections_invested, forced_availability_factor, graph_view_position, has_binary_gas_flow, initial_connections_invested_available, initial_connections_invested and is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__investment_group, connection__investment_stochastic_structure, connection__investment_temporal_block, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node and connection__user_constraint","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.","category":"page"},{"location":"concept_reference/Object Classes/#investment_group","page":"Object Classes","title":"investment_group","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A group of investments that need to be done together.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: equal_investments, maximum_capacity_invested_available, maximum_entities_invested_available, minimum_capacity_invested_available and minimum_entities_invested_available","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__investment_group, connection__to_node__investment_group, node__investment_group, unit__from_node__investment_group, unit__investment_group and unit__to_node__investment_group","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.","category":"page"},{"location":"concept_reference/Object Classes/#model","page":"Object Classes","title":"model","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"An instance of SpineOpt, that specifies general parameters such as the temporal horizon.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: big_m, db_lp_solver_options, db_lp_solver, db_mip_solver_options, db_mip_solver, duration_unit, is_active, max_gap, max_iterations, max_mga_iterations, max_mga_slack, min_iterations, model_end, model_start, model_type, roll_forward, window_duration, window_weight, write_lodf_file, write_mps_file and write_ptdf_file","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: model__default_investment_stochastic_structure, model__default_investment_temporal_block, model__default_stochastic_structure, model__default_temporal_block, model__report, model__stochastic_structure and model__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).","category":"page"},{"location":"concept_reference/Object Classes/#node","page":"Object Classes","title":"node","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A universal aggregator of commodify flows over units and connections, with storage capabilities.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: balance_type, benders_starting_storages_invested, candidate_storages, demand, downward_reserve, fix_node_pressure, fix_node_state, fix_node_voltage_angle, fix_storages_invested_available, fix_storages_invested, frac_state_loss, fractional_demand, graph_view_position, has_pressure, has_state, has_voltage_angle, initial_node_pressure, initial_node_state, initial_node_voltage_angle, initial_storages_invested_available, initial_storages_invested, is_active, is_non_spinning, is_reserve_node, max_node_pressure, max_voltage_angle, min_node_pressure, min_voltage_angle, minimum_reserve_activation_time, nodal_balance_sense, node_opf_type, node_slack_penalty, node_state_cap, node_state_min, state_coeff, storage_investment_cost, storage_investment_lifetime, storage_investment_variable_type, storages_invested_big_m_mga, storages_invested_mga_weight, storages_invested_mga, tax_in_unit_flow, tax_net_unit_flow, tax_out_unit_flow and upward_reserve","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node, node__commodity, node__investment_group, node__investment_stochastic_structure, node__investment_temporal_block, node__node, node__stochastic_structure, node__temporal_block, node__user_constraint, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint and unit__to_node","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.","category":"page"},{"location":"concept_reference/Object Classes/#output","page":"Object Classes","title":"output","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A variable name from SpineOpt that can be included in a report.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active and output_resolution","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: report__output","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/Object Classes/#report","page":"Object Classes","title":"report","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A results report from a particular SpineOpt run, including the value of specific variables.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active and output_db_url","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: model__report and report__output","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/Object Classes/#settings","page":"Object Classes","title":"settings","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Internal SpineOpt settings. We kindly advise not to mess with this one.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: version","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"TODO","category":"page"},{"location":"concept_reference/Object Classes/#stochastic_scenario","page":"Object Classes","title":"stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A scenario for stochastic optimisation in SpineOpt.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: parent_stochastic_scenario__child_stochastic_scenario and stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.","category":"page"},{"location":"concept_reference/Object Classes/#stochastic_structure","page":"Object Classes","title":"stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A group of stochastic scenarios that represent a structure.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__investment_stochastic_structure, model__default_investment_stochastic_structure, model__default_stochastic_structure, model__stochastic_structure, node__investment_stochastic_structure, node__stochastic_structure, stochastic_structure__stochastic_scenario, unit__investment_stochastic_structure and units_on__stochastic_structure","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.","category":"page"},{"location":"concept_reference/Object Classes/#temporal_block","page":"Object Classes","title":"temporal_block","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A length of time with a particular resolution.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: block_end, block_start, is_active, representative_periods_mapping, resolution and weight","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__investment_temporal_block, model__default_investment_temporal_block, model__default_temporal_block, model__temporal_block, node__investment_temporal_block, node__temporal_block, unit__investment_temporal_block and units_on__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.","category":"page"},{"location":"concept_reference/Object Classes/#unit","page":"Object Classes","title":"unit","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A conversion of one/many comodities between nodes.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: benders_starting_units_invested, candidate_units, curtailment_cost, fix_units_invested_available, fix_units_invested, fix_units_on, fom_cost, forced_availability_factor, graph_view_position, initial_units_invested_available, initial_units_invested, initial_units_on, is_active, is_renewable, min_down_time, min_up_time, number_of_units, online_variable_type, shut_down_cost, start_up_cost, unit_availability_factor, unit_investment_cost, unit_investment_lifetime, unit_investment_variable_type, units_invested_big_m_mga, units_invested_mga_weight, units_invested_mga, units_on_cost, units_on_non_anticipativity_margin and units_on_non_anticipativity_time","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: unit__commodity, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__investment_group, unit__investment_stochastic_structure, unit__investment_temporal_block, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint, unit__to_node, unit__user_constraint, units_on__stochastic_structure and units_on__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.","category":"page"},{"location":"concept_reference/Object Classes/#user_constraint","page":"Object Classes","title":"user_constraint","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A generic data-driven custom constraint.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: constraint_sense, is_active, right_hand_side and user_constraint_slack_penalty","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__user_constraint, connection__to_node__user_constraint, connection__user_constraint, node__user_constraint, unit__from_node__user_constraint, unit__to_node__user_constraint and unit__user_constraint","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"concept_reference/max_cum_in_unit_flow_bound/","page":"-","title":"-","text":"To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.","category":"page"},{"location":"concept_reference/max_cum_in_unit_flow_bound/","page":"-","title":"-","text":"Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)","category":"page"},{"location":"tutorial/unit_commitment/#Unit-commitment-constraints-tutorial","page":"Unit Commitment","title":"Unit commitment constraints tutorial","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial provides a step-by-step guide to include unit commitment constraints in a simple energy system with Spine Toolbox for SpineOpt.","category":"page"},{"location":"tutorial/unit_commitment/#Introduction","page":"Unit Commitment","title":"Introduction","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Welcome to our tutorial, where we will walk you through the process of adding unit commitment constraints in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.","category":"page"},{"location":"tutorial/unit_commitment/#Model-assumptions","page":"Unit Commitment","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial is built on top of the Simple System. The main changes to that system are:","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The demand at electricity_node is a 24-hour time series instead of a unique value\nThe power_plant_b has new parameters to account for the unit commitment constraints, such as minimum operating point, minimum uptime, and minimum downtime\nThe optimization is done a mixed-integer programming (MIP) to account for the binary nature of the unit commitment decision variables","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial includes a step-by-step guide to include the parameters to help analyze the results in SpineOpt and the unit commitment concepts.","category":"page"},{"location":"tutorial/unit_commitment/#Step-1-Update-the-demand","page":"Unit Commitment","title":"Step 1 - Update the demand","text":"","category":"section"},{"location":"tutorial/unit_commitment/#Opening-the-Simple-System-project","page":"Unit Commitment","title":"Opening the Simple System project","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.\nLocate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In this tutorial, you will learn how to add unit commitment constraints to the Simple System using the Spine DB editor, but first let's start by updating the electricity demand from a single value to a 24-hour time series.","category":"page"},{"location":"tutorial/unit_commitment/#Editing-demand-value","page":"Unit Commitment","title":"Editing demand value","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [node] class, and select the electricity_node from the expanded tree.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table, identify the demand parameter which should have a 150 value from the Simple System first run.\nRight click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.\nChange the Parameter type to Time series fixed resolution, Resolution to 1h, and the demand values to the time series as in the image below. You can copy and paste the values from the file: ucelectricitynode_demand.csv\nFinish by pressing OK in the Edit value menu. In the Object parameter table you will see that the value of the demand has changed to Time series.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Editing-the-temporal-block","page":"Unit Commitment","title":"Editing the temporal block","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"You might or might not notice that the Simple System has, by default, a temporal block resolution of 1D (i.e., one day); wait, what! Yes, by default, it has 1D in its template. So, we want to change that to 1h since our unit commitment case study is for a day-ahead dispatch of 24 hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate again the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [temporal_block] class, and select the flat from the expanded tree.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table, identify the resolution parameter which should have a 1D value from the Simple System first run.\nRight click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.\nChange the Duration from 1D to 1h as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Establishing-new-output-relationships","page":"Unit Commitment","title":"Establishing new output relationships","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Since we will have the new unit commitment variables, we want to see the results of these variables and their total cost in the objective function. So, we will create new relationships to report these results:","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and units_on under output. Repete the same procedure for the following outputs as seen in the image below; then press OK.\nThis will write the unit commitment variable values and costs in the objective function to the output database as a part of report1.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow","page":"Unit Commitment","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results","page":"Unit Commitment","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. As expected, the power_plant_a (i.e., the cheapest unit) always covers the demand first until its maximum capacity, and then the power_plant_b (i.e., the more expensive unit) covers the demand that is left. This is the most economical dispatch since the problem has no extra constraints (so far!).","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To explore the cost results, the pivot table view shows a more user-friendly option to analyze the results. Remember that you can find a description of how to create the pivot table view in the Simple System tutorial here. The cost components in the objective function are shown in the image below. As expected, all the costs are associated with the variable_om_costs since we haven't included the unit-commitment constraints yet.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-2-Include-the-minimum-operating-point","page":"Unit Commitment","title":"Step 2 - Include the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b has a minimum operating point of 10%, meaning that if the power plant is on, it must produce at least 20MW.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minium-operating-point","page":"Unit Commitment","title":"Adding the minium operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nIn Relationship tree, expand the unit__to_node class and select power_plant_b | electricity_node.\nIn the Relationship parameter table (typically at the bottom-center), select the minimum_operating_point parameter and the Base alternative, and enter the value 0.1 as seen in the image below. This will set the minimum operating point of power_plant_b when producing electricity.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-unit-commitment-costs-and-initial-states","page":"Unit Commitment","title":"Adding the unit commitment costs and initial states","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:\nonline_variable_type parameter and the Base alternative, and select the value unit_online_variable_type_binary. This will define that the unit commitment variables will be binary. SpineOpt identifies this situation from the input data and internally changes the model from LP to MIP.\nshut_down_cost parameter and the Base alternative, and enter the value 7. This will establish that there's a cost of '7' EUR per shutdown.\nstart_up_cost parameter and the Base alternative, and enter the value 5. This will establish that there's a cost of '5' EUR per startup.\nunits_on_cost parameter and the Base alternative, and enter the value 3. This will establish that there's a cost of '3' EUR per units on (e.g., idling cost).\ninitial_units_on parameter and the Base alternative, and enter the value 0. This will establish that there are no units 'on' before the first time step.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-operating-point","page":"Unit Commitment","title":"Executing the workflow including the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.\nDo you notice something different in your solver log? Depending on the solver, the output might change, but you should be able to see that the solver is using MIP to solve the problem. For instance, if you are using the solver HiGHS (i.e., the default solver in SpineOpt), then you will see something like \"Solving MIP model with:\" and the Branch and Bound (B&B) tree solution. Since this is a tiny problem, sometimes the solver can find the optimal solution from the presolve step, avoiding going into the B&B step.","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-operating-point","page":"Unit Commitment","title":"Examining the results including the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Any difference? What happended to the flows in power_plant_a and power_plant_b?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look to the units_on and units_started_up in the image below to get wider perspective.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"So, since power_plant_b needs to be at least producing 20MW when it is 'on', then power_plant_a needs to reduce its output even though it has the lower variable cost, making the total system cost (i.e., objective function) more expensive than in the previous run. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-3-Include-the-minimum-uptime","page":"Unit Commitment","title":"Step 3 - Include the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b also has a minimum uptime of 8 hours, meaning that if the power plant starts up, it must be on at least eight hours.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minimum-uptime","page":"Unit Commitment","title":"Adding the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the min_up_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum uptime is eight hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-uptime","page":"Unit Commitment","title":"Executing the workflow including the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"You know the drill, go ahead :wink:","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-uptime","page":"Unit Commitment","title":"Examining the results including the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Interesting. Don't you think?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look again to the units_on and units_started_up in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"So, since power_plant_b needs to be at least producing 20MW when it is 'on' and also needs to be at least 8h 'on' each time it starts, then power_plant_b starts even before the demand is greater than the capacity of power_plant_a. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-4-Include-the-minimum-downtime","page":"Unit Commitment","title":"Step 4 - Include the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b also has a minimum downtime of 8 hours, meaning that if the power plant shuts down, it must be off at least eight hours.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minimum-downtime","page":"Unit Commitment","title":"Adding the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the min_down_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum downtime is eight hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-downtime","page":"Unit Commitment","title":"Executing the workflow including the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"One last time, don't give up!","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-downtime","page":"Unit Commitment","title":"Examining the results including the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Wow! This result is even more interesting :stuckouttonguewinkingeye:. Do you know what happened?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look again to the units_on and units_started_up in the image below. Instead of two start-ups, the power_plant_b only starts once. Why?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Since power_plant_b needs to be at least producing 20MW when it is 'on' plus also needs to be at least 8h 'on' each time it starts, and it needs to be at least 8h 'off' if it shutdowns, then power_plant_b never shuts down and stays 'on' after it starts because it is the only way to fulfil the unit commitment constraints. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs (which is zero this time), and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"If you have completed this tutorial, congratulations! You have mastered the basic concepts of unit commitment using SpineToolbox and SpineOpt. Keep up the good work!","category":"page"},{"location":"concept_reference/fixed_pressure_constant_0/","page":"-","title":"-","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/min_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/min_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"advanced_concepts/mga/#mga-advanced","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"Through modelling to generate alternatives (short MGA), near-optimal solutions can be explored under certain conditions. Currently, SpineOpt supports two methods for MGA are available.","category":"page"},{"location":"advanced_concepts/mga/#Modelling-to-generate-alternative:-Maximally-different-portfolios","page":"Modelling to generate alternatives","title":"Modelling to generate alternative: Maximally different portfolios","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"The idea is that an orginal problem is solved, and subsequently solved again under the condition that the realization of variables should be maximally different from the previous iteration(s), while keeping the objective function within a certain threshold (defined by max_mga_slack).","category":"page"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"In SpineOpt, we choose units_invested_available, connections_invested_available, and storages_invested_available as variables that can be considered for the maximum-difference-problem. The implementation is based on Modelling to generate alternatives: A technique to explore uncertainty in energy-environment-economy models.","category":"page"},{"location":"advanced_concepts/mga/#How-to-set-up-an-MGA-problem","page":"Modelling to generate alternatives","title":"How to set up an MGA problem","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"model: In order to explore an MGA model, you will need one model of type spineopt_mga. You should also define the number of iterations (max_mga_iterations, and the maximum allowed deviation from the original objective function (max_mga_slack).\nat least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.\nTo include the investment decisions in the MGA difference maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.\nThe original MGA formulation is non-convex (maximization problem of an absolute function), but has been linearized through big M method. For this purpose, one should always make sure that units_invested_big_m_mga, connections_invested_big_m_mga, or storages_invested_big_m_mga, respectively, is sufficently large to always be larger the the maximum possible difference per MGA iteration. (Typically the number of candidates could suffice.)\nAs outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.","category":"page"},{"location":"advanced_concepts/mga/#Modelling-to-generate-alternative:-Trade-offs-between-technology-investments","page":"Modelling to generate alternatives","title":"Modelling to generate alternative: Trade-offs between technology investments","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"The idea of this approach is to explore near-optimal solutions that maximize/minimize investment in a certain technology (or multiple technologies simultanesously). ","category":"page"},{"location":"advanced_concepts/mga/#How-to-set-up-an-MGA-problem-2","page":"Modelling to generate alternatives","title":"How to set up an MGA problem","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"model: In order to explore an MGA model, you will need one model of type spineopt_mga. The maximum allowed deviation from the original objective function should be defined via max_mga_slack. Note that for this method, we don't define an explicit number of iteration via the max_mga_iterations parameter (see also below)\nat least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.\nTo include the investment decisions in the MGA min/maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.\nTo explore near-optimal solutions using this methodology, the units_invested_mga_weight, connections_invested_mga_weight, and storages_invested_mga_weight parameters are used to define near-optimal solutions. For this purpose, these parameters are defined as Arrays, defining the weight of the technology per iterations. Note that the length of these Arrays should be the same for all technologies, as this will correspond to the number of MGA iterations, i.e., the number of near-optimal solutions. To analyze the trade-off between two technology types, we can, e.g., define units_invested_mga_weight for unit group 1 as [-1,-0.5,0], whereas the use the weights [0,-0.5,-1] for the other technology storage group 1 in question. Note that a negative sign will correspond to a minimization of investments in the corresponding technology type, while positive signs correspond to a maximization of the respective technology. In the given example, we would hence first minimize the investments in unit group 1, then minimize the two technologies simultaneuously, and finally only minimize investments in storage group 2.\nAs outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Temporal-Framework","page":"Temporal Framework","title":"Temporal Framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Spine Model aims to provide a high degree of flexibility in the temporal dimension across different components of the created model. This means that the user has some freedom to choose how the temporal aspects of different components of the model are defined. This freedom increases the variety of problems that can be tackled in Spine: from very coarse, long term models, to very detailed models with a more limited horizon, or a mix of both. The choice of the user on how this flexibility is used will lead to the temporal structure of the model.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The main components of flexibility consist of the following parts:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The horizon that is modeled: end and start time\nTemporal resolution\nPossibility of a rolling optimization window\nSupport for commonly used methods such as representative days","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Part of the temporal flexibility in Spine is due to the fact that these options mentioned above can be implemented differently across different components of the model, which can be very useful when different markets are coupled in a single model. The resolution and horizon of the gas market can for example be taken differently than that of the electricity market. This documentation aims to give the reader insight in how these aspects are defined, and which objects are used for this.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"We start by introducing the relevant objects with their parameters, and the relevant relationship classes for the temporal structure. Afterwards, we will discuss how this setting creates flexibility and will present some of the practical approaches to create a variety of temporal structures.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Objects,-relationships,-and-their-parameters","page":"Temporal Framework","title":"Objects, relationships, and their parameters","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"In this section, the objects and relationships will be discussed that form the temporal structure together.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Objects-relevant-for-the-temporal-framework","page":"Temporal Framework","title":"Objects relevant for the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"For the objects, the relevant parameters will also be introduced, along with the type of values that are allowed, following the format below: ","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"'parameter_name' : \"Allowed value type\"","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model](@ref)-object","page":"Temporal Framework","title":"model object","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Each model object holds general information about the model at hand. Here we only discuss the time related parameters:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"model_start and model_end : \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"These two parameters define the model horizon. A Datetime value is to be taken for both parameters, in which case they directly mark respectively the beginning and end of the modeled time horizon.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"duration_unit (optional): \"minute or hour\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameters gives the unit of duration that is used in the model calculations. The default value for this parameter is 'minute'. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"roll_forward (optional): \"duration value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In the practical approaches presented below, the rolling window optimization will be explained in more detail.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[temporal_block](@ref)-object","page":"Temporal Framework","title":"temporal_block object","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"A temporal block defines the properties of the optimization that is to be solved in the current window. Most importantly, it holds the necessary information about the resolution and horizon of the optimization.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"resolution (optional): \"duration value\" or \"array of duration values\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"block_start (optional): \"duration value\" or \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Indicates the start of this temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"block_end(optional): \"duration value\" or \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Indicates the end of this temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Relationships-relevant-for-the-temporal-framework","page":"Temporal Framework","title":"Relationships relevant for the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#[model__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"In this relationship, a model instance is linked to a temporal block. If this relationship doesn't exist - the temporal block is disregarded from this optimization model.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model__default_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__default_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Defines the default temporal block used for model objects, which will be replaced when a specific relationship is defined for a model in model__temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[node__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"node__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship will link a node to a temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[units_on__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"units_on__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship links the units_on variable of a unit to a temporal block and will therefore govern the time-resolution of the unit's online/offline status.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[unit__investment_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"unit__investment_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship sets the temporal dimensions for investment decisions of a certain unit. The separation between this relationship and the units_on__temporal_block, allows the user for example to give a much finer resolution to a unit's on- or offline status than to it's investment decisions.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model__default_investment_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__default_investment_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Defines the default temporal block used for investment decisions, which will be replaced when a specific relationship is defined for a unit in unit__investment_temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#General-principle-of-the-temporal-framework","page":"Temporal Framework","title":"General principle of the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The general principle of the Spine modeling temporal structure is that different temporal blocks can be defined and linked to different objects in a model. This leads to great flexibility in the temporal structure of the model as a whole. To illustrate this, we will discuss some of the possibilities that arise in this framework.","category":"page"},{"location":"advanced_concepts/temporal_framework/#One-single-temporal_block","page":"Temporal Framework","title":"One single temporal_block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Single-solve-with-single-block","page":"Temporal Framework","title":"Single solve with single block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The simplest case is a single solve of the entire time horizon (so roll_forward not defined) with a fixed resolution. In this case, only one temporal block has to be defined with a fixed resolution. Each node has to be linked to this temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Alternatively, a variable resolution can be defined by choosing an array of durations for the resolution parameter. The sum of the durations in the array then have to match the length of the temporal block. The example below illustrates an optimization that spans one day for which the resolution is hourly in the beginning and then gradually decreases to a 6h resolution at the end.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_block_1\nblock_start: 0h (Alternative DateTime: e.g. 2030-01-01T00:00:00)\nblock_end: 1D (Alternative DateTime: e.g. 2030-01-02T00:00:00)\nresolution: [1h 1h 1h 1h 2h 2h 2h 4h 4h 6h]","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Note that, as mentioned above, the block_start and block_end parameters can also be entered as absolute values, i.e. DateTime values.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Rolling-window-optimization-with-single-block","page":"Temporal Framework","title":"Rolling window optimization with single block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"A model with a single temporal_block can also be optimized in a rolling horizon framework. In this case, the roll_forward parameter has to be defined in the model object. The roll_forward parameter will then determine how much the optimization moves forward with every step, while the size of the temporal block will determine how large a time frame is optimized in each step. To see this more clearly, let's take a look at an example.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Suppose we want to model a horizon of one week, with a rolling window size of one day. The roll_forward parameter will then be a duration value of 1d. If we take the temporal_block parameters block_start and block_end to be the duration values 0h and 1d respectively, the model will optimize each day of the week separately. However, we could also take the block_end parameter to be 2d. Now the model will start by optimizing day 1 and day 2 together, after which it keeps only the values obtained for the first day, and moves forward to optimize the second and third day together.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Again, a variable resolution can be implemented for the rolling window optimization. The sum of the durations must in this case match the size of the optimized window.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Advanced-usage:-multiple-temporal_block-objects","page":"Temporal Framework","title":"Advanced usage: multiple temporal_block objects","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Single-solve-with-multiple-blocks","page":"Temporal Framework","title":"Single solve with multiple blocks","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Disconnected-time-periods","page":"Temporal Framework","title":"Disconnected time periods","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Multiple temporal blocks can be used to optimize disconnected periods. Let's take a look at an example in which two temporal blocks are defined.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_block_1\nblock_start: 0h\nblock_end: 4h\ntemporal_block_2\nblock_start: 12h\nblock_end: 16h","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This example will lead to an optimization of the first four hours of the model horizon, and also of hour 12 to 16. By defining exactly the same relationships for the two temporal blocks, an optimization of disconnected periods is achieved for exactly the same model components. This leads to the possibility of implementing the widely used representative days method. If desired, it is possible to choose a different temporal resolution for the different temporal_blocks.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"It is worth noting that dynamic variables like node_state and units_on merit special attention when using disconnected time periods. By default, when trying to access variables Variables outside the defined temporal_blocks, SpineOpt.jl assumes such variables exist but allows them to take any values within specified bounds. If fixed initial conditions for the disconnected periods are desired, one needs to use parameters such as fix_node_state or fix_units_on.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Different-regions/commodities-in-different-resolutions","page":"Temporal Framework","title":"Different regions/commodities in different resolutions","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Multiple temporal blocks can also be used to model different regions or different commodities with a different resolution. This is especially useful when there is a certain region or commodity of interest, while other elements are connected to this but require less detail. For this kind of usage, the relationships that are defined for the temporal blocks will be different, as shown in the example below.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_blocks\ntemporal_block_1\nresolution: 1h\ntemporal_block_2\nresolution: 2h\nnodes\nnode_1\nnode_2\nnode_temporal_block relationships\nnode_1_temporal_block_1\nnode_2_temporal_block_2","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Similarly, the on- and offline status of a unit can be modeled with a lower resolution than the actual output of that unit, by defining the units_on_temporal_block relationship with a different temporal block than the one used for the node_temporal_block relationship (of the node to which the unit is connected).","category":"page"},{"location":"advanced_concepts/temporal_framework/#Rolling-horizon-with-multiple-blocks","page":"Temporal Framework","title":"Rolling horizon with multiple blocks","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Rolling-horizon-with-different-window-sizes","page":"Temporal Framework","title":"Rolling horizon with different window sizes","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Similar to what has been discussed above in Different regions/commodities in different resolutions, different commodities or regions can be modeled with a different resolution in the rolling horizon setting. The way to do it is completely analogous. Furthermore, when using the rolling horizon framework, a different window size can be chosen for the different modeled components, by simply using a different block_end parameter. However, using different block_ends e.g. for interconnected regions should be treated with care, as the variables for each region will only be generated for their respective temporal_block, which in most cases will lead to inconsistent linking constraints.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Putting-it-all-together:-rolling-horizon-with-variable-resolution-that-differs-for-different-model-components","page":"Temporal Framework","title":"Putting it all together: rolling horizon with variable resolution that differs for different model components","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Below is an example of an advanced use case in which a rolling horizon optimization is used, and different model components are optimized with a different resolution. By choosing the relevant parameters in the following way:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"model\nroll_forward: 4h\ntemporal_blocks\ntemporal_block_A\nresolution: [1h 1h 2h 2h 2h 3h 3h]\nblock_end: 14h\ntemporal_block_B\nresolution: [2h 2h 4h 6h]\nblock_end: 14h\nnodes\nnode_1\nnode_2\nnode_temporal_block relationships\nnode_1_temporal_block_A\nnode_2_temporal_block_B","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The two model components that are considered have a different resolution, and their own resolution is also varying within the optimization window. Note that in this case the two optimization windows have the same size, but this is not strictly necessary. The image below visualizes the first two window optimizations of this model.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"(Image: temporal structure)","category":"page"},{"location":"concept_reference/fix_binary_gas_connection_flow/","page":"-","title":"-","text":"The binary flow of a gas pipelines for pressure driven gas transfer is enables through the binary variable binary_gas_connection_flow and the big_m constant. To fix this binary variable, i.e. pre-define the direction of gas through the pipelines, the fix_binary_gas_connection_flow parameter can be used.","category":"page"},{"location":"concept_reference/connection_capacity/","page":"-","title":"-","text":"Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.","category":"page"},{"location":"concept_reference/fix_units_invested/","page":"-","title":"-","text":"Used primarily to fix the value of the units_invested variable which represents the point-in-time unit investment decision variable and how many candidate units are invested-in in a particular timeslice.","category":"page"},{"location":"concept_reference/fix_units_invested/","page":"-","title":"-","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"The candidate_connections parameter denotes the possibility of investing on a certain connection.","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"The default value of nothing means that the connection can't be invested in, because it's already in operation. An integer value represents the maximum investment possible at any point in time, as a factor of the connection_capacity.","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"In other words, candidate_connections is the upper bound of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/connection__to_node__unit_constraint/","page":"-","title":"-","text":"connection__to_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable from the specified connection to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__to_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/is_reserve_node/","page":"-","title":"-","text":"By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/storages_invested_mga/","page":"-","title":"-","text":"The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/units_on_non_anticipativity_time/","page":"-","title":"-","text":"The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.","category":"page"},{"location":"concept_reference/units_on_non_anticipativity_time/","page":"-","title":"-","text":"This is intended to model \"slow\" units whose commitment decision needs to be taken in advance, e.g., in \"day-ahead\" mode, and cannot be changed afterwards.","category":"page"},{"location":"mathematical_formulation/objective_function/#Objective-function","page":"Objective","title":"Objective function","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The objective function of SpineOpt expresses the minimization of the total system costs associated with maintaining and operating the considered energy system.","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n min obj = v_unit_investment_costs + v_connection_investment_costs + v_storage_investment_costs\n + v_fixed_om_costs + v_variable_om_costs + v_fuel_costs + v_start_up_costs \n + v_shut_down_costs + v_res_proc_costs \n + v_renewable_curtailment_costs + v_connection_flow_costs + v_taxes +\nv_objective_penalties\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Note that each cost term is reflected here as a separate variable that can be expressed mathematically by the equations below. All cost terms are weighted by the associated scenario and temporal block weights. To enhance readability and avoid writing a product of weights in every cost term, all weights are combined in a single weight parameter p_weight(). As such, the indices associated with each weight parameter indicate which weights are included.","category":"page"},{"location":"mathematical_formulation/objective_function/#Unit-investment-costs","page":"Objective","title":"Unit investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account unit investments in the objective function, the parameter unit_investment_cost can be defined. For all tuples of (unit, scenario, timestep) in the set units_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a unit is invested in during the current optimization window. The total unit investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_unit_investment_costs \n = sum_substack(ust) in units_invested_available_indices\n u in ind(p_unit_investment_cost)\n v_units_invested(u s t) cdot p_unit_investment_cost(ust) cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Connection-investment-costs","page":"Objective","title":"Connection investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account connection investments in the objective function, the parameter connection_investment_cost can be defined. For all tuples of (connection, scenario, timestep) in the set connections_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a connection is invested in during the current optimization window. The total connection investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_connection_investment_costs \n = sum_substack(connst) in connections_invested_available_indices conn in ind(p_connection_investment_cost)\n v_connections_invested(conn s t) cdot p_connection_investment_cost(connst) cdot p_weight(connst) \nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Storage-investment-costs","page":"Objective","title":"Storage investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account storage investments in the objective function, the parameter storage_investment_cost can be defined. For all tuples of (node, scenario, timestep) in the set storages_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a node storage is invested in during the current optimization window. The total storage investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_storage_investment_costs \n = sum_substack(nst) in storages_invested_available_indices n in ind(p_storage_investment_cost)\n v_storages_invested(n s t) cdot p_storage_investment_cost(nst) cdot p_weight(nst) \nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Fixed-O-and-M-costs","page":"Objective","title":"Fixed O&M costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Fixed operation and maintenance costs associated with a specific unit can be accounted for by defining the parameters fom_cost and unit_capacity. For all tuples of (unit, {node,node_group}, direction) for which these parameters are defined, and for which tuples (unit, scenario, timestep) exist in the set units_on_indices, a fixed O&M cost term is added to the objective function. Note that, as the units_on_indices are used to retrieve the relevant time slices, the unit of the fom_cost parameter should be given per resolution of the units_on. The total fixed O&M costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_fixed_om_costs \n = \nsum_substack(ust) in units_on_indices\ntext sum_substack(und) in ind(p_unit_capacity) u in ind(p_fom_cost) \n leftp_number_of_units(ust) + sum_substack(ust) in units_invested_available_indices t in t_overlaps_t(t) v_units_invested_available(u s t) right \n cdot p_unit_capacity(undst)\n cdot p_fom_cost(ust)\n p_weight(t) cdot\n p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Variable-O-and-M-costs","page":"Objective","title":"Variable O&M costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Variable operation and maintenance costs associated with a specific unit can be accounted for by defining the parameter (vom_cost). For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a variable O&M cost term is added to the objective function. As the parameter vom_cost is a dynamic parameter, the cost term is multiplied with the duration of each timestep. The total variable O&M costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_variable_om_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_vom_cost)\n v_unit_flow(u n d s t) cdot p_vom_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Fuel-costs","page":"Objective","title":"Fuel costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Fuel costs associated with a specific unit can be accounted for by defining the parameter fuel_cost. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a fuel cost term is added to the objective function. As the parameter fuel_cost is a dynamic parameter, the cost term is multiplied with the duration of each timestep. The total fuel costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_fuel_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_fuel_cost)\n v_unit_flow(u n d s t) cdot p_fuel_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Connection-flow-costs","page":"Objective","title":"Connection flow costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To account for operational costs associated with flows over a specific connection, the connection_flow_cost parameter can be defined. For all tuples of (conn, {node,node_group}, direction, scenario, timestep) in the set connection_flow_indices for which this parameter is defined, a connection flow cost term is added to the objective function. The total connection flow costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_connection_flow_costs \n = sum_substack(connndst) in connection_flow_indices conn in ind(p_connection_flow_cost)\nv_connection_flow (conn n d s t) cdot p_connection_flow_cost(connst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Start-up-costs","page":"Objective","title":"Start up costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Start up costs associated with a specific unit can be included by defining the start_up_cost parameter. For all tuples of (unit, scenario, timestep) in the set units_on_indices for which this parameter is defined, a start up cost term is added to the objective function. The total start up costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_start_up_costs \n = sum_substack(ust) in units_on_indices u in ind(p_start_up_cost)\n v_units_started_up(u s t) cdot p_start_up_cost(ust)cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Shut-down-costs","page":"Objective","title":"Shut down costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Shut down costs associated with a specific unit can be included by defining the shut_down_cost parameter. For all tuples of (unit, scenario, timestep) in the set units_on_indices for which this parameter is defined, a shut down cost term is added to the objective function. The total shut down costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_shut_down_costs \n = sum_substack(ust) in units_on_indices u in ind(p_shut_down_cost)\nv_units_shut_down(ust) cdot p_start_up_cost(ust)cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Reserve-procurement-costs","page":"Objective","title":"Reserve procurement costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The procurement costs for reserves provided by a specific unit can be accounted for by defining the reserve_procurement_cost parameter. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a reserve procurement cost term is added to the objective function. The total reserve procurement costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_res_proc_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_reserve_procurement_cost)\nv_unit_flow(u n d s t) cdot p_reserve_procurement_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Renewable-curtailment-costs","page":"Objective","title":"Renewable curtailment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The curtailment costs of renewable units can be accounted for by defining the parameters curtailment_cost and unit_capacity. For all tuples of (unit, {node,node_group}, direction) for which these parameters are defined, and for which tuples (unit, scenario, timestep_long) exist in the set units_on_indices, and for which tuples (unit, {node,node_group}, direction, scenario, timestep_short) exist in the set unit_flow_indices, a renewable curtailment cost term is added to the objective function. The total renewable curtailment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_renewable_curtailment_costs \n = sum_substack(und) in ind(p_unit_capacity) u in ind(p_curtailment_cost)\nsum_substack(ust_long) in units_on_indices\nsum_substack(unst_short) in unit_flow_indices \n ( v_units_available(u s t_long)cdot p_unit_capacity(undst_short) cdot p_unit_conv_cap_to_flow(undst_short) \n - v_unit_flow(u n d s t_short) ) \n cdot p_curtailment_cost(ust_short) cdot p_weight(nst_short) cdot p_duration(t_short)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Taxes","page":"Objective","title":"Taxes","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To account for taxes on certain commodity flows, the tax unit flow parameters (i.e., tax_net_unit_flow, tax_out_unit_flow and tax_in_unit_flow) can be defined. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which these parameters are defined, a tax term is added to the objective function. The total taxes can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_taxes \n = sum_substack(undst) in unit_flow_indices n in ind(p_tax_net_unit_flow) d= to_node\nv_unit_flow(u n d s t)cdot p_tax_net_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\n - sum_substack(undst) in unit_flow_indices n in ind(p_tax_net_unit_flow) d= from_node\nv_unit_flow(u n d s t)cdot p_tax_net_unit_flow(nst)cdot p_weight(nst)cdot p_duration(t)\n + sum_substack(undst) in unit_flow_indices n in ind(p_tax_out_unit_flow) d= from_node\n v_unit_flow(u n d s t)cdot p_tax_out_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\n + sum_substack(undst) in unit_flow_indices n in ind(p_tax_in_unit_flow) d= to_node\n v_unit_flow(u n d s t)cdot p_tax_in_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Objective-penalties","page":"Objective","title":"Objective penalties","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Penalty cost terms associated with the slack variables of a specific constraint can be accounted for by defining a node_slack_penalty parameter. For all tuples of ({node,node_group}, scenario, timestep) in the set node_slack_indices for which this parameter is defined, a penalty term is added to the objective function. The total objective penalties can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_objective_penalties \n = sum_substack(ust) in node_slack_indices\nleftv_node_slack_neg(n s t)-v_node_slack_pos(n s t) rightcdot p_node_slack_penalty(nst)cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"concept_reference/cyclic_condition/","page":"-","title":"-","text":"The cyclic_condition parameter is used to enforce that the storage level at the end of the optimization window is higher or equal to the storage level at the beginning optimization. If the cyclic_condition parameter is set to true for a node__temporal_block relationship, and the has_state parameter of the corrresponding node is set to true, the constraint_cyclic_node_state will be triggered.","category":"page"},{"location":"concept_reference/node__investment_temporal_block/","page":"-","title":"-","text":"node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.","category":"page"},{"location":"concept_reference/node__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"tutorial/reserves/#Reserve-definition-tutorial","page":"Reserve requirements","title":"Reserve definition tutorial","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"This tutorial provides a step-by-step guide to include reserve requirements in a simple energy system with Spine Toolbox for SpineOpt.","category":"page"},{"location":"tutorial/reserves/#Introduction","page":"Reserve requirements","title":"Introduction","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Welcome to our tutorial, where we will walk you through the process of adding a new reserve node in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Reserves refer to the capacity or energy that is kept as a backup to ensure the power system's reliability. This reserve capacity can be brought online automatically or manually in the event of unforeseen system disruptions such as generation failure, transmission line failure, or a sudden increase in demand. Operating reserves are essential to ensure that there is always enough generation capacity available to meet demand, even in the face of unforeseen system disruptions.","category":"page"},{"location":"tutorial/reserves/#Model-assumptions","page":"Reserve requirements","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"The reserve node has a requirement of 20MW for upwards reserve\nPower plants 'a' and 'b' can both provide reserve to this node","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Guide","page":"Reserve requirements","title":"Guide","text":"","category":"section"},{"location":"tutorial/reserves/#Entering-input-data","page":"Reserve requirements","title":"Entering input data","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.\nLocate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In this tutorial, you will learn how to add a new reserve node to the Simple System.","category":"page"},{"location":"tutorial/reserves/#Creating-objects","page":"Reserve requirements","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nRight click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.\nEnter the names for the new reserve node as seen in the image below, then press Ok. This will create a new object of class node, called upward_reserve_node.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Right click on the node class, and select Add object group from the context menu. The Add object group dialog will pop up. In the Group name field write upward_reserve_group to refer to this group. Then, add as a members of the group the nodes electricity_node and upward_reserve_node, as shown in the image below; then press Ok.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"note: Note\n","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In SpineOpt, groups of nodes allow the user to create constraints that involve variables from its members. Later in this tutorial, the group named upward_reserve_group will help to link the flow variables for electricity production and reserve procurement.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Establishing-relationships","page":"Reserve requirements","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into both the upward_reserve_node and the upward_reserve_group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and variable_om_costs under output. Repeat the same procedure in the second line to add the res_proc_costs under output as seen in the image below; then press Ok. This will write the total vom_cost and procurement reserve cost values in the objective function to the output database as a part of report1.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Specifying-object-parameter-values","page":"Reserve requirements","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Back to Object tree, expand the node class and select upward_reserve_node.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:\ndemand parameter and the Base alternative, and enter the value 20. This will establish that there's a demand of '20' at the reverse node.\nis_reserve_node parameter and the Base alternative, and enter the value True. This will establish that it is a reverse node.\nupward_reserve parameter and the Base alternative, then right-click on the value cell and then, in the context menu, select 'Edit...' and select the option True. This will establish the direction of the reserve is upwards.\nnodal_balance_sense parameter and the Base alternative, and enter the value geq. This will establish that the total reserve procurement must be greater or equal than the reserve demand.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Select upward_reserve_group in the Object tree.\nIn the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that there is no need to create an extra balance between the members of the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Specifying-relationship-parameter-values","page":"Reserve requirements","title":"Specifying relationship parameter values","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity to provide reserve for power_plant_a.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"note: Note\n","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"The value is equal to the unit capacity defined for the electricity node. However, the value can be lower if the unit cannot provide reserves with its total capacity.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity to provide reserve for power_plant_b.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_group.\nIn the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:\nunit_capacity parameter and the Base alternative, and enter the value 100. This will set the total capacity for power_plant_a in the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_group.\nIn the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:\nunit_capacity parameter and the Base alternative, and enter the value 200. This will set the total capacity for power_plant_b in the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"When you're ready, save/commit all changes to the database.","category":"page"},{"location":"tutorial/reserves/#Executing-the-workflow","page":"Reserve requirements","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.","category":"page"},{"location":"tutorial/reserves/#Examining-the-results","page":"Reserve requirements","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables or use a pivot table.\nFor the pivot table, press Alt + F for the shortcut to the hamburger menu, and select Pivot -> Index.\nSelect report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.\nUnder alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.\nThe Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"As anticipated, the power_plant_b is supplying the necessary reserve due to its surplus capacity, while power_plant_a is operating at full capacity. Additionally, in this model, we have not allocated a cost for reserve procurement. One way to double-check it is by selecting report__model under Relationship tree and look at the costs the Pivot table, see image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"So, is it possible to assign costs to this reserve procurement in SpineOpt? Yes, it is indeed possible.","category":"page"},{"location":"tutorial/reserves/#Specifying-a-reserve-procurement-cost-value","page":"Reserve requirements","title":"Specifying a reserve procurement cost value","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 5 as seen in the image below. This will set the cost of providing reserve for power_plant_a.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 35 as seen in the image below. This will set the cost of providing reserve for power_plant_b.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Don't forget to commit the new changes to the database!","category":"page"},{"location":"tutorial/reserves/#Executing-the-worflow-and-examining-the-results-again","page":"Reserve requirements","title":"Executing the worflow and examining the results again","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Go back to Spine Toolbox's main window, and hit again the Execute project button as before.\nSelect the output data store and open the Spine DB editor. You can inspect results as before, which should look like the image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Since the cost of reserve procurement is way cheaper in power_plant_a than in power_plant_b, then the optimal solution is to reduce the production of electricity in power_plant_a to provide reserve with this unit rather than power_plant_b as before. By looking at the total costs, we can see that the reserve procurement costs are no longer zero.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"advanced_concepts/investment_optimization/#Investment-Optimization","page":"Investment Optimization","title":"Investment Optimization","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"SpineOpt offers numerous ways to optimise investment decisions energy system models and in particular, offers a number of methologogies for capturing increased detail in investment models while containing the impact on run time. The basic principles of investments will be discussed first and this will be followed by more advanced approaches.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Key-concepts-for-investments","page":"Investment Optimization","title":"Key concepts for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Decisions These are the investment decisions that SpineOpt currently supports. At a high level, this means that the activity of the entities in question is controlled by an investment decision variable. The current implementation supports investments in :","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit\nconnection\nStorage - Note: while the above investment decisions correspond to an object class (i.e.) an investment in a unit or a connection, Storages are not an object class in themselves and are rather a property of a node. As such, a storage investment controls whether a particular node has a state variable or not. ","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Variable Types In all cases the capacity of the unit or connection or the maximum node state of a node is multiplied by the investment variable which may either be continuous, binary or integer. This is determined, for units, by setting the unit_investment_variable_type parameter accordingly. Similary, for connections and node storages the connection_investment_variable_type and storage_investment_variable_type are specified.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Identiying Investment Candidate Units, Connections and Storages The parameter candidate_units represents the number of units of this type that may be invested in. candidate_units determines the upper bound of the investment variable and setting this to a value greater than 0 identifies the unit as an investment candidate unit in the optimisation. If the unit_investment_variable_type is set to :variable_type_integer, the investment variable can be interpreted as the number of discrete units that may be invested in. However, if unit_investment_variable_type is :variable_type_continuous and the unit_capacity is set to unity, the investment decision variable can then be interpreted as the capacity of the unit rather than the number of units with candidate_units being the maximum capacity that can be invested in. Finally, we can invest in discrete blocks of capacity by setting unit_capacity to the size of the investment capacity blocks and have unit_investment_variable_type set to :variable_type_integer with candidate_units representing the maximum number of capacity blocks that may be invested in. The key points here are:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"The upper bound on the relevant flow variables are determined by the product of the investment variable and the unit_capacity or connection_capacity for connections or node_state_cap for storages.\ncandidate_units sets the upper bound on the investment variable, candidate_connections for connections and candidate_storages for storages\nunit_investment_variable_type determines whether the investment variable is integer, binary or continuous (connection_investment_variable_type for connections and storage_investment_variable_type for storages).","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Costs Investment costs are specified by setting the appropriate *_investment\\_cost parameter. The investment cost for units are specified by setting the unit_investment_cost parameter. This is currently interpreted as the full cost over the investment period for the unit. See the section below on investment temporal structure for setting the investment period. If the investment period is 1 year, then the corresponding unit_investment_cost is the annualised investment cost. For connections and storages, the investment cost parameters are connection_investment_cost and storage_investment_cost, respectively.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Temporal and Stochastic Structure of Investment Decisions SpineOpt's flexible stochastic and temporal structure extend to investments where individual investment decisions can have their own temporal and stochastic structure independent of other investment decisions and other model variables. A global temporal resolution for all investment decisions can be defined by specifying the relationship model__default_investment_temporal_block. If a specific temporal resolution is required for specific investment decisions, then one can specify the following relationships:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit__investment_temporal_block for units,\nconnection__investment_temporal_block for connections, and\nnode__investment_temporal_block for storages. ","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Specifying any of the above relationships will override the corresponding model__default_investment_temporal_block.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Similarly, a global stochastic structure can be defined for all investment decisions by specifying the relationship model__default_investment_stochastic_structure. If a specific stochastic structure is required for specific investment decisions, then one can specifying the following relationships:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit__investment_stochastic_structure for units,\nconnection__investment_stochastic_structure for connections, and\nnode__investment_stochastic_structure for storages.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Specifying any of the above relationships will override the corresponding model__default_investment_stochastic_structure.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Creating-an-Investment-Candidate-Unit-Example","page":"Investment Optimization","title":"Creating an Investment Candidate Unit Example","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"If we have model that is not currently set up for investments and we wish to create an investment candidate unit, we can take the following steps.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Create the unit object with all the relationships and parameters necessary to describe its function.\nEnsure that the number_of_units parameter is set to zero so that the unit is unavailable unless invested in.\nSet the candidate_units parameter for the unit to 1 to specify that a maximum of 1 new unit of this type may be invested in by the model.\nSet the unit_investment_variable_type to unit_investment_variable_type_integer to specify that this is a discrete unit investment decision.\nSpecify the unit_investment_lifetime of the unit to, say, 1 year to specify that this is the minimum amount of time this new unit must be in existence after being invested in.\nSpecify the investment period for this unit's investment decision in one of two ways:\nDefine a default investment period for all investment decisions in the model as follows:\ncreate a temporal_block with the appropriate resolution (say 1 year)\nlink this to your model object by creating the appropriate model__temporal_block relationship\nset it as the default investment temporal block by setting model__default_investment_temporal_block\nOr, define an investment period unique to this investment decision as follows:\ncreating a temporal_block with the appropriate resolution (say 1 year)\nlink this to your model object by creating the appropriate model__temporal_block relationship\nspecify this as the investment period for your unit's investment decision by setting the appropriate unit__investment_temporal_block relationship\nSimilarly to the above, define the stochastic structure for the unit's investment decision by specifying either model__default_investment_stochastic_structure or unit__investment_stochastic_structure\nSpecify your unit's investment cost by setting the unit_investment_cost parameter. Since we have defined the investment period above as 1 year, this is therefore the unit's annualised investment cost.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Model-Reference","page":"Investment Optimization","title":"Model Reference","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/#Variables-for-investments","page":"Investment Optimization","title":"Variables for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Variable Name Indices Description\nunits_invested_available unit, s, t The number of invested in units that are available at a given (s, t)\nunits_invested unit, s, t The point-in-time investment decision corresponding to the number of units invested in at (s,t)\nunits_mothballed unit, s, t \"Instantaneous\" decision variable to mothball a unit\nconnections_invested_available connection, s, t The number of invested-in connectionss that are available at a given (s, t)\nconnections_invested connection, s, t The point-in-time investment decision corresponding to the number of connectionss invested in at (s,t)\nconnections_decommissioned connection, s, t \"Instantaneous\" decision variable to decommission a connection\nstorages_invested_available node, s, t The number of invested-in storages that are available at a given (s, t)\nstorages_invested node, s, t The point-in-time investment decision corresponding to the number of storages invested in at (s,t)\nstorages_decommissioned node, s, t \"instantaneous\" decision variable to decommission a storage","category":"page"},{"location":"advanced_concepts/investment_optimization/#Relationships-for-investments","page":"Investment Optimization","title":"Relationships for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Relationship Name Related Object Class List Description\nmodel__default_investment_temporal_block model, temporal_block Default temporal resolution for investment decisions effective if unit__investmenttemporalblock is not specified\nmodel__default_investment_stochastic_structure model, stochastic_structure Default stochastic structure for investment decisions effective if unit__investmentstochasticstructure is not specified\nunit__investment_temporal_block unit, temporal_block Set temporal resolution of investment decisions - overrides model__defaultinvestmenttemporal_block\nunit__investment_stochastic_structure unit, stochastic_structure Set stochastic structure for investment decisions - overrides model__defaultinvestmentstochastic_structure","category":"page"},{"location":"advanced_concepts/investment_optimization/#Parameters-for-investments","page":"Investment Optimization","title":"Parameters for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Parameter Name Object Class List Description\ncandidate_units unit The number of additional units of this type that can be invested in\nunit_investment_cost unit The total overnight investment cost per candidate unit over the model horizon\nunit_investment_lifetime unit The investment lifetime of the unit - once invested-in, a unit must exist for at least this amount of time\nunit_investment_variable_type unit Whether the units_invested_available variable is continuous, integer or binary\nfix_units_invested unit Fix the value of units_invested\nfix_units_invested_available unit Fix the value of connections_invested_available\ncandidate_connections connection The number of additional connections of this type that can be invested in\nconnection_investment_cost connection The total overnight investment cost per candidate connection over the model horizon\nconnection_investment_lifetime connection The investment lifetime of the connection - once invested-in, a connection must exist for at least this amount of time\nconnection_investment_variable_type connection Whether the connections_invested_available variable is continuous, integer or binary\nfix_connections_invested connection Fix the value of connections_invested\nfix_connections_invested_available connection Fix the value of connection_invested_available\ncandidate_storages node The number of additional storages of this type that can be invested in at node\nstorage_investment_cost node The total overnight investment cost per candidate storage over the model horizon\nstorage_investment_lifetime node The investment lifetime of the storage - once invested-in, a storage must exist for at least this amount of time\nstorage_investment_variable_type node Whether the storages_invested_available variable is continuous, integer or binary\nfix_storages_invested node Fix the value of storages_invested\nfix_storages_invested_available node Fix the value of storages_invested_available","category":"page"},{"location":"advanced_concepts/investment_optimization/#Related-Model-Files","page":"Investment Optimization","title":"Related Model Files","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Filename Relative Path Description\nconstraintunitsinvested_available.jl \\constraints constrains units_invested_available to be less than candidate_units\nconstraintunitsinvested_transition.jl \\constraints defines the relationship between units_invested_available, units_invested and units_mothballed. Analagous to units_on, units_started and units_shutdown\nconstraintunitlifetime.jl \\constraints once a unit is invested-in, it must remain in existence for at least unit_investment_lifetime - analagous to min_up_time.\nconstraintunitsavailable.jl \\constraints Enforces units_available is the sum of number_of_units and units_invested_available\nconstraintconnectionsinvested_available.jl \\constraints constrains connections_invested_available to be less than candidate_connections\nconstraintconnectionsinvested_transition.jl \\constraints defines the relationship between connections_invested_available, connections_invested and connections_decommissioned. Analagous to units_on, units_started and units_shutdown\nconstraintconnectionlifetime.jl \\constraints once a connection is invested-in, it must remain in existence for at least connection_investment_lifetime - analagous to min_up_time.\nconstraintstoragesinvested_available.jl \\constraints constrains storages_invested_available to be less than candidate_storages\nconstraintstoragesinvested_transition.jl \\constraints defines the relationship between storages_invested_available, storages_invested and storages_decommissioned. Analagous to units_on, units_started and units_shutdown\nconstraintstoragelifetime.jl \\constraints once a storage is invested-in, it must remain in existence for at least storage_investment_lifetime - analagous to min_up_time.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.","category":"page"},{"location":"concept_reference/model_type_list/","page":"-","title":"-","text":"model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/fix_units_invested_available/","page":"-","title":"-","text":"Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/fix_units_invested_available/","page":"-","title":"-","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/node__unit_constraint/","page":"-","title":"-","text":"node__user_constraint is a two-dimensional relationship between a node and a user_constraint. The relationship specifies that a variable associated only with the node (currently only the node_state) is involved in the constraint. For example, the node_state_coefficient defined on node__user_constraint specifies the coefficient of the node's node_state variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/node__unit_constraint/","page":"-","title":"-","text":"See also user_constraint","category":"page"},{"location":"concept_reference/investment_group/","page":"-","title":"-","text":"The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.","category":"page"},{"location":"concept_reference/investment_group/","page":"-","title":"-","text":"To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.","category":"page"},{"location":"concept_reference/state_coeff/","page":"-","title":"-","text":"The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.","category":"page"},{"location":"concept_reference/state_coeff/","page":"-","title":"-","text":"Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.","category":"page"},{"location":"concept_reference/commodity/","page":"-","title":"-","text":"Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)","category":"page"},{"location":"concept_reference/demand_coefficient/","page":"-","title":"-","text":"The demand_coefficient is an optional parameter that can be used to include the demand of the a node in a user_constraint via the node__user_constraint relationship. Essentially, demand_coefficient appears as a coefficient for the demand parameter of the connected node in the user constraint.","category":"page"},{"location":"concept_reference/min_voltage_angle/","page":"-","title":"-","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), a lower bound on the pressure can be introduced through the min_voltage_angle parameter, which triggers the generation of the minimum node voltage angle constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Constraints","page":"Constraints","title":"Constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Balance-constraint","page":"Constraints","title":"Balance constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_nodal_balance","page":"Constraints","title":"Nodal balance","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In SpineOpt, node is the place where an energy balance is enforced. As universal aggregators, they are the glue that brings all components of the energy system together. An energy balance is created for each node for all node_stochastic_time_indices, unless the balance_type parameter of the node takes the value balance_type_none or if the node in question is a member of a node group, for which the balance_type is balance_type_group. The parameter nodal_balance_sense defaults to equality, but can be changed to allow overproduction (nodal_balance_sense >=) or underproduction (nodal_balance_sense <=). The energy balance is enforced by the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_injection_(nst)\n+ sum_\n conn\n\nv^connection_flow_(connnto_nodest)\n- sum_\n conn\n\nv^connection_flow_(connnfrom_nodest) \n begincases\nge textif p^nodal_balance_sense = = \n= textif p^nodal_balance_sense = == \nle textif p^nodal_balance_sense = = \nendcases \n 0 \n forall n in node p^balance_type_(n) ne balance_type_none land nexists ng ni n p^balance_type_(ng) = balance_type_group \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also balance_type and nodal_balance_sense.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_injection","page":"Constraints","title":"Node injection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The node injection itself represents all local production and consumption, computed as the sum of all connected unit flows and the nodal demand. If a node corresponds to a storage node, the parameter has_state should be set to true for this node. The node injection is created for each node in the network (unless the node is only used for parameter aggregation purposes, see Introduction to groups of objects).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_injection_(nst) \n = \n left(p^state_coeff_(n s t-1) cdot v^node_state_(n s t-1) - p^state_coeff_(n s t) cdot v^node_state_(n s t)right)\n Delta t \n - p^frac_state_loss_(nst) cdot v^node_state_(n s t) \n + sum_n p^diff_coeff_(nnst) cdot v^node_state_(n s t)\n- sum_n p^diff_coeff_(nnst) cdot v^node_state_(n s t) \n + sum_\n u\n\nv^unit_flow_(unto_nodest)\n- sum_\n u\n\nv^unit_flow_(unfrom_nodest)\n - left(p^demand_(nst) + sum_ng ni n p^fractional_demand_(nst) cdot p^demand_(ngst)right) \n + v^node_slack_pos_(nst) - v^node_slack_neg_(nst) \n forall n in node p^has_state_(n)\n forall (s t)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also state_coeff, frac_state_loss, diff_coeff, node__node, unit__from_node, unit__to_node, demand, fractional_demand, has_state.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_state_capacity","page":"Constraints","title":"Node state capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To limit the storage content, the v_node_state variable needs be constrained by the following equation:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^node_state_(n s t) leq p^node_state_cap_(n s t) quad forall n in node p^has_state_(n) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The discharging and charging behavior of storage nodes can be described through unit(s), representing the link between the storage node and the supply node. Note that the dis-/charging efficiencies and capacities are properties of these units. See the capacity constraint and the unit flow ratio constraints.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also node_state_cap, has_state.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_cyclic_node_state","page":"Constraints","title":"Cyclic condition on node state variable","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To ensure that the node state at the end of the optimization is at least the same value as the initial value at the beginning of the optimization (or higher), the cyclic node state constraint can be used by setting the cyclic_condition of a node__temporal_block to true. This triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^node_state_(n s start(tb)) geq v^node_state_(n s end(tb))\nqquad forall (ntb) in indices(p^cyclic_condition) p^cyclic_condition_(ntb)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also cyclic_condition.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Unit-operation","page":"Constraints","title":"Unit operation","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In the following, the operational constraints on the variables associated with units will be elaborated on. The static constraints, in contrast to the dynamic constraints, are addressing constraints without sequential time-coupling. It should however be noted that static constraints can still perform temporal aggregation.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#static-constraints-unit","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The fundamental static constraints for units within SpineOpt relate to the relationships between commodity flows from and to units and to limits on the unit flow capacity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_unit_flow","page":"Constraints","title":"Conversion constraint / limiting flow shares inprocess / relationship in process","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"A unit can have different commodity flows associated with it. The most simple relationship between these flows is a linear relationship between input and/or output nodes/node groups. SpineOpt holds constraints for each combination of flows and also for the type of relationship, i.e. whether it is a maximum, minimum or fixed ratio between commodity flows. Note that node groups can be used in order to aggregate flows, i.e. to give a ratio between a combination of units flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#ratio_unit_flow","page":"Constraints","title":"Ratios between flows of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"By specifying the parameters fix_ratio_out_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_in_in_unit_flow, and/or fix_ratio_out_out_unit_flow, a fix ratio can be set between, respectively, outgoing and incoming flows from and to a unit, incoming and outgoing flows to and from a unit, two incoming flows to a unit, and/or two outgoing flows from a unit.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similary, a minimum ratio between flows can be set by specifying min_ratio_out_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_in_in_unit_flow, and/or min_ratio_out_out_unit_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Finally, a maximum ratio can be set by specifying max_ratio_out_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_in_in_unit_flow, and/or max_ratio_out_out_unit_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For example, whenever there is only a single input node and a single output node, fix_ratio_out_in_unit_flow relates to the notion of efficiency. Also, fix_ratio_in_out_unit_flow can for instance be used to relate emissions to input primary fuel flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The constraint below is written for fix_ratio_out_in_unit_flow, but equivalent formulations exist for the other 11 cases described above.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_out v^unit_flow_(unfrom_nodest) \n = \n p^fix_ratio_out_in_unit_flow_(u ng_out ng_inst)\ncdot sum_n in ng_in v^unit_flow_(unto_nodest) \n + p^fix_units_on_coefficient_out_in_(ung_outng_inst) cdot v^units_on_(ust) \n forall (u ng_out ng_in) in indices(p^fix_ratio_out_in_unit_flow) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nIf any of the above mentioned ratio parameters is specified for a node group, then the ratio is enforced over the sum of flows from or to that group. In this case, there remains a degree of freedom regarding the composition of flows within the group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fix_ratio_out_in_unit_flow, fix_units_on_coefficient_out_in.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_flow_capacity","page":"Constraints","title":"Bounds on the unit capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In a multi-commodity setting, there can be different commodities entering/leaving a certain technology/unit. These can be energy-related commodities (e.g., electricity, natural gas, etc.), emissions, or other commodities (e.g., water, steel). The unit_capacity must be specified for at least one unit__to_node or unit__from_node relationship, in order to trigger a constraint on the maximum commodity flows to this location in each time step. When desirable, the capacity can be specified for a group of nodes (e.g. combined capacity for multiple products).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\n v^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right\n + sum_\n n in ng\n\n v^unit_flow_(undst) cdot left\n p^is_reserve_node_(n) land p^upward_reserve_(n) land neg p^is_non_spinning_(n) \n right\n le \n p^unit_capacity_(ungdst) cdot p^unit_availability_factor_(ust) cdot p^unit_conv_cap_to_flow_(ungdst) \n cdot ( \n qquad v^units_on_(ust) \n qquad + left(1 - p^shut_down_limit_(ungdst)right)\ncdot left( v^units_shut_down_(ust+1)\n+ sum_\n n in ng\n v^nonspin_units_shut_down_(unst) right) \n qquad - left(1 - p^start_up_limit_(ungdst)right) cdot v^units_started_up_(ust) \n ) \n forall (ungd) in indices(p^unit_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe conversion factor unit_conv_cap_to_flow has a default value of 1, but can be adjusted in case the unit of measurement for the capacity is different to the unit flows unit of measurement.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for time-slices whose duration is greater than the minimum up time of the unit. This ensures that the unit is not online for exactly one time-slice, which might result in an infeasibility if this formulation was used. Instead, for time-slices whose duration is lower or equal than the minimum up time of the unit there is a similar formulation, but the details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for flows going from a unit to a node (i.e., output flows). For flows going from a node to a unit (i.e., input flows) the direction of the reserves is switched (downwards becomes upwards, non-spinning units shut-down becomes non-spinning units started-up). The details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, upward_reserve, is_non_spinning, unit_capacity, unit_availability_factor, unit_conv_cap_to_flow, start_up_limit, shut_down_limit.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_minimum_operating_point","page":"Constraints","title":"Constraint on minimum operating point","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The minimum operating point of a unit is based on the unit_flows of input or output nodes/node groups.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst) cdot leftneg p^is_reserve_node_(n)right\n- sum_\n n in ng\n\nv^unit_flow_(undst) cdot leftp^is_reserve_node_(n) land p^downward_reserve_(n)right \n ge p^minimum_operating_point_(ungdst) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) \n cdot left( v^units_on_(ust)\n- sum_\n n in ng\n v^nonspin_units_shut_down_(unst) right) \n forall (ungd) in indices(p^minimum_operating_point) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for flows going from a unit to a node (i.e., output flows). For flows going from a node to a unit (i.e., input flows) the direction of the reserves is switched (downwards becomes upwards, non-spinning units shut-down becomes non-spinning units started-up). The details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, downward_reserve, is_non_spinning, minimum_operating_point, unit_capacity, unit_conv_cap_to_flow","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Dynamic-constraints","page":"Constraints","title":"Dynamic constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Commitment-constraints","page":"Constraints","title":"Commitment constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For modeling certain technologies/units, it is important to not only have unit_flow variables of different commodities, but also model the online (\"commitment\") status of the unit/technology at every time step. Therefore, an additional variable units_on is introduced. This variable represents the number of online units of that technology (for a normal unit commitment model, this variable might be a binary, for investment planning purposes, this might also be an integer or even a continuous variable). To define the type of a commitment variable, see online_variable_type. Commitment variables will be introduced by the following constraints (with corresponding parameters):","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"constraint on units_on\nconstraint on units_available\nconstraint on the unit state transition\nconstraint on minimum down time\nconstraint on minimum up time\nconstraint on ramp rates\nconstraint on reserve provision","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_available","page":"Constraints","title":"Bound on available units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The aggregated available units are constrained by the parameter number_of_units and the variable number of invested units units_invested_available:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_available_(ust) leq p^number_of_units_(ust) + v^units_invested_available_(ust) \n forall u in unit \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also number_of_units.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_on","page":"Constraints","title":"Bound on online units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of online units needs to be restricted to the aggregated available units:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^units_on_(ust) leq v^units_available_(ust) quad forall u in unit forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The investment formulation is described in chapter Investments.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_state_transition","page":"Constraints","title":"Unit state transition","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The units on status is constrained by shutting down and starting up actions. This transition is defined as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_on_(ust) - v^units_started_up_(ust) + v^units_shut_down_(ust) = v^units_on_(ust-1) \n forall u in unit \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_down_time","page":"Constraints","title":"Minimum down time","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to the minimum up time constraint, a minimum time that a unit needs to remain offline after a shut down can be imposed by defining the min_down_time parameter. This will trigger the generation of the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n p^number_of_units_(ust) + v^units_invested_available_(ust) - v^units_on_(ust) \n - sum_n v^nonspin_units_started_up_(unst) \n geq\nsum_t=t-p^min_down_time_(ust) + 1^t\nv^units_shut_down_(ust) \n forall u in indices(p^min_down_time)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also number_of_units, min_down_time.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_up_time","page":"Constraints","title":"Minimum up time","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to the minimum down time constraint, a minimum time that a unit needs to remain online after a start up can be imposed by defining the min_up_time parameter. This will trigger the generation of the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_on_(ust) - sum_n v^nonspin_units_shut_down_(unst) \n geq\nsum_t=t-p^min_up_time_(ust) +1 ^t\nv^units_started_up_(ust) \n forall u in indices(p^min_up_time)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_up_time","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Ramping-constraints","page":"Constraints","title":"Ramping constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To include ramping and reserve constraints, it is a pre requisite that minimum operating points and capacity constraints are enforced as described.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For dispatchable units, additional ramping constraints can be introduced. For setting up ramping characteristics of units see Ramping.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ramp_up","page":"Constraints","title":"Ramp up limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the increase of unit_flow over a time period of one duration_unit according to the start_up_limit and ramp_up_limit parameter values.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right \n - sum_\n n in ng\n\nv^unit_flow_(undst-1) cdot left neg p^is_reserve_node_(n) right \n + sum_\n n in ng\n\nv^unit_flow_(undst) cdot left p^is_reserve_node_(n) land p^upward_reserve_(n) right \n le ( \n qquad left(p^start_up_limit_(ungdst) - p^minimum_operating_point_(ungdst)\n- p^ramp_up_limit_(ungdst)right) cdot v^units_started_up_(ust) \n qquad + left(p^minimum_operating_point_(ungdst) + p^ramp_up_limit_(ungdst)right)\ncdot v^units_on_(ust) \n qquad - p^minimum_operating_point_(ungdst) cdot v^units_on_(ust-1) \n ) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) cdot Delta t \n forall (ungd) in indices(p^ramp_up_limit) cup indices(p^start_up_limit) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, upward_reserve, unit_capacity, unit_conv_cap_to_flow, ramp_up_limit, start_up_limit, minimum_operating_point.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ramp_down","page":"Constraints","title":"Ramp down limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the decrease of unit_flow over a time period of one duration_unit according to the shut_down_limit and ramp_down_limit parameter values.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst-1) cdot left neg p^is_reserve_node_(n) right \n - sum_\n n in ng\n\nv^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right \n + sum_\n n in ng\n\nv^unit_flow_(undst) cdot left p^is_reserve_node_(n) land p^downward_reserve_(n) right \n le ( \n qquad left(p^shut_down_limit_(ungdst) - p^minimum_operating_point_(ungdst) - p^ramp_down_limit_(ungdst)right) cdot v^units_shut_down_(ust) \n qquad + left(p^minimum_operating_point_(ungdst) + p^ramp_down_limit_(ungdst)right) cdot v^units_on_(ust-1) \n qquad - p^minimum_operating_point_(ungdst) cdot v^units_on_(ust) \n ) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) cdot Delta t \n forall (ungd) in indices(p^ramp_down_limit) cup indices(p^shut_down_limit) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, downward_reserve, unit_capacity, unit_conv_cap_to_flow, ramp_down_limit, shut_down_limit, minimum_operating_point.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Reserve-constraints","page":"Constraints","title":"Reserve constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_res_minimum_node_state","page":"Constraints","title":"Constraint on minimum node state for reserve provision","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-11-20: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Operating-segments","page":"Constraints","title":"Operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_operating_point_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the maximum number of each activated segment unit_flow_op_active cannot be higher than the number of online units. This constraint is activated only when parameter ordered_unit_flow_op is set true.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_active_(undopst) leq v^units_on_(ust) \n forall (und) in indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 1 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_operating_point_rank","page":"Constraints","title":"Rank operating segments as per the index of operating points","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Rank operating segments by enforcing that the variable unit_flow_op_active of operating point i can only be active if previous operating point i-1 is also active. The first segment does not need this constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_active_(undopst) leq v^unit_flow_op_active_(undop-1st) \n forall (und) in indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 2 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"If the segments of a unit_flow, i.e. unit_flow_op is not ordered according to the rank of the unit_flow's operating_points (parameter ordered_unit_flow_op is false), the operating segment variable unit_flow_op is only bounded by the difference between successive operating_points adjusted for available capacity. If the order is enforced on the segments (parameter ordered_unit_flow_op is true), unit_flow_op can only be active if the segment is active (variable unit_flow_op_active is true) besides being bounded by the segment capacity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_(u n d op s t) \n leq p^unit_capacity_(u n d s t) cdot p^unit_conv_cap_to_flow_(u n d s t) cdot p^unit_availability_factor_(u s t) \n cdot left( p^operating_points_(u n d op s t)\n- begincases \n p^operating_points_(u n op-1 s t) textif op 1\n 0 textotherwise\nendcases right) \n cdot begincases\n v^unit_flow_op_active_(undopst) textif p^ordered_unit_flow_op_(ust) \n v^units_on_(ust) textotherwise\nendcases \n forall (und) in indices(p^unit_capacity) cup indices(p^operating_points) \n forall op in 1 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_capacity, unit_conv_cap_to_flow, unit_availability_factor, operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_rank","page":"Constraints","title":"Bounding operating segments to use up its own capacity for activating the next segment","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Enforce the operating point flow variable unit_flow_op at operating point i to use its full capacity if the subsequent operating point i+1 is active if parameter ordered_unit_flow_op is set true. The last segment does not need this constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op(u n d op s t) \n geq p^unit_capacity_(u n d s t) cdot p^unit_conv_cap_to_flow_(u n d s t) \n cdot left(p^operating_points_(u n op s t) - begincases \n p^operating_points_(u n op-1 s t) textif op 1 \n 0 textotherwise \nendcases right) \n cdot v^unit_flow_op_active_(u n d op+1 s t) \n forall (und) in indices(p^unit_capacity) cup indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 1 ldots leftp^operating_points_(und)right - 1 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_capacity, unit_conv_cap_to_flow, operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_sum","page":"Constraints","title":"Bounding unit flows by summing over operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"unit_flow is constrained to be the sum of all operating segment variables, unit_flow_op","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_(u n d s t) = sum_op=1^leftp^operating_points_(und)right v^unit_flow_op_(u n d op s t) \n forall (und) in indices(p^operating_points) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_pw_heat_rate","page":"Constraints","title":"Unit piecewise incremental heat rate","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Implements a standard piecewise linear heat-rate function where unit_flow from a (input fuel consumption) node is equal to the sum over operating point segments of unit_flow_op to a (output electricity node) node times the corresponding incremental_heat_rate.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_(u n_in d s t) \n = sum_op=1^leftp^operating_points_(und)right p^unit_incremental_heat_rate_(u n_in n_out op s t)\ncdot v^unit_flow_op_(u n_out d op s t) \n + p^unit_idle_heat_rate_(u n_in n_out s t) cdot v^units_on_(u s t) \n + p^unit_start_flow_(u n_in n_out s t) cdot v^units_started_up_(u s t) \n forall (un_inn_out) in indices(p^unit_incremental_heat_rate) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_incremental_heat_rate, unit_idle_heat_rate, unit_start_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Bounds-on-commodity-flows","page":"Constraints","title":"Bounds on commodity flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_total_cumulated_unit_flow","page":"Constraints","title":"Bound on cumulated unit flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To impose a limit on the cumulative amount of certain commodity flows, a cumulative bound can be set by defining one of the following parameters:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"max_total_cumulated_unit_flow_from_node\nmin_total_cumulated_unit_flow_from_node\nmax_total_cumulated_unit_flow_to_node\nmin_total_cumulated_unit_flow_to_node","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"A maximum cumulated flow restriction can for example be used to limit emissions or consumption of a certain commodity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_u in ug n in ng v^unit_flow_(undst) leq p^max_total_cumulated_unit_flow_from_node_(ugngd) \n forall (ugngd) in indices(p^max_total_cumulated_unit_flow_from_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) geq p^min_total_cumulated_unit_flow_from_node_(ugngd) \n forall (ugngd) in indices(p^min_total_cumulated_unit_flow_from_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) leq p^max_total_cumulated_unit_flow_to_node_(ugngd) \n forall (ugngd) in indices(p^max_total_cumulated_unit_flow_to_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) geq p^min_total_cumulated_unit_flow_to_node_(ugngd) \n forall (ugngd) in indices(p^min_total_cumulated_unit_flow_to_node) forall s \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Network-constraints","page":"Constraints","title":"Network constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#static-constraints-connection","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_capacity","page":"Constraints","title":"Capacity constraint on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In a multi-commodity setting, there can be different commodities entering/leaving a certain connection. These can be energy-related commodities (e.g., electricity, natural gas, etc.), emissions, or other commodities (e.g., water, steel). The connection_capacity should be specified for at least one connection__to_node or connection__from_node relationship, in order to trigger a constraint on the maximum commodity flows to this location in each time step. When desirable, the capacity can be specified for a group of nodes (e.g. combined capacity for multiple products).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\nn in ng\n v^connection_flow_(connndst)\n- sum_\nn in ng\n v^connection_flow_(connnreverse(d)st) \n = p^connection_capacity_(connngdst) cdot p^connection_availability_factor_(connst) cdot p^connection_conv_cap_to_flow_(connngdst) \n cdot begincases \n v^connections_invested_available_(connst) textif p^candidate_connections_(connst) geq 1 \n 1 textotherwise \nendcases \n forall (connngd) in indices(p^connection_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_capacity, connection_availability_factor, connection_conv_cap_to_flow, candidate_connections","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nFor situations where the same connection handles flows to multiple nodes with different temporal resolutions, the constraint is only generated for the lowest resolution, and only the average of the higher resolution flow is constrained. In other words, what gets constrained is the \"average power\" (e.g. MWh/h) rather than the \"instantaneous power\" (e.g. MW). If instantaneous power needs to be constrained as well, then connection_capacity needs to be specified separately for each node served by the connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe conversion factor connection_conv_cap_to_flow has a default value of 1, but can be adjusted in case the unit of measurement for the capacity is different to the connection flows unit of measurement.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_out_in_connection_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"By defining the parameters fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow or min_ratio_out_in_connection_flow, a ratio can be set between outgoing and incoming flows from and to a connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The constraint below is written for fix_ratio_out_in_connection_flow, but equivalent formulations exist for the other two cases.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_out v^connection_flow_(connnfrom_nodest) \n = \n p^fix_ratio_out_in_connection_flow_(conn ng_out ng_inst)\ncdot sum_n in ng_in v^connection_flow_(connnto_nodest) \n forall (conn ng_out ng_in) in indices(p^fix_ratio_out_in_connection_flow) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nIf any of the above mentioned ratio parameters is specified for a node group, then the ratio is enforced over the sum of flows from or to that group. In this case, there remains a degree of freedom regarding the composition of flows within the group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fix_ratio_out_in_connection_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Specific-network-representation","page":"Constraints","title":"Specific network representation","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In the following, the different specific network representations are introduced. While the Static constraints find application in any of the different networks, the following equations are specific to the discussed use cases. Currently, SpineOpt incorporated equations for pressure driven gas networks, nodal lossless DC power flows and PTDF based lossless DC power flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#pressure-driven-gas-transfer-math","page":"Constraints","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For gas pipelines it can be relevant a pressure driven gas transfer can be modelled, i.e. to account for linepack flexibility. Generally speaking, the main challenges related to pressure driven gas transfers are the non-convexities associated with the Weymouth equation. In SpineOpt, a convexified MILP representation has been implemented, which as been presented in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. The approximation approach is based on the Taylor series expansion around fixed pressure points.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In addition to the already known variables, such as connection_flow and node_state, the start and end points of a gas pipeline connection are associated with the variable node_pressure. The variable is triggered by the has_pressure parameter. For more details on how to set up a gas pipeline, see also the advanced concept section on pressure driven gas transfer.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_max_node_pressure","page":"Constraints","title":"Maximum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose an upper limit on the maximum pressure at a node the parameter max_node_pressure can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sum_n in ng v^node_pressure_(nst) leq p^max_node_pressure_(ngst)\nquad forall (ng) in indices(p^max_node_pressure) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter max_node_pressure can also be defined on a node group, in order to impose an upper limit on the aggregated node_pressure within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_node_pressure.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_node_pressure","page":"Constraints","title":"Minimum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose a lower limit on the pressure at a node the parameter min_node_pressure can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sum_n in ng v^node_pressure_(nst) geq p^min_node_pressure_(ngst)\nquad forall (ng) in indices(p^min_node_pressure) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter min_node_pressure can also be defined on a node group, in order to impose a lower limit on the aggregated node_pressure within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_node_pressure.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_compression_factor","page":"Constraints","title":"Constraint on the pressure ratio between two nodes","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"If a compression station is located in between two nodes, the connection is considered to be active and a compression ratio between the two nodes can be imposed. The parameter compression_factor needs to be defined on a connection__node__node relationship, where the first node corresponds the origin node, before the compression, while the second node corresponds to the destination node, after compression. The existence of this parameter will trigger the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng2 v^node_pressure_(nst) leq p^compression_factor_(connng1ng2st) cdot sum_n in ng1 v^node_pressure_(nst) \n forall (connng1ng2) in indices(p^compression_factor) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also compression_factor.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_fixed_node_pressure_point","page":"Constraints","title":"Outer approximation through fixed pressure points","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The Weymouth equation relates the average flows through a connection to the difference between the adjacent squared node pressures.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\n left(\n v^connection_flow_(conn n_origfrom_nodest)\n + v^connection_flow_(conn n_destto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_destfrom_nodest)\n + v^connection_flow_(conn n_origto_nodest)\n right)\nright)\n\n cdot left\n left(\n v^connection_flow_(conn n_origfrom_nodest)\n + v^connection_flow_(conn n_destto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_destfrom_nodest)\n + v^connection_flow_(conn n_origto_nodest)\n right)\nright\n\n = 4 cdot K_(conn) cdot left(\n left(v^node_pressure_(n_origst)right)^2 - left(v^node_pressure_(n_destst)right)^2\nright) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where K corresponds to the natural gas flow constant.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The above can be rewritten as","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\n- left(v^connection_flow_(conn n_destfrom_nodest) + v^connection_flow_(conn n_origto_nodest)right)\nright)\n = 2 cdot sqrt\n K_(conn)\n cdot left(\n left(v^node_pressure_(n_origst)right)^2 - left(v^node_pressure_(n_destst)right)^2\n right)\n \n textif left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\nright) 0\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"and","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\n left(\n v^connection_flow_(conn n_destfrom_nodest) + v^connection_flow_(conn n_origto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\n right)\nright) \n = 2 cdot sqrt\n K_(conn) cdot left(\n left(v^node_pressure_(n_destst)right)^2 - left(v^node_pressure_(n_origst)right)^2\n right)\n \n textif left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\nright) 0\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The cone described by the Weymouth equation can be outer approximated by a number of tangent planes, using a set of fixed pressure points, as illustrated in Schwele - Integration of Electricity, Natural Gas and Heat Systems With Market-based Coordination. The big M method is used to replace the sign function.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The linearized version of the Weymouth equation implemented in SpineOpt is given as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n \nleft\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\nmiddle2 \nright\n\n leq p^fixed_pressure_constant_1_(connn_orign_destjst) cdot v^node_pressure_(n_origst) \n - p^fixed_pressure_constant_0_(connn_orign_destjst) cdot v^node_pressure_(n_destst) \n + p^big_m cdot left(1 - v^binary_gas_connection_flow_(conn n_dest to_node s t)right) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall j in left1 ldots left p^fixed_pressure_constant_1_(conn n_orig n_dest) right right\np^fixed_pressure_constant_1_(conn n_orig n_dest j) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 should be defined. For each considered fixed pressure point, they can be calculated as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n p^fixed_pressure_constant_1_(connn_orign_destj) =\n left K_(conn) cdot p^fixed_pressure_(n_origj) middle sqrt\n left(p^fixed_pressure_(n_origj)right)^2 - left(p^fixed_pressure_(n_destj)right)^2\n right \n p^fixed_pressure_constant_0_(connn_orign_destj) =\n left K_(conn) cdot p^fixed_pressure_(n_destj) middle sqrt\n left(p^fixed_pressure_(n_origj)right)^2 - left(p^fixed_pressure_(n_destj)right)^2\n right \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where p^fixed_pressure_(nj) is the fix pressure for node n and point j.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The big_m parameter combined with the variable binary_gas_connection_flow together with the equations on unitary gas flow and on the maximum gas flow ensure that the bound on the average flow through the fixed pressure points becomes active, if the flow is in a positive direction for the observed set of connection, node1 and node2.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fixed_pressure_constant_1, fixed_pressure_constant_0, big_m.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_unitary_gas_flow","page":"Constraints","title":"Enforcing unidirectional flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The flow through a connection can only be in one direction at at time. Whether a flow is active in a certain direction is indicated by the binary_gas_connection_flow variable, which takes a value of 1 if the direction of flow is positive. To ensure that the binary_gas_connection_flow in the opposite direction then takes the value 0, the following constraint is enforced:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^binary_gas_connection_flow_(conn n_orig to_node s t) \n = 1 - v^binary_gas_connection_flow_(conn n_dest to_node s t) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_gas_capacity","page":"Constraints","title":"Gas connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To enforce that the averge flow of a connection is only in one direction, the flow in the opposite direction is forced to be 0 by the following equation. For the connection flow in the direction of flow the parameter big_m should be chosen large enough not to become binding.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n \nleft\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\nmiddle2 \nright\n\n = p^big_m cdot v^binary_gas_connection_flow_(conn n_dest to_node s t) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also p^{fixed_pressure_constant_1}, big_m.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storage_line_pack","page":"Constraints","title":"Linepack storage flexibility","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to account for linepack flexibility, i.e. storage capability of a connection, the linepack storage is linked to the average pressure of the adjacent nodes by the following equation, triggered by the parameter connection_linepack_constant:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_state_(n_storst) = left(\n p^connection_linepack_constant_(connn_storng) middle 2\nright) cdot sum_n in ng v^node_pressure_(nst) \n forall (conn n_stor ng) in indices(p^connection_linepack_constant) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe parameter connection_linepack_constant should be defined on a connection__node__noderelationship, where the first node corresponds to the linepack storage node, whereas the second node corresponds to the node group of both start and end nodes of the pipeline.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_linepack_constant","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#nodal-lossless-DC","page":"Constraints","title":"Node-based lossless DC power flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For the implementation of the nodebased loss DC powerflow model, a new variable node_voltage_angle is introduced. See also has_voltage_angle. For further explanation on setting up a database for nodal lossless DC power flow, see the advanced concept chapter on Lossless nodal DC power flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_max_node_voltage_angle","page":"Constraints","title":"Maximum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose an upper limit on the maximum voltage angle at a node the parameter max_voltage_angle can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng v^node_voltage_angle_(nst) geq p^max_voltage_angle_(ngst) \n forall ng in indices(p^max_voltage_angle) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter max_voltage_angle can also be defined on a node group, in order to impose an upper limit on the aggregated node_voltage_angle within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_voltage_angle.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_node_voltage_angle","page":"Constraints","title":"Minimum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose a lower limit on the voltage angle at a node the parameter min_voltage_angle can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng v^node_voltage_angle_(nst) leq p^min_voltage_angle_(ngst) \n forall ng in indices(p^min_voltage_angle) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter min_voltage_angle can also be defined on a node group, in order to impose a lower limit on the aggregated node_voltage_angle within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_voltage_angle.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_voltage_angle","page":"Constraints","title":"Voltage angle to connection flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To link the flow over a connection to the voltage angles of the adjacent nodes, the following constraint is imposed. Note that this constraint is only generated if the parameter connection_reactance is defined for a connection object and if a fix_ratio_out_in_connection_flow is defined for a connection__node__node relationship involving that connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_from v^connection_flow_(connnfrom_nodest)\n- sum_n in ng_to v^connection_flow_(connnfrom_nodest)\n = \n left(p^connection_reactance_base_(connst) middle p^connection_reactance_(connst)right) \n cdot left(sum_n in ng_from v^node_voltage_angle_(nst) - sum_n in ng_to v^node_voltage_angle_(nst) right)\n forall (conn ng_to ng_from) in indices(p^fix_ratio_out_in_connection_flow)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_reactance, connection_reactance_base, fix_ratio_out_in_connection_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#PTDF-lossless-DC","page":"Constraints","title":"PTDF based DC lossless powerflow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_intact_flow_ptdf","page":"Constraints","title":"Connection intact flow PTDF","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The power transfer distribution factors are a property of the network reactances. p^ptdf_(c n) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of p^ptdf_(c n) multiplied by the net injection at that node. connection_intact_flow represents the flow on each line of the network with all candidate connections with PTDF-based flow present in the network.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_intact_flow_(c n_to to_node s t)\n- v^connection_intact_flow_(c n_to from_node s t) \n = sum_n_inj p^ptdf_(c n_inj t) cdot v^node_injection_(n_inj s t)\ncdot leftp^node_opf_type_(n_inj) neq node_opf_type_reference right\n\n forall c in connection p^is_monitored_(c) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_lodf","page":"Constraints","title":"N-1 post contingency connection flow limits","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The N-1 security constraint for the post-contingency flow on monitored connection, c_mon, upon the outage of a contingency connection, c_cont, is formed using line outage distribution factors (LODF). p^lodf_(c_con c_mon) represents the fraction of the pre-contingency flow on connection c_cont that will flow on c_mon if the former is disconnected. If connection c_cont is disconnected, the post-contingency flow on the monitored connection connection c_mon is the pre-contingency connection_flow on c_mon plus the LODF times the pre-contingency connection_flow on c_cont. This post-contingency flow should be less than the connection_emergency_capacity of c_mon.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c_mon n_mon_to to_node s t)\n- v^connection_flow_(c_mon n_mon_to from_node s t) \n + p^lodf_(c_cont c_mon) cdot left( \nv^connection_flow_(c_cont n_cont_to to_node s t)\n- v^connection_flow_(c_cont n_cont_to from_node s t)\nright) \n leq min left(\n p^connection_emergency_capacity_(c_mon n_cont_to to_node s t)\n p^connection_emergency_capacity_(c_mon n_cont_to from_nodes t)\nright) \n forall (c_mon c_cont) in connection times connection \np^is_monitored_(c_mon) land p^is_contingency_(c_cont) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments","page":"Constraints","title":"Investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-units","page":"Constraints","title":"Investments in units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_lifetime","page":"Constraints","title":"Economic lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-03: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-unit","page":"Constraints","title":"Technical lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_invested_available","page":"Constraints","title":"Available Investment Units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in units at any point in time is less than the number of investment candidate units.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_invested_available_(ust) p^candidate_units_(u) \n forall u in unit p^candidate_units_(u) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_invested_transition","page":"Constraints","title":"Investment transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"units_invested represents the point-in-time decision to invest in a unit or not, while units_invested_available represents the invested-in units that are available at a specific time. This constraint enforces the relationship between units_invested, units_invested_available and units_mothballed in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_invested_available_(ust) - v^units_invested_(ust)\n+ v^units_monthballed_(ust)\n= v^units_invested_available_(ust-1) \n forall u in unit p^candidate_units_(u) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-connections","page":"Constraints","title":"Investments in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connections_invested_available","page":"Constraints","title":"Available invested-in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in connections at any point in time is less than the number of investment candidate connections.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connections_invested_available_(cst) p^candidate_connections_(c) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connections_invested_transition","page":"Constraints","title":"Transfer of previous investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"connections_invested represents the point-in-time decision to invest in a connection or not while connections_invested_available represents the invested-in connections that are available at a specific time. This constraint enforces the relationship between connections_invested, connections_invested_available and connections_decommissioned in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connections_invested_available_(cst) - v^connections_invested_(cst)\n+ v^connections_decommissioned_(cst) \n = v^connections_invested_available_(cst-1) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_intact_flow","page":"Constraints","title":"Intact network ptdf-based flows on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Enforces the relationship between connection_intact_flow (flow with all investments assumed in force) and connection_flow. This constraint ensures that the connection_flow is connection_intact_flow plus additional flow contributions from investment connections that are not invested in.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(v^connection_flow_(c n_to from_node s t)\n- v^connection_flow_(c n_to to_node s t) right)\n- left(v^connection_intact_flow_(c n_to from_node s t)\n- v^connection_intact_flow_(c n_to to_node s t) right) \n =\n sum_c_cand p^lodf_(c_cand c) cdot leftp^candidate_connections_(c_cand) neq 0 right cdot Big( \n qquad left(\n v^connection_flow_(c_cand n_to_cand from_node s t)\n - v^connection_flow_(c_cand n_to_cand to_node s t) \nright)\n\n qquad \n- left(\n v^connection_intact_flow_(c_cand n_to_cand from_node s t)\n - v^connection_intact_flow_(c_cand n_to_cand to_node s t)\nright)\n\n Big) \n forall c in connection p^is_monitored_(c) land p^candidate_connections_(c) = 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_intact_flow_capacity","page":"Constraints","title":"Intact connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to this, limits connection_intact_flow according to connection_capacity","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\nn in ng\n v^connection_intact_flow_(connndst)\n- sum_\nn in ng\n v^connection_intact_flow_(connnreverse(d)st) \n = p^connection_capacity_(connngdst) cdot p^connection_availability_factor_(connst)\ncdot p^connection_conv_cap_to_flow_(connngdst) \n forall (connngd) in indices(p^connection_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_out_in_connection_intact_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming intact flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For PTDF-based lossless DC power flow, ensures that the output flow to the to_node equals the input flow from the from_node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned \n v^connection_intact_flow_(c n_out d_to s t)\n=\nv^connection_intact_flow_(c n_in d_from s t) \n forall c in connection p^is_monitored_(c) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_candidate_connection_flow_lb","page":"Constraints","title":"Lower bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For candidate connections with PTDF-based poweflow, together with this, this constraint ensures that connection_flow is zero if the candidate connection is not invested-in and equals connection_intact_flow otherwise.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c n d s t) \n leq \n v^connection_intact_flow_(c n d s t)\n- p^connection_capacity_(c n d s t) cdot left(\n p^candidate_connections_(c s t) - v^connections_invested_available_(c s t) right) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_candidate_connection_flow_ub","page":"Constraints","title":"Upper bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For candidate connections with PTDF-based poweflow, together with this, this constraint ensures that connection_flow is zero if the candidate connection is not invested-in and equals connection_intact_flow otherwise.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c n d s t) \nleq\nv^connection_intact_flow_(c n d s t) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_lifetime","page":"Constraints","title":"Economic lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-connection","page":"Constraints","title":"Technical lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-storages","page":"Constraints","title":"Investments in storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Note: can we actually invest in nodes that are not storages? (e.g. new location)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storages_invested_available","page":"Constraints","title":"Available invested storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in storages at node n at any point in time is less than the number of investment candidate storages at that node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^storages_invested_available_(nst)\nleq p^candidate_storages_(nst) \n forall n in node p^candidate_storages_(n) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storages_invested_transition","page":"Constraints","title":"Storage capacity transfer ","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"storages_invested represents the point-in-time decision to invest in storage at a node n or not, while storages_invested_available represents the invested-in storages that are available at a node at a specific time. This constraint enforces the relationship between storages_invested, storages_invested_available and storages_decommissioned in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^storages_invested_available_(nst) - v^storages_invested_(nst)\n+ v^storages_decommissioned_(nst)\n= v^storages_invested_available_(nst-1) \n forall n in node p^candidate_storages_(n) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storage_lifetime","page":"Constraints","title":"Economic lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-storage","page":"Constraints","title":"Technical lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Capacity-transfer","page":"Constraints","title":"Capacity transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Early-retirement-of-capacity","page":"Constraints","title":"Early retirement of capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#User-constraints","page":"Constraints","title":"User constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_user_constraint","page":"Constraints","title":"User constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This is a generic data-driven custom constraint which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant term of the constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_u n left\n beginaligned \n sum_op=1^left p^operating_points_(u) right p^unit_flow_coefficient_(unopucst)\n cdot v^unit_flow_op_(undopst) textif left p^operating_points_(u) right 1 \n p^unit_flow_coefficient_(unucst) cdot v^unit_flow_(undst) textotherwise \n endaligned\n right\n\n+sum_u p^units_started_up_coefficient_(uucst) cdot v^units_started_up_(ust) \n+sum_u p^units_on_coefficient_(uucst) cdot v^units_on_(ust) \n+sum_c p^connection_flow_coefficient_(cnucst) cdot v^connection_flow_(cndst) \n+sum_n p^node_state_coefficient_(nucst) cdot v^node_state_(nst) \n+sum_n p^demand_coefficient_(nucst) cdot p^demand_(nst) \n begincases \n = textif p^constraint_sense_(uc) text= ==\n geq textif p^constraint_sense_(uc) text= =\n leq textif p^constraint_sense_(uc) text= ==\n endcases\n+p^right_hand_side_(ucts)\nforall uc in user_constraint \nforall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#benders_decomposition","page":"Constraints","title":"Benders decomposition","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This section describes the high-level formulation of the benders-decomposed problem.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Taking the simple example of minimising capacity and operating cost for a fleet of units with a linear cost coefficient p^operational_cost:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sum_ust left( p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ sum_nd p^operational_cost_(undst) cdot v^unit_flow_(u n d s t) right) \nst \n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + v^units_invested_available_(u s t)\nright) quad forall u in unit n in node s t\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"So this is a single problem that can't be decoupled over t because the investment variables units_invested_available couple the timesteps together. If units_invested_available were a constant in the problem, then all t's could be solved individually. This is the basic idea in Benders decomposition. We decompose the problem into a master problem and sub problems with the master problem optimising the coupling investment variables which are treated as constants in the sub problems.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The master problem is built by replacing the operational costs (which will be minimised in the sub problem) by a new decision variable, v^sp_objective:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust) + v^sp_objective \nst \n v^sp_objective geq 0\nendaligned\n","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The solution to this problem yields values for the investment variables which are fixed as p^units_invested_available in the sub problem and will be zero in the first iteration.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The sub problem for benders iteration b then becomes :","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sp_obj_b = sum_undst p^operational_cost_(undst) cdot v^unit_flow_(u n d s t)\nst\n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + p^units_invested_available_(b u s t)\nright) \n qquad forall u in unit n in node st qquad mu_(bust)\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This sub problem can be solved individually for each t. This is pretty trivial in this small example but if we consider a single t to be a single rolling horizon instead, decoupling the investment variables means that each rolling horizon can be solved individually rather than having to solve the entire model horizon as a single problem.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"mu_(bust) is the marginal value of the capacity constraint for benders iteration b and can be interpreted as the decrease in the objective function for an additional MW of flow from unit u (in scenario s at time t). Thus, an upper bound on the sub problem objective function is obtained as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sp_obj_b + sum_undst mu_(bust) cdot p^unit_capacity_(undst) \ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The above is added to the master problem for the next iteration as a new constraint, called a Benders cut, thus becoming:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ v^sp_objective \n\nst \n\n v^sp_objective geq sp_obj_b \n quad + sum_undst mu_(bust) cdot p^unit_capacity_(undst)\ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right) quad forall b \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Note the benders cuts are added as inequalities because they represent an upper bound on the value we are going to get for the sub problem objective function by adjusting the master problem variables in that benders iteration. If we consider the example of renewable generation - because it's marginal cost is zero, on the first benders iteration, it could look like there would be a lot of value in increasing the capacity because of the marginal values from the sub problems. However, when the capacity variables are increased accordingly and curtailment occurs in the sub-problems, the marginal values will be zero when curtailment occurs and so, other resources may become optimal in subsequent iterations.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This is a simple example but it illustrates the general strategy. The algorithm pseudo code looks something like this:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":" initialise master problem\n initialise sub problem\n solve first master problem\n create master problem variable time series\n solve rolling spine opt model\n save zipped marginal values\n while master problem not converged\n update master problem\n solve master problem\n update master problem variable timeseries for benders iteration b\n rewind sub problem\n update sub problem\n solve rolling spine opt model\n save zipped marginal values\n test for convergence\n end","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_mp_any_invested_cuts","page":"Constraints","title":"Benders cuts","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The benders cuts for the problem including all investments in candidate connections, storages and units is given below.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^sp_objective \n geq \n p^sp_obj_(b) + \n sum_ust p^units_invested_available_mv_(bust)\ncdot left( v^units_invested_available_(ust) - p^units_invested_available_(ust) right) \n + sum_cst p^connections_invested_available_mv_(bcst)\ncdot left( v^connections_invested_available_(cst) - p^connections_invested_available_(cst) right) \n + sum_nst p^storages_invested_available_mv_(bnst)\ncdot left( v^storages_invested_available_(nst) - p^storages_invested_available_(nst) right) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p^sp_obj_(b) is the sub problem objective function value in benders iteration b,\np^units_invested_available_mv is the reduced cost of the units_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a unit of this type, \np^connections_invested_available_mv is the reduced cost of the connections_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a connection of this type, \np^storages_invested_available_mv is the reduced cost of the storages_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a storage node of this type, \np^units_invested_available is the value of the fixed sub problem variable units_invested_available in benders iteration b, \np^connections_invested_available is the value of the fixed sub problem variable connections_invested_available in benders iteration b and \np^storages_invested_available is the value of the fixed sub problem variable storages_invested_available in benders iteration b","category":"page"},{"location":"concept_reference/fix_storages_invested_available/","page":"-","title":"-","text":"Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/fix_storages_invested_available/","page":"-","title":"-","text":"See also candidate_storages and Investment Optimization","category":"page"},{"location":"concept_reference/connection_availability_factor/","page":"-","title":"-","text":"To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.","category":"page"},{"location":"concept_reference/connection__from_node/","page":"-","title":"-","text":"connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/duration_unit_list/","page":"-","title":"-","text":"The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.","category":"page"},{"location":"concept_reference/commodity_physics_list/","page":"-","title":"-","text":"commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details","category":"page"},{"location":"concept_reference/connection_investment_variable_type/","page":"-","title":"-","text":"The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.","category":"page"},{"location":"concept_reference/connection_investment_variable_type/","page":"-","title":"-","text":"The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_in/","page":"-","title":"-","text":"The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/model__report/","page":"-","title":"-","text":"The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_in/","page":"-","title":"-","text":"The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/fix_node_voltage_angle/","page":"-","title":"-","text":"For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.","category":"page"},{"location":"how_to/print_the_model/#How-to-print-the-model","page":"Print the model","title":"How to print the model","text":"","category":"section"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"As the SpineOpt model formulation is quite complex and can change depending on a few parameters (some parts of the formulation can be activated or deactivated), it can be useful to print the model that SpineOpt sends to JuMP. There are a few ways to do this.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"The model that SpineOpt sends to JuMP can be saved to a file. It is not the nicest file to read but at the very least you can find the used variables and parameter values.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"To write that file you need to set the write_mps_file parameter of the model object to write_mps_always.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"SpineOpt will write the file to the working directory. If you are using Spine Toolbox that working directory will be the Spine Toolbox work folder which is typically in your user directory e.g. C:\\Users\\username\\.spinetoolbox\\work\\run_spineopt_gibberish_toolbox\\model_diagnostics.mps","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"An alternative approach is to directly use the write_model_file(m, filename) command in which m is a reference to your model and filename is the filename you want the model file written to.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"m can be obtained from the call to run_spineopt(). In Spine Toolbox, more particularly the run_SpineOpt tool, you will have m=run_spineopt(). That means that you can call write_model_file(m,filename) in the console once SpineOpt has finished executing and the console remains open.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"In either case, here are some tips if you are using this file for debugging. The file can be very large so often it is helpful to create a minimum example of your model with only one or two timesteps. Also, in the call to run_spineopt() you can add the keyword argument optimize=false so it will just build the model and not attempt to solve it.","category":"page"},{"location":"concept_reference/overwrite_results_on_rolling/","page":"-","title":"-","text":"The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.","category":"page"},{"location":"concept_reference/overwrite_results_on_rolling/","page":"-","title":"-","text":"If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_out/","page":"-","title":"-","text":"The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/node_state_min/","page":"-","title":"-","text":"The node_state_min parameter sets the lower bound for the node_state variable, if one has been enabled by the has_state parameter. For reserve nodes with minimum_reserve_activation_time, the node_state_min is considered also via a special constraint.","category":"page"},{"location":"concept_reference/node_slack_penalty/","page":"-","title":"-","text":"node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.","category":"page"},{"location":"concept_reference/downward_reserve/","page":"-","title":"-","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/node_opf_type/","page":"-","title":"-","text":"Used to identify the reference node (or slack bus) when ptdf based dc load flow is enabled (commodity_physics set to commodity_physics_ptdf or commodity_physics_lodf. To identify the reference node, set node_opf_type = :node_opf_type_reference","category":"page"},{"location":"concept_reference/node_opf_type/","page":"-","title":"-","text":"See also powerflow.","category":"page"},{"location":"concept_reference/balance_type/","page":"-","title":"-","text":"The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.","category":"page"},{"location":"concept_reference/balance_type/","page":"-","title":"-","text":"The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.","category":"page"},{"location":"advanced_concepts/decomposition/#Decomposition","page":"Decomposition","title":"Decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Decomposition approaches take advantage of certain problem structures to separate them into multiple related problems which are each more easily solved. Decomposition also allows us to do the inverse, which is to combine independent problems into a single problem, where each can be solved separately but with communication between them (e.g. investments and operations problems)","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Decomposition thus allows us to do a number of things","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Solve larger problems which are otherwise intractable\nInclude more detail in problems which otherwise need to be simplified\nCombine related problems (e.g. investments/operations) in a more scientific way (rather than ad-hoc).\nEmploy parallel computing methods to solve multiple problems simultaneously.","category":"page"},{"location":"advanced_concepts/decomposition/#High-level-Decomposition-Algorithm","page":"Decomposition","title":"High-level Decomposition Algorithm","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"The high-level algorithm is described below. For a more detailed description please see Benders decomposition","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Model initialisation (preprocessdatastructure, generate temporal structures etc.)\nFor each benders_iteration\nSolve master problem\nProcess master-problem solution:\nset units_invested_bi(unit=u) equal to the investment variables solution from the master problem\nSolve operations problem loop\nProcess operations sub-problem\nset units_on_mv(unit=u) equal to the marginal value of the units_on bound constraint\nTest for convergence\nUpdate master problem\nAdd Benders cuts constraints\nRewind operations problem\nNext benders iteration","category":"page"},{"location":"advanced_concepts/decomposition/#Duals-and-reduced-costs-calculation-for-decomposition","page":"Decomposition","title":"Duals and reduced costs calculation for decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"The marginal values above are computed as the reduced costs of relevant optimisation variables. However, the dual solution to a MIP problem is not well defined. The standard approach to obtaining marginal values from a MIP model is to relax the integer variables, fix them to their last solution value and re-solve the problem as an LP. This is the standard approach in energy system modelling to obtain energy prices. However, although this is the standard approach, it does need to be used with caution. The main hazard associated with inferring duals in this way is that the impact on costs of an investment may be overstated. However, since these duals are used in Benders decomposition to obtain a lower bound on costs (i.e. the maximum potential value from an investment), this is ok and can be \"corrected\" in the next iteration. And finally, the benders gap will tell us how close our decomposed problem is to the optimal global solution.","category":"page"},{"location":"advanced_concepts/decomposition/#Reporting-dual-values-and-reduced-costs","page":"Decomposition","title":"Reporting dual values and reduced costs","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's relaxed problem marginal value will be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"To report the reduced cost for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of units_on in the final fixed LP to be written to the output db.","category":"page"},{"location":"advanced_concepts/decomposition/#Using-Decomposition","page":"Decomposition","title":"Using Decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Assuming one has set up a conventional investments problem as described in Investment Optimization the following additional steps are required to utilise the decomposition framework:","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Set the model_type parameter for your model to spineopt_benders.\nSpecify max_gap parameter for your model - This determines the master problem convergence criterion for the relative benders gap. A value of 0.05 will represent a relative benders gap of 5%.\nSpecify the max_iterations parameter for your model - This determines the master problem convergence criterion for the number of iterations. A value of 10 could be appropriate but this is highly dependent on the size and nature of the problem.","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Once the above is set, all investment decisions in the model are automatically decomposed and optimised in a Benders master problem. This behaviour may change in the future to allow some investment decisions to be optimised in the operations problem and some optimised in the master problem as desired.","category":"page"},{"location":"advanced_concepts/reserves/#Reserves","page":"Reserves","title":"Reserves","text":"","category":"section"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"To include a requirement of reserve provision in a model, SpineOpt offers the possibility of creating reserve nodes. Of course reserve provision is different from regular operation, because the reserved capacity does not actually get activated. In this section we will take a look at the things that are particular for a reserve node.","category":"page"},{"location":"advanced_concepts/reserves/#Defining-a-reserve-node","page":"Reserves","title":"Defining a reserve node","text":"","category":"section"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"To define a reserve node, the following parameters have to be defined for the relevant node:","category":"page"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"is_reserve_node : this boolean parameter indicates that this node is a reserve node.\nupward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns upward reserves.\ndownward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns downward reserves.\nreserve_procurement_cost: (optional) this parameter indicates the procurement cost of a unit for a certain reserve product and can be define on a unit__to_node or unit__from_node relationship.","category":"page"},{"location":"concept_reference/connections_invested_mga/","page":"-","title":"-","text":"The connections_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of connections_invested_mga is set to true, investment decisions in this connection, or group of connections, will be included in the MGA algorithm.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Hydro-Power-Planning","page":"Two hydro plants","title":"Hydro Power Planning","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Welcome to this Spine Toolbox tutorial for building hydro power planning models. The tutorial guides you through the implementation of different ways of modelling hydrodologically-coupled hydropower systems.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Introduction","page":"Two hydro plants","title":"Introduction","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"This tutorial aims at demonstrating how we can model a hydropower system in Spine (SpineOpt.jl and Spine-Toolbox) with different assumptions and goals. It starts off by setting up a simple model of system of two hydropower plants and gradually introduces additional features. The goal of the model is to capture the combined operation of two hydropower plants (Språnget and Fallet) that operate on the same river as shown in the picture bellow. Each power plant has its own reservoir and generates electricity by discharging water. The plants might need to spill water, i.e., release water from their reservoirs without generating electricity, for various reasons. The water discharged or spilled by the upstream power plant follows the river route and becomes available to the downstream power plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: A system of two hydropower plants.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"A system of two hydropower plants","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing-the-spineopt-database-template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nJust remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Two_hydro’) in the corresponding step, so to not mix up the Spine Toolbox projects!","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"That is all you need at the moment, you can now start inserting the data.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Setting-up-a-Basic-Hydropower-Model","page":"Two hydro plants","title":"Setting up a Basic Hydropower Model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"For creating a SpineOpt model you need to create Objects, Relationships (associating the objects), and in some cases, parameters values accompanying them. To do this, open the input database using the Spine DB Editor (double click on the input database in the Design View pane of Spine Toolbox).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nTo save your work in the Spine DB Editor you need to commit your changes (please check the Simple System tutorial for how to do that). As a good practice, you should commit often as you enter the data in the model to avoid data loss.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-objects","page":"Two hydro plants","title":"Defining objects","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Commodities","page":"Two hydro plants","title":"Commodities","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Since we are modelling a hydropower system we will have to define two commodities, water and electricity. In the Spine DB editor, locate the Object tree, expand the root element if required, right click on the commodity class, and select Add objects from the context menu. In the Add objects dialogue that should pop up, enter the object names for the commodities as you see in the image below and then press Ok.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining commodities.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Nodes","page":"Two hydro plants","title":"Nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Follow a similar path to add nodes, right click on the node class, and select Add objects from the context menu. In the dialogue, enter the node names as shown:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining nodes.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Nodes in SpineOpt are used to balance commodities. As you noticed, we defined two nodes for each hydropower station (water nodes) and a single electricity node. This is one possible way to model the hydropower plant operation. This will become clearer in the next steps, but in a nutshell, the upper node represents the water arriving at each plant, while the lower node represents the water that is discharged and becomes available to the next plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Connections","page":"Two hydro plants","title":"Connections","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Similarly, add connections, right click on the connection class, select Add objects from the context menu and add the following connections:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining connections.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Connections enable the nodes to interact. Since, for each plant we need to model the amount of water that is discharged and the amount that is spilled, we must define two connections accordingly. When defining relationships we shall associate the connections with the nodes.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Units","page":"Two hydro plants","title":"Units","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To convert from one type of commodity associated with one node to another, you need a unit. You guessed it! Right click on the unit class, select Add objects from the context menu and add the following units:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining units.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"We have defined one unit for each hydropower plant that converts water to electricity and an additional unit that we will use to model the income from selling the electricity production in the electricity market.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Relationships","page":"Two hydro plants","title":"Relationships","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Assinging-commodities-to-nodes","page":"Two hydro plants","title":"Assinging commodities to nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Since we have defined more than one commodities, we need to assign them to nodes. In the Spine DB editor, locate the Relationship tree, expand the root element if required, right click on the node__commodity class, and select Add relationships from the context menu. In the Add relationships dialogue, enter the following relationships as you see in the image below and then press Ok.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing node__commodity relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Associating-connections-to-nodes","page":"Two hydro plants","title":"Associating connections to nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Next step is to define the topology of flows between the nodes. To do that insert the following relationships in the connection__from_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing connection__from_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"as well as the following the following connection__node_node relationships as you see in the figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing connection__node_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing connection__node_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Placing-the-units-in-the-model","page":"Two hydro plants","title":"Placing the units in the model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To define the topology of the units and be able to introduce their parameters later on, you need to define the following relationships in the unit__from_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__from_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__from_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"in the unit__node_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__node_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__node_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"and in the unit__to_node class as you see in the following figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__to_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__to_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-the-report-outputs","page":"Two hydro plants","title":"Defining the report outputs","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To force Spine to export the optimal values of the optimization variables to the output database you need to specify them in the form of report_output relationships. Add the following relationships to the report_output class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing report outputs with report_output relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing report outputs with report_output relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Objects-and-Relationships-parameter-values","page":"Two hydro plants","title":"Objects and Relationships parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Defining-model-parameter-values","page":"Two hydro plants","title":"Defining model parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The specify modelling properties of both objects and relationships you need to introduce respective parameter values. To introduce object parameter values first select the model class in the Object tree and enter the following values in the Object parameter value pane:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining model execution parameters.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining model execution parameters.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Observe the difference between the Object parameter value and the Object parameter definition sub-panes of the Object parameter value pane. The first one is for the modeller to introduce values for specific parameters, while the second one holds the definition of all available parameters with their default values (these are overwritten when the user introduces their own values). Feel free to explore the different parameters and their default values. While entering data in each row you will also observe that, in most cases, clicking on each cell activates a drop-down list of elements that the user must choose from. In the case of the value cells, however, unless you need to input a scalar value or a string, you should right-click on the cell and select edit for specifying the data type of the parameter value. As you see in the figure above, for the first duration_unit parameter you is of type string, while the model_start and model_end parameters are of type Date time. The Date time parameters can be edited by right-clicking on the corresponding value cells, selecting Edit, and then inserting the Date time values that you see in the figure above in the Datetime field using the correct format.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-node-parameter-values","page":"Two hydro plants","title":"Defining node parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Going back to hydropower modelling, we need to specify several parameters for the nodes of the systems. In the same pane as before, but this time selecting the node class from the Object tree, we need to add the following entries:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining model execution parameters.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining model execution parameters.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Before we go through the interpretation of each parameter, click on the following link for each fix_node_state parameter (Node state Språnget, Node state Fallet), select all, copy the data and then paste them directly in the respective parameter value cell. Spine should automatically detect and input the timeseries data as a parameter value. The data type for those entries should be Timeseries as shown in the figure above. Alternatively, you can select the data type as Timeseries and manually insert the data (values with their corresponding datetimes).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To model the reservoirs of each hydropower plant, we leverage the state feature that a node can have to represent storage capability. We only need to do this for one of the two nodes that we have used to model each plant and we choose the upper level node. To define storage, we set the value of the parameter has_state as True (be careful to not set it as a string but select the boolean true value by right clicking and selecting Edit in the respective cells). This activates the storage capability of the node. Then, we need to set the capacity of the reservoir by setting the node_state_cap parameter value. Finally, we fix the initial and final values of the reservoir by setting the parameter fix_node_state to the respective values (we introduce nan values for the time steps that we don't want to impose such constraints). To model the local inflow we use the demand parameter but using the negated value of the actual inflow, due to the definition of the parameter in Spine as a demand.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-the-temporal-resolution-of-the-model","page":"Two hydro plants","title":"Defining the temporal resolution of the model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Spine automates the creation of the temporal resolution of the optimization model and even supports different temporal resolutions for different parts of the model. To define a model with an hourly resolution we select the temporal_block class in the Object tree and we set the resolution parameter value to 1h as shown in the figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the temporal resolution of the model.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the temporal resolution of the model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-connection-parameter-values","page":"Two hydro plants","title":"Defining connection parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The water that is discharged from Språnget will flow from Språnget_lower node to Fallet_upper through the Språnget_to_Fallet_disc connection, while the water that is spilled will flow from Språnget_upper directly to to Fallet_upper through the Språnget_to_Fallet_spill connection. To model this we need to select the connection__node_node class in the Relationship tree and add the following entries in the Relationship parameter value pane, as shown next:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining discharge and spillage ratio flows.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining discharge and spillage ratio flows.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-unit-parameter-values","page":"Two hydro plants","title":"Defining unit parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Similarly, for each one of the unit__from_node, unit__node_node, and unit__to_node relationship classes we need to add the the maximal water that can be discharged by each hydropower plant:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the maximal water discharge of each plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the maximal water discharge of each plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To define the income from selling the produced electricity we use the vom_cost parameter and negate the values of the electricity prices. To automatically insert the timeseries data in Spine, click on the Electricity prices timeseries, select all values, copy, and paste them, after having selected the value cell of the corresponding row. You can plot and edit the timeseries data by double clicking on the same cell afterwards:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Previewing and editing the electricity prices timeseries.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Previewing and editing the electricity prices timeseries.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Carrying on with our hydropower model we must define the conversion ratios between the nodes. Assuming that water is not \"lost\" from the upper node toward the lower node and electricity is produced with the discharged water with a given efficiency we define the following parameter values for each hydropower plant, in the unit__node_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining conversion efficiencies.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining conversion efficiencies.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Lastly, we can define the maximal electricity production of each plant by inserting the following unit__to_node relationship parameter values:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the maximal electricity production of each plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the maximal electricity production of each plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Hooray! You can now commit the database, close the Spine DB Editor and run your model! Go to the main Spine window and click on Execute (Image: image).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Examining-the-results","page":"Two hydro plants","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Select the output data store and open the Spine DB editor. To quickly plot some results, you can expand the unit class in the Object tree and select the electricity_load unit. In the Relationship parameter value pane double click on the value cell of","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | electricity_load | electricity_node | from_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"object name. This will open a plotting window from were you can also examine closer and retrieve the data, as shown in the next figure. The unit_flow variable of the electricity_load unit represents the total electricity production in the system:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Total electricity produced in the system.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Total electricity produced in the system.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Now, take to a minute to reflect on how you could retrieve the data representing the water that is discharged by each hydropower plant as shown in the next figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Water discharge of Språnget hydropower plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Water discharge of Språnget hydropower plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The right answer is that you need to select some hydropower plant (e.g., Språnget) and then double-click on the value cell of the object name","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | Språnget_pwr_plant | Språnget_lower | to_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"or","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | Språnget_pwr_plant | Språnget_upper | from_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It could be useful to also reflect on why these objects give the same results, and what do the results from the third element represent. (Hint: observe the to_ or from_ directions in the object names). As an exercise, you can try to retrieve the timeseries data for spilled water as well as the water levels at the reservoir of each hydropower plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"You can further explore the model, or make changes in the input database to observe how these affect the results, e.g., you can use different electricity prices, values for the reservoir capacity (and initialization points), as well as change the temporal resolution of the model. All you need to do is commit the changes and run your model. Every time that you run the model, your results are appended in the output database with an execution timestamp. You can however filter your results per execution, by selecting the Alternative that you want from the Alternative/Scenario tree pane. You can use the exporter too to export specific variables in an Excel sheet. Alternatively, you can export all the data of the output database by going to the main menu (Press Alt + F to display it), selecting File -> Export, then select the items that you want, click ok and export the data in Excel, or json format.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"In the following, we extend this simple hydropower system to include more elaborate modelling choices.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nIn each of the next sections, we perform incremental changes to the initial simple hydropower model. If you want to keep the database that you created, you can duplicate the database file (right-click on the input database and select Duplicate and duplicate files) and perform the changes in the new database. You need to configure the workflow accordingly in order to run the database you want (please check the Simple System tutorial for how to do that).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Maximisation-of-Stored-Water","page":"Two hydro plants","title":"Maximisation of Stored Water","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Instead of fixing the water content of the reservoirs at the end of the planning period, we can consider that the remaining water in the reservoirs has a value and then maximize the value along with the revenues for producing electricity within the planning horizon. This objective term is often called the Value of stored water and we can approximate it by assuming that this water will be used to generate electricity in the future that would be sold at a forecasted price. The water stored in the upstream hydropower plant will become also available to the downstream plant and this should be taken into account.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To model the value of stored water we need to make some additions and modifications to the initial model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"First, add a new node (see adding nodes) and give it a name (e.g., stored_water). This node will accumulate the water stored in the reservoirs at the end of the planning horizon. Associate the node with the water commodity (see node__commodity).\nAdd three more units (see adding units); two will transfer the water at the end of the planning horizon in the new node that we just added (e.g., Språnget_stored_water, Fallet_stored_water), and one will be used as a sink introducing the value of stored water in the objective function (e.g., value_stored_water).\nTo establish the topology of the new units and nodes (see adding unit relationships):\nadd one unit__from_node relationship, between the value_stored_water unit from the stored_water node, another one between the Språnget_stored_water unit from the Språnget_upper node and one for Faller_stored_water from Fallet_upper.\nadd one unit__node__node relationship between the Språnget_stored_water unit with the stored_water and Språnget_upper nodes and another one for Fallet_stored_water unit with the stored_water and Fallet_upper nodes,\nadd a unit__to_node relationship between the Fallet_stored_water and the stored_water node and another one between the Språnget_stored_water unit and the stored_water node.\nNow we need to make some changes in object parameter values.\nExtend the planning horizon of the model by one hour, i.e., change the model_end parameter value to 2021-01-02T01:00:00 (right-click on the value cell, click edit and paste the new datetime in the popup window).\nRemove the fix_node_state parameter values for the end of the optimization horizon as you seen in the following figure: double click on the value cell of the Språnget_upper and Fallet_upper nodes, select the third data row, right-click, select Remove rows, and click OK.\nAdd an electricity price for the extra hour. Enter the parameter vom_cost on the unit__from_node relationship between the electricity_node and the electricity_load and set 0 as the price of electricity for the last hour 2021-01-02T00:00:00. The price is set to zero to ensure no electricity is sold during this hour.\n(Image: Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.) Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.\nFinally, we need to add some relationship parameter values for the new units:\nAdd a vom_cost parameter value on a value_stored_water|stored_water instance of a unit__from_node relationship, as you see in the figure bellow. For the timeseries you can copy-paste the data directly from this link. If you examine the timeseries data you'll notice that we have imposed a zero cost for all the optimisation horizon, while we use an assumed future electricity value for the additional time step at the end of the horizon. \n(Image: Adding vom_cost parameter value on the value_stored_water unit.) Adding vom_cost parameter value on the value_stored_water unit.\nAdd two fix_ratio_out_in_unit_flow parameter values as you see in the figure bellow. The efficiency of Fallet_stored_water is the same as the Fallet_pwr_plant as the water in Fallet's reservoir will be used to produce electricity by the the Fallet plant only. On the other hand, the water from Språnget's reservoir will be used both by Fallet and Språnget plant, therefore we use the sum of the two efficiencies in the parameter value of Språnget_stored_water.\n(Image: Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.) Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"You can now commit your changes in the database, execute the project and examine the results! As an exercise, try to retrieve the value of stored water as it is calculated by the model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Spillage-Constraints-Minimisation-of-Spilt-Water","page":"Two hydro plants","title":"Spillage Constraints - Minimisation of Spilt Water","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It might be the case that we need to impose certain limits to the amount of water that is spilt on each time step of the planning horizon, e.g., for environmental reasons, there can be a minimum and a maximum spillage level. At the same time, to avoid wasting water that could be used for producing electricity, we could explicitly impose the spillage minimisation to be added in the objective function.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Add one unit (see adding units) to impose the spillage constraints to each plant and name it (for example Språnget_spill).\nRemove the Språnget_to_Fallet_spill connection (in the Object tree expand the connection class, right-click on Språnget_to_Fallet_spill, and the click Remove).\nTo establish the topology of the unit (see adding unit relationships):\nAdd a unit__from_node relationship, between the Språnget_spill unit from the Språnget_upper node,\nadd a unit__node__node relationship between the Språnget_spill unit with the Fallet_upper and Språnget_upper nodes,\nadd a unit__to_node relationship between the Språnget_spill and the Fallet_upper node,\nAdd the relationship parameter values for the new units:\nSet the unit_capacity (to apply a maximum), the minimum_operating_point (defined as a percentage of the unit_capacity) to impose a minimum, and the vom_cost to penalise the water that is spilt:\n(Image: Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.)\nSetting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"For the Språnget_spill unit define the fix_ratio_out_in_unit_flow parameter value of the min_spillage|Fallet_upper|Språnget_upper relationship to 1 (see adding unit relationships).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Commit your changes in the database, execute the project and examine the results! As an exercise, you can perform this process for and Fallet plant (you would also need to add another water node, downstream of Fallet).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Follow-Contracted-Load-Curve","page":"Two hydro plants","title":"Follow Contracted Load Curve","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It is often the case that a system of hydropower plants should follow a given production profile. To model this in the given system, all we have to do is set a demand in the form of a timeseries to the electricity_node.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Add the Contracted load timeseries, to the demand parameter value of the electricity_node (see adding node parameter values).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Commit your changes in the database, execute the project and examine the results!","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"This concludes the tutorial, we hope that you enjoyed building hydropower systems in Spine as much as we do!","category":"page"},{"location":"concept_reference/node__commodity/","page":"-","title":"-","text":"node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:","category":"page"},{"location":"concept_reference/node__commodity/","page":"-","title":"-","text":"To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow\nOnly connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.","category":"page"},{"location":"getting_started/archetypes/#Archetypes","page":"Archetypes","title":"Archetypes","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Archetypes are essentially ready-made templates for different aspects of SpineOpt.jl. They are intended to serve both as examples for how the data structure in SpineOpt.jl works, as well as pre-made modular parts that can be imported on top of existing model input data.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"The templates/models/basic_model_template.json contains a ready-made template for simple energy system models, with uniform time resolution and deterministic stochastic structure. Essentially, it serves as a basis for testing how the modelled system is set up, without having to worry about setting up the temporal and stochastic structures.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"The rest of the different archetypes are included under templates/archetypes in the SpineOpt.jl repository. Each archetype is stored as a .json file containing the necessary objects, relationships, and parameters to form a functioning pre-made part for a SpineOpt.jl model. The archetypes aren't completely plug-and-play, as there are always some relationships required to connect the archetype to the other input data correctly. Regardless, the following sections explain the different archetypes included in the SpineOpt.jl repository, as well as what steps the user needs to take to connect said archetype to their input data correctly.","category":"page"},{"location":"getting_started/archetypes/#Loading-the-SpineOpt-Template-and-Archetypes-into-Your-Model","page":"Archetypes","title":"Loading the SpineOpt Template and Archetypes into Your Model","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"To load the latest version of the SpineOpt template, in the Spine DB Editor, from the menu (three hirzontal bars in the top right), click on import as follows:","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"(Image: importing the SpineOpt Template)","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Change the file type to JSON and click on spineopt_template.json as follows:","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"(Image: importing the SpineOpt Template)","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Click on spineopttemplate.json and press Open. If you don't see spineopttemplate.json make sure you have navigated to Spine\\SpineOpt.jl\\templates.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Loading the latest version of the SpineOpt template in this way will update your datastore with the latest version of the data structure.","category":"page"},{"location":"getting_started/archetypes/#Branching-Stochastic-Tree","page":"Archetypes","title":"Branching Stochastic Tree","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/branching_stochastic_tree.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called branching, representing a branching scenario tree. The stochastic_structure starts out as a single stochastic_scenario called realistic, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. This archetype is the final product of following the steps in the Example of branching stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"getting_started/archetypes/#Converging-Stochastic-Tree","page":"Archetypes","title":"Converging Stochastic Tree","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/converging_stochastic_tree.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called converging, representing a converging scenario tree (technically a directed acyclic graph DAG). The stochastic_structure starts out as a single stochastic_scenario called realization, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. Then, after 24 hours (1 day), these three forecasts converge into a single stochastic_scenario called converged_forecast. This archetype is the final product of following the steps in the Example of converging stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"getting_started/archetypes/#Deterministic-Stochastic-Structure","page":"Archetypes","title":"Deterministic Stochastic Structure","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/deterministic_stochastic_structure.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called deterministic, representing a simple deterministic modelling case. The stochastic_structure contains only a single stochastic_scenario called realization, which continues indefinitely. This archetype is the final product of following the steps in the Example of deterministic stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"concept_reference/duration_unit/","page":"-","title":"-","text":"The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"implementation_details/documentation/#Documentation","page":"Documentation","title":"Documentation","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The documentation is build with Documenter.jl, by running the make.jl script. Note that make.jl calls some stuff from docs_util.jl.","category":"page"},{"location":"implementation_details/documentation/#Concept-reference","page":"Documentation","title":"Concept reference","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"Parameters.md is one of the files that is automatically generated. Each parameter has a description in the concept_reference folder and is further processed with the spineopt template. As such there is no point in attempting to make changes directly in Parameters.md.","category":"page"},{"location":"implementation_details/documentation/#Documentation-from-docstring","page":"Documentation","title":"Documentation from docstring","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The mathematical formulation of the constraints is also automatically generated: constraints.md contains tags to automatically pull a function's docstring to the file constraints_automatically_generated.md. An example of a tag:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"@@add_constraint_nodal_balance!","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"An example for how the docstring looks:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n add_constraint_nodal_balance!(m::Model)\n\nBalance equation for nodes.\n\nIn **SpineOpt**, [node](@ref) is the place where an energy balance is enforced. As universal aggregators,\nthey are the glue that brings all components of the energy system together. An energy balance is created for each [node](@ref) for all `node_stochastic_time_indices`, unless the [balance\\_type](@ref) parameter of the node takes the value [balance\\_type\\_none](@ref balance_type_list) or if the node in question is a member of a node group, for which the [balance\\_type](@ref) is [balance\\_type\\_group](@ref balance_type_list). The parameter [nodal\\_balance\\_sense](@ref) defaults to equality, but can be changed to allow overproduction ([nodal\\_balance\\_sense](@ref) [`>=`](@ref constraint_sense_list)) or underproduction ([nodal\\_balance\\_sense](@ref) [`<=`](@ref constraint_sense_list)).\nThe energy balance is enforced by the following constraint:\n","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"math \\begin{aligned} & v{node\\injection}(n,s,t) \\\n& + \\sum{\\substack{(conn,n',d{in},s,t) \\in connection_flow_indices: \\ d{out} == :to\\node}} v{connection\\flow}(conn,n',d{in},s,t)\\\n& - \\sum{\\substack{(conn,n',d{out},s,t) \\in connection\\flow_indices: \\ d{out} == :from\\node}} v{connection\\flow}(conn,n',d{out},s,t)\\\n& + v{node_slack_pos}(n,s,t) \\\n& - v{node\\slack_neg}(n,s,t) \\\n& {>=,==,<=} \\\n& 0 \\\n& \\forall (n,s,t) \\in node_stochastic_time_indices: \\\n& p{balance\\type}(n) != balance_type_none \\\n& \\nexists ng \\in groups(n) : balance_type_group \\\n\\end{aligned}","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The reason for using the docstring is such that it is easier to update the documentation in the docstring when developing a certain constraint.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The feature is completely optional. To activate the functionality for another file (e.g. objective.md) add tags to that file and then add code similar to this to make.jl.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"mathpath = joinpath(path, \"src\", \"mathematical_formulation\")\ndocstrings = all_docstrings(SpineOpt)\n\nobjective_function_lines = readlines(joinpath(mathpath, \"objective_function.md\"))\nexpand_tags!(objective_function_lines, docstrings)\nopen(joinpath(mathpath, \"objective_function_automatically_generated.md\"), \"w\") do file\n write(file, join(objective_function_lines, \"\\n\"))\nend","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"To deactivate the functionality, just remove the code and replace the tags in your .md file.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"It is also possible to introduce this feature over time. Anytime you want to add the documentation of a constraint to the docstring you need to follow a few steps:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"For the docstring\nadd @doc raw before the docstring (that allows to write latex in the docstring)\nFor the .md file\ncut the description and mathematical formulation and paste them in the corresponding function's docstring\nadd the tag to pull the above from the docstring","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"An example of both the docstring and the instruction file have already been shown above.","category":"page"},{"location":"implementation_details/documentation/#Drag-and-drop","page":"Documentation","title":"Drag and drop","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"There is also a drag-and-drop feature for select chapters (e.g. the how to section). For those chapters you can simply add your markdown file to the folder of the chapter and it will be automatically added to the documentation. To allow both manually composed chapters and automatically generated chapter, the functionality is only activated for empty chapters (of the structure \"chapter name\" => []).","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The drag-and-drop function assumes a specific structure for the documentation files.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"All chapters and corresponding markdownfiles are in the docs/src folder.\nFolder names need to be lowercase with underscores because the automated folder names are derived from the page names in make.jl. A new chapter (e.g. implementation details) needs to follow this structure.\nMarkdown file names can have uppercases and can have underscores but don't need to because the page names in make.jl are derived from the actual file names. In other words, your filename will become the page name in the documentation so make this descriptive.","category":"page"},{"location":"concept_reference/resolution/","page":"-","title":"-","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.","category":"page"},{"location":"concept_reference/resolution/","page":"-","title":"-","text":"An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"mathematical_formulation/sets/#Sets","page":"Sets","title":"Sets","text":"","category":"section"},{"location":"mathematical_formulation/sets/#ind(*parameter*)","page":"Sets","title":"ind(*parameter*)","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Tuple of all objects, for which the parameter is defined ","category":"page"},{"location":"mathematical_formulation/sets/#t_before_t(t_aftert')","page":"Sets","title":"t_before_t(t_after=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are directly before timeslice t'. ","category":"page"},{"location":"mathematical_formulation/sets/#t_before_t(t_beforet')","page":"Sets","title":"t_before_t(t_before=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are directly after timeslice t'. ","category":"page"},{"location":"mathematical_formulation/sets/#t_in_t(t_shortt')","page":"Sets","title":"t_in_t(t_short=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that contain timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#t_in_t(t_longt')","page":"Sets","title":"t_in_t(t_long=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are contained in timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#t_overlaps_t(t')","page":"Sets","title":"t_overlaps_t(t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that overlap with timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#full_stochastic_paths","page":"Sets","title":"full_stochastic_paths","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of all possible scenario branches ","category":"page"},{"location":"mathematical_formulation/sets/#active_stochastic_paths(s)","page":"Sets","title":"active_stochastic_paths(s)","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of all active scenario branches, based on active scenarios s ","category":"page"},{"location":"mathematical_formulation/variables/#Variables","page":"Variables","title":"Variables","text":"","category":"section"},{"location":"mathematical_formulation/variables/#binary_gas_connection_flow","page":"Variables","title":"binary_gas_connection_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_binary_gas_connection_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: binary_gas_connection_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Binary variable with the indices node n over the connection conn in the direction to_node for the stochastic scenario s at timestep t describing if the direction of gas flow for a pressure drive gastransfer is in the indicated direction. ","category":"page"},{"location":"mathematical_formulation/variables/#connection_flow","page":"Variables","title":"connection_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connection_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connection_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity flow associated with node n over the connection conn in the direction d for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#connection_intact_flow","page":"Variables","title":"connection_intact_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connection_intact_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connection_intact_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"??? ","category":"page"},{"location":"mathematical_formulation/variables/#connections_decommissioned","page":"Variables","title":"connections_decommissioned","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_decommissioned ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of decomissioned connections conn for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#connections_invested","page":"Variables","title":"connections_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of connections conn invested at timestep t in for the stochastic scenario s ","category":"page"},{"location":"mathematical_formulation/variables/#connections_invested_available","page":"Variables","title":"connections_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested connections conn that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#mp_objective_lowerbound_indices","page":"Variables","title":"mp_objective_lowerbound_indices","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_mp_objective_lowerbound_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: mp_objective_lowerbound_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Updating lowerbound for master problem of Benders decomposition ","category":"page"},{"location":"mathematical_formulation/variables/#node_injection","page":"Variables","title":"node_injection","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_injection ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_injection_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity injections at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_pressure","page":"Variables","title":"node_pressure","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_pressure ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_pressure_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Pressue at a node n for a specific stochastic scenario s and timestep t. See also: has_pressure ","category":"page"},{"location":"mathematical_formulation/variables/#node_slack_neg","page":"Variables","title":"node_slack_neg","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_slack_neg ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_slack_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Positive slack variable at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_slack_pos","page":"Variables","title":"node_slack_pos","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_slack_pos ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_slack_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Negative slack variable at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_state","page":"Variables","title":"node_state","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_state ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_state_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Storage state at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_voltage_angle","page":"Variables","title":"node_voltage_angle","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_voltage_angle ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_voltage_angle_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Voltage angle at a node n for a specific stochastic scenario s and timestep t. See also: has_voltage_angle ","category":"page"},{"location":"mathematical_formulation/variables/#nonspin_units_shut_down","page":"Variables","title":"nonspin_units_shut_down","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_nonspin_units_shut_down ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: nonspin_units_shut_down_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u held available for non-spinning downward reserve provision via shutdown to node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#nonspin_units_started_up","page":"Variables","title":"nonspin_units_started_up","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_nonspin_units_started_up ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: nonspin_units_started_up_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u held available for non-spinning upward reserve provision via startup to node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#storages_decommissioned","page":"Variables","title":"storages_decommissioned","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_decommissioned ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of decomissioned storage nodes n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#storages_invested","page":"Variables","title":"storages_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of storage nodes n invested in at timestep t for the stochastic scenario s ","category":"page"},{"location":"mathematical_formulation/variables/#storages_invested_available","page":"Variables","title":"storages_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested storage nodes n that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow","page":"Variables","title":"unit_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity flow associated with node n over the unit u in the direction d for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow_op","page":"Variables","title":"unit_flow_op","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow_op ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_op_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Contribution of the unit flow assocaited with operating point i ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow_op_active","page":"Variables","title":"unit_flow_op_active","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow_op_active ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_op_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Control the activation of operating point i of units ","category":"page"},{"location":"mathematical_formulation/variables/#units_available","page":"Variables","title":"units_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of available units u for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_invested","page":"Variables","title":"units_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s invested in at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_invested_available","page":"Variables","title":"units_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested units u that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_mothballed","page":"Variables","title":"units_mothballed","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_mothballed ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenariocenario s mothballed at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_on","page":"Variables","title":"units_on","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_on ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of online units u for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_shut_down","page":"Variables","title":"units_shut_down","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_shut_down ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s that switched to offline status at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_started_up","page":"Variables","title":"units_started_up","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_started_up ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s that switched to online status at timestep t ","category":"page"},{"location":"concept_reference/minimum_reserve_activation_time/","page":"-","title":"-","text":"The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.","category":"page"},{"location":"concept_reference/minimum_reserve_activation_time/","page":"-","title":"-","text":"In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves","category":"page"},{"location":"concept_reference/fixed_pressure_constant_1/","page":"-","title":"-","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/units_invested_avaiable_coefficient/","page":"-","title":"-","text":"The units_invested_available_coefficient is an optional parameter that can be used to include the units_invested_available variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_available_coefficient appears as a coefficient for the units_invested_available variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/fuel_cost/","page":"-","title":"-","text":"By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values \"unit_online_variable_type_binary\", \"unit_online_variable_type_integer\", \"unit_online_variable_type_linear\" and \"unit_online_variable_type_none\".","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment). ","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\\_online\\_variable\\_type\\_integer.","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.","category":"page"},{"location":"concept_reference/fractional_demand/","page":"-","title":"-","text":"Whenever a node is a member of a group, the fractional_demand parameter represents its share of the group's demand.","category":"page"},{"location":"concept_reference/node/","page":"-","title":"-","text":"The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.","category":"page"},{"location":"concept_reference/node/","page":"-","title":"-","text":"Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.","category":"page"},{"location":"advanced_concepts/ramping/#Ramping","page":"Ramping","title":"Ramping","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"To enable the representation of units with a high level of technical detail, the ramping capability of units can be constrained in SpineOpt. This means that the user has the freedom to impose restrictions on the change in the output (or input) of units over time, for online (spinning) units, units starting up and units shutting down. In this section, the concept of ramps in SpineOpt will be introduced.","category":"page"},{"location":"advanced_concepts/ramping/#Relevant-objects,-relationships-and-parameters","page":"Ramping","title":"Relevant objects, relationships and parameters","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Everything that is related to ramping is defined in parameters of either the unit__to_node or unit__from_node relationship (where the node can be a group). Generally speaking, the ramping constraints will impose restrictions on the change in the unit_flow variable between two consecutive timesteps.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"All parameters that limit the ramping abilities of a unit are expressed as a fraction of the unit capacity. This means that a value of 1 indicates the full capacity of a unit.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The discussion here will be conceptual. For the mathematical formulation the reader is referred to the Ramping constraints","category":"page"},{"location":"advanced_concepts/ramping/#Constraining-spinning-up-and-down-ramps","page":"Ramping","title":"Constraining spinning up and down ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : limit the maximum increase in the unit_flow variable when the unit is online, over a period of time equal to the duration_unit. The parameter is given as a fraction of the unit_capacity. Inclusion of this parameter will trigger the creation of the Constraint on spinning upwards ramp\nramp_down_limit : limit the maximum decrease in the unit_flow variable when the unit is online, over a period of time equal to the duration_unit. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning downward ramps","category":"page"},{"location":"advanced_concepts/ramping/#Constraining-start-up-and-shut-down-ramps","page":"Ramping","title":"Constraining start up and shut down ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"start_up_limit : limit the maximum increase in the unit_flow variable when the unit is starting up. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning upwards ramp\nshut_down_limit : limit the maximum decrease in the unit_flow variable when the unit is shutting down. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning downward ramps","category":"page"},{"location":"advanced_concepts/ramping/#General-principle-and-example-use-cases","page":"Ramping","title":"General principle and example use cases","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The general principle of the Spine modelling ramping constraints is that all of these parameters can be defined separately for each unit. This allows the user to incorporate different units (which can either represent a single unit or a technology type) with different flexibility characteristics.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"It should be noted that it is perfectly possible to omit all of the ramp constraining parameters mentioned above, or to specify only some of them. Anything that is omitted is interpreted as if it shouldn't be constrained. For example, if you only specify start_up_limit and ramp_down_limit, then only the flow increase during start up and the flow decrease during online operation will be constrained (but not any other flow increase or decrease).","category":"page"},{"location":"advanced_concepts/ramping/#Illustrative-examples","page":"Ramping","title":"Illustrative examples","text":"","category":"section"},{"location":"advanced_concepts/ramping/#Step-1:-Simple-case-of-unrestricted-unit","page":"Ramping","title":"Step 1: Simple case of unrestricted unit","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When none of the ramping parameters mentioned above are specified, the unit is considered to have full ramping flexibility. This means that over any period of time, its flow can be any value between 0 and its capacity, regardless of what the flow of the unit was in previous timesteps, and regardless of the on- or offline status of the unit in previous timesteps (while still respecting, of course, the Unit commitment restrictions that are defined for this unit). This is equivalent to specifying the following:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"shut_down_limit : 1\nstart_up_limit : 1\nramp_up_limit : 1\nramp_down_limit : 1","category":"page"},{"location":"advanced_concepts/ramping/#Step-2:-Spinning-ramp-restriction","page":"Ramping","title":"Step 2: Spinning ramp restriction","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"A unit which is only restricted in spinning ramping can be created by changing the ramp_up/down_limit parameters:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.2\nramp_down_limit : 0.4","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"This parameter choice implies that the unit flow cannot increase more than 02 * 200 and cannot decrease more than 04 * 200 over a period of time equal to 'one' duration_unit. For example, when the unit is running at an output of 100 in some timestep t, its output for the next 'one' duration_unit must be somewhere in the interval 20 140 - unless it shuts down completely.","category":"page"},{"location":"advanced_concepts/ramping/#Step-3:-Shutdown-restrictions","page":"Ramping","title":"Step 3: Shutdown restrictions","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"By specifying the parameter shut_down_limit, an additional restriction is imposed on the maximum flow of the unit at the moment it goes offline:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"shut_down_limit : 0.5\nminimum_operating_point : 0.3","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When the unit goes offline in a given timestep t, the output of the unit must be below 05 * 200 = 100 in the timestep right before that t (and of course, above 03 * 200 = 60 - the minimum operating point).","category":"page"},{"location":"advanced_concepts/ramping/#Step-4:-Startup-restrictions","page":"Ramping","title":"Step 4: Startup restrictions","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The start up restrictions are very similar to the shut down restrictions, but of course apply to units that are starting up. THey are activated by specifying start_up_limit:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"start_up_limit : 0.4\nminimum_operating_point : 0.2","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When the unit goes online in a given timestep t, its output will be restricted to the interval 40 80.","category":"page"},{"location":"advanced_concepts/ramping/#Using-node-groups-to-constraint-aggregated-flow-ramps","page":"Ramping","title":"Using node groups to constraint aggregated flow ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"SpineOpt allows the user to constrain ramping abilities of units that are linked to multiple nodes by defining node groups. When a node group is defined, ramping restrictions can be imposed both on the group level (thus for the unit as a whole) as well as for the individual nodes. For example, let's assume that we have one unit and two nodes in a model. The unit is linked via unit__to_node relationships to each node individually, and on top of that, it is linked to a node group containing both nodes.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"If, for example a ramp_up_limit is defined for the node group, the sum of upward ramping of the two nodes will be restricted by this parameter. However, it is still possible to limit the individual flows to the nodes as well. Let's say that our unit is capable of ramping up by 20% of its capacity and down by 40%. We might want to impose tighter restrictions for the flows towards one of the nodes (e.g. because the energy has to be provided in a shorter time than the duration_unit). One can then simply define an additional parameter for that unit__to_node relationship as follows.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.15","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Which now restricts the flow of the unit into that node to 15% of its capacity.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Please note that by default, node groups are balanced in the same way as individual nodes. So if you're using node groups for the sole purpose of constraining flow ramps, you should set the balance type of the group to balance_type_none.","category":"page"},{"location":"advanced_concepts/ramping/#Ramping-with-reserves","page":"Ramping","title":"Ramping with reserves","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"If a unit is set to provide reserves, then it should be able to provide that reserve within one duration_unit. For this reason, reserve provision must be accounted for within ramp constraints. Please see Reserves for details on how to setup a node as a reserve.","category":"page"},{"location":"advanced_concepts/ramping/#Examples","page":"Ramping","title":"Examples","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Let's assume that we have one unit and two nodes in a model, one for reserves and one for regular demand. The unit is then linked by the unit__to_node relationships to both the reserves and regular demand node.","category":"page"},{"location":"advanced_concepts/ramping/#Spinning-ramp-restriction","page":"Ramping","title":"Spinning ramp restriction","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The unit can be restricted in spinning ramping by defining the ramp_up/down_limit parameters in the unit__to_node relationship for the regular demand node:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.2\nramp_down_limit : 0.4","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"This parameter choice implies that the unit's flow to the regular demand node cannot increase more than 02 * 200 - upward_reserve_demand or decrease more than 04 * 200 - downward_reserve_demand over one duration_unit. For example, when the unit is running at an output of 100 and there is an upward reserve demand of 10, then its output over the next duration_unit must be somewhere in the interval 20 130.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"It can be seen in this example that the demand for reserves is subtracted from the ramping capacity of the unit that is available for regular operation. This stems from the fact that in providing reserve capacity, the unit is expected to be able to provide the demanded reserve within one duration_unit as stated above.","category":"page"},{"location":"getting_started/output_data/#Managing-Output-Data","page":"Managing Outputs","title":"Managing Output Data","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Once a model is created and successfully run, it will hopefully produce results and output data. This section covers how the writing of output data is controlled and managed.","category":"page"},{"location":"getting_started/output_data/#Specifying-Your-Output-Data-Store","page":"Managing Outputs","title":"Specifying Your Output Data Store","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In your workflow (for more details see Setting up a workflow for SpineOpt in Spine Toolbox) you will normally have a output datastore connected to your RunSpineOpt workflow tool. This is where your output data will be written. If no output datastore is specified, the results will be written by default to the input datastore. However, it is generally preferable to define a separate output data store for results. See Setting up a workflow for SpineOpt in Spine Toolbox for the steps to add an output datastore to your workflow)","category":"page"},{"location":"getting_started/output_data/#Specifying-Outputs-to-Write","page":"Managing Outputs","title":"Specifying Outputs to Write","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Outputting of results to the output datastore is controlled using the output and report object classes. To output a specific variable to the output datastore, we need to create an output object of the same name. For example, to output the unit_flow variable, we must create an output object named unit_flow. The SpineOpt template contains output objects for most problem variables and importing or re-importing the SpineOpt template will add these to your input datastore. So it is probable these output objects will exist already in your input datastore. Once the output objects exist in your model, they must then be added to a report object by creating an report__output relationship","category":"page"},{"location":"getting_started/output_data/#Creating-Reports","page":"Managing Outputs","title":"Creating Reports","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Reports are essentially a collection of outputs that can be written to an output datastore. Any number of report objects can be created. We add output items to a report by creating report__output relationships between the output objects we want included and the desired report object. Finally, to write a specic report to the output database, we must create a model__report relationship for each report object we want included in the output datastore.","category":"page"},{"location":"getting_started/output_data/#Reporting-of-Input-Parameters","page":"Managing Outputs","title":"Reporting of Input Parameters","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In addition to writing results as outputs to a datastore, SpineOpt can also report input parameter data. To allow specific input parameters to be included in a report, they must be first added as output objects with a name corresponding exactly to the parameter name. For example, to allow the demand parameter to be included in a report, there must be a correspondingly named output object called demand. Similarly to outputs, to include an input parameter in a report, we must create a report__output relationship between the output object representing the input parameter (e.g. demand) and the desired report object.","category":"page"},{"location":"getting_started/output_data/#Reporting-of-Dual-Values","page":"Managing Outputs","title":"Reporting of Dual Values","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's marginal value to be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To report the reduced_cost() for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of unitson in the final fixed LP to be written to the output db. Finally, if any constraint duals or reducedcost values are requested via a report, calculate_duals is set to true and the final fixed LP solve is triggered.","category":"page"},{"location":"getting_started/output_data/#Output-Data-Temporal-Resolution","page":"Managing Outputs","title":"Output Data Temporal Resolution","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To control the resolution of report data (both output data and input data appearing in reports), we use the output_resolution output parameter. For the specific output (or input), this indicates the resolution at which the values should be reported. If output_resolution is null (the default), results are reported at the highest available resolution that will follow from the temporal structure of the model. If output_resolution is a duration value, then the average value is reported. ","category":"page"},{"location":"getting_started/output_data/#Output-Data-Structure","page":"Managing Outputs","title":"Output Data Structure","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"The structure of the output data will follow the structure of the input data with the inclusion of additional dimensions as described below:","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"The report object to which the output data items belong will be added as a dimension\nThe relevant stochastic scenario will be added as a dimension to all output data items. This allows for stochastic data to be written to the output datastore. However, in deterministic models, the single deterministic scenario will still appear as an additional dimension\nFor unit flows, the flow direction is added as a dimension to the output. ","category":"page"},{"location":"getting_started/output_data/#Example:-unit_flow","page":"Managing Outputs","title":"Example: unit_flow","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"For example, consider the unit_flow) optimisation variable. This variable is dimensioned on the unit__to_node and unit__from_node relationships. In the output datastore, the report, stochastic_scenario and flow direction are added as additional dimensions. Therefore, unit__to_node values will appear in the output datastore as timeseries parameters associated with the report__unit__node__direction__stochastic_scenario relationship as shown below.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To view the data, simply double-click on the timeseries value","category":"page"},{"location":"getting_started/output_data/#Example:-units_on","page":"Managing Outputs","title":"Example: units_on","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Consider the units_on) optimisation variable. This variable is dimensioned on the unit object class. In the output datastore, the report and stochastic_scenario are added as additional dimensions. Therefore, units_on values will appear in the output datastore as timeseries parameters associated with the report__unit__stochastic_scenario relationship as shown below.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To view the data, simply double-click on the timeseries value","category":"page"},{"location":"getting_started/output_data/#Alternatives-and-Multiple-Model-Runs","page":"Managing Outputs","title":"Alternatives and Multiple Model Runs","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"All outputs from a single run of a model will be tagged with a unique \"alternative\". Alternatives allow multiple values to be specified for the same parameter. If a model is run multiple times, the results will be appended to the output datastore with a new alternative which uniquely identifies the scenario and model run. This is convenient as it allows results from multiple runs and for multiple scenarios to be viewed and compared simultaneously. If a specific altnernative is not selected (the default condition) the results for all alternatives will be visible. If a single altnerative is selected or multiple alternatives are selected in the altnerative tree, then only the results for the selected alternatives will be shown. ","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In the example below, the relationship class report__unit__stochastic_scenario is selected in the relationship treem therefore results for that relationship class are showing in the relationship parameter pane. Furthermore, in the alternative tree, the alternative 10h TP Load _Reun SpineOpt... is selected, meaning only results for that alternative are being displayed.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/#Output-Writing-Summary","page":"Managing Outputs","title":"Output Writing Summary","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"We need an output object in our intput datastore for each variable or marginal value we want included in a report\nInputs data can also be reported. As above, we need to create an output object named after the input parameter we want reported \nWe need to create a report object to contain our desired outputs (or input parameters) which are added to our report via report__output relationships\nWe need to create a model__report object to write a specific report to the output datastore.\nThe temporal resolution of outputs (which may also be input parameters) is controlled by the output_resolution output duration parameter. If null, the highest available resolution is reported, otherwise the average is reported over the desired duration. \nAdditional dimensions are added to the output data such as the report object, stochastic_scenario and, in the case of unit_flow, the flow direction. \nModel outputs are tagged with altnernatives that are unique to the model run and scenario that generated them","category":"page"},{"location":"concept_reference/fix_connection_intact_flow/","page":"-","title":"-","text":"The fix_connection_intact_flow parameter can be used to fix the values of the connection_intact_flow variable to preset values. If set to a Scalar type value, the connection_intact_flow variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/start_up_limit/","page":"-","title":"-","text":"The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.","category":"page"},{"location":"concept_reference/start_up_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/node__investment_stochastic_structure/","page":"-","title":"-","text":"The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.","category":"page"},{"location":"concept_reference/node__investment_stochastic_structure/","page":"-","title":"-","text":"The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"See also Investment Optimization and unit_investment_variable_type","category":"page"},{"location":"getting_started/installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"getting_started/installation/#Compatibility","page":"Installation","title":"Compatibility","text":"","category":"section"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"This package requires Julia 1.2 or later.","category":"page"},{"location":"getting_started/installation/#Installation-2","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"If you haven't yet installed the tools yet, please follow the installation guides: ","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For Spine Toolbox: https://github.com/spine-tools/SpineOpt.jl#installation\nFor SpineOpt: https://github.com/spine-tools/Spine-Toolbox#installation","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For Spine Toolbox:","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"- If installed with pipx, then use `python -m pipx upgrade spinetoolbox`\n- If installed from sources using git, then
\n `git pull`
\n\t`python -m pip install -U -r requirements.txt`
","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For SpineOpt: https://github.com/spine-tools/SpineOpt.jl#upgrading","category":"page"},{"location":"concept_reference/variable_type_list/","page":"-","title":"-","text":"The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.","category":"page"},{"location":"concept_reference/fom_cost/","page":"-","title":"-","text":"By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.","category":"page"},{"location":"concept_reference/ordered_unit_flow_op/","page":"-","title":"-","text":"If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.","category":"page"},{"location":"concept_reference/ordered_unit_flow_op/","page":"-","title":"-","text":"Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.","category":"page"},{"location":"concept_reference/reserve_procurement_cost/","page":"-","title":"-","text":"By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/max_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/connection__investment_temporal_block/","page":"-","title":"-","text":"connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.","category":"page"},{"location":"concept_reference/connection__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/node_state_coefficient/","page":"-","title":"-","text":"The node_state_coefficient is an optional parameter that can be used to include the node_state variable of a node in a user_constraint via the node__user_constraint relationship. Essentially, node_state_coefficient appears as a coefficient for the node_state variable of the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#Parameter-Value-Lists","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/#balance_type_list","page":"Parameter Value Lists","title":"balance_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: balance_type_group, balance_type_node and balance_type_none ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The balance_type_list parameter value list contains the possible values for the balance_type parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#boolean_value_list","page":"Parameter Value Lists","title":"boolean_value_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: false and true ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"A list of boolean values (True or False).","category":"page"},{"location":"concept_reference/Parameter Value Lists/#commodity_physics_list","page":"Parameter Value Lists","title":"commodity_physics_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: commodity_physics_lodf, commodity_physics_none and commodity_physics_ptdf ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#connection_investment_variable_type_list","page":"Parameter Value Lists","title":"connection_investment_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: connection_investment_variable_type_continuous and connection_investment_variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#connection_type_list","page":"Parameter Value Lists","title":"connection_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: connection_type_lossless_bidirectional and connection_type_normal ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#constraint_sense_list","page":"Parameter Value Lists","title":"constraint_sense_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: <=, == and >= ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#db_lp_solver_list","page":"Parameter Value Lists","title":"db_lp_solver_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: CDCS.jl, CDDLib.jl, COSMO.jl, CPLEX.jl, CSDP.jl, Clp.jl, ECOS.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Hypatia.jl, Ipopt.jl, KNITRO.jl, MadNLP.jl, MosekTools.jl, NLopt.jl, OSQP.jl, ProxSDP.jl, SCIP.jl, SCS.jl, SDPA.jl, SDPNAL.jl, SDPT3.jl, SeDuMi.jl and Xpress.jl ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#db_mip_solver_list","page":"Parameter Value Lists","title":"db_mip_solver_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: CPLEX.jl, Cbc.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Juniper.jl, KNITRO.jl, MosekTools.jl, SCIP.jl and Xpress.jl ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#duration_unit_list","page":"Parameter Value Lists","title":"duration_unit_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: hour and minute ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#model_type_list","page":"Parameter Value Lists","title":"model_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: spineopt_benders, spineopt_mga, spineopt_other and spineopt_standard ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#node_opf_type_list","page":"Parameter Value Lists","title":"node_opf_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: node_opf_type_normal and node_opf_type_reference ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"See also powerflow.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#unit_investment_variable_type_list","page":"Parameter Value Lists","title":"unit_investment_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: unit_investment_variable_type_continuous and unit_investment_variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#unit_online_variable_type_list","page":"Parameter Value Lists","title":"unit_online_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear and unit_online_variable_type_none ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#variable_type_list","page":"Parameter Value Lists","title":"variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: variable_type_binary, variable_type_continuous and variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#write_mps_file_list","page":"Parameter Value Lists","title":"write_mps_file_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: write_mps_always, write_mps_never and write_mps_on_no_solve ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"This parameter value list is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\\_mps\\_on\\_no\\_solve, and write\\_mps\\_never.","category":"page"},{"location":"concept_reference/max_mga_iterations/","page":"-","title":"-","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.","category":"page"},{"location":"concept_reference/has_pressure/","page":"-","title":"-","text":"If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here","category":"page"},{"location":"concept_reference/node_opf_type_list/","page":"-","title":"-","text":"Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.","category":"page"},{"location":"concept_reference/node_opf_type_list/","page":"-","title":"-","text":"See also powerflow.","category":"page"},{"location":"concept_reference/units_invested_big_m_mga/","page":"-","title":"-","text":"The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_in/","page":"-","title":"-","text":"The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/units_invested_coefficient/","page":"-","title":"-","text":"The units_invested_coefficient is an optional parameter that can be used to include the units_invested variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_coefficient appears as a coefficient for the units_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/unit_start_flow/","page":"-","title":"-","text":"Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/connection_investment_variable_type_list/","page":"-","title":"-","text":"The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous. ","category":"page"},{"location":"concept_reference/balance_type_list/","page":"-","title":"-","text":"The balance_type_list parameter value list contains the possible values for the balance_type parameter.","category":"page"},{"location":"concept_reference/connection_reactance/","page":"-","title":"-","text":"The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node. ","category":"page"},{"location":"concept_reference/fix_node_pressure/","page":"-","title":"-","text":"In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.","category":"page"},{"location":"concept_reference/units_invested_mga/","page":"-","title":"-","text":"The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/shut_down_limit/","page":"-","title":"-","text":"The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.","category":"page"},{"location":"concept_reference/shut_down_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Relationship Classes/#Relationship-Classes","page":"Relationship Classes","title":"Relationship Classes","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/#connection__from_node","page":"Relationship Classes","title":"connection__from_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the connection can take input from, and holds most connection_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__from_node__investment_group","page":"Relationship Classes","title":"connection__from_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which connection capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__from_node__user_constraint","page":"Relationship Classes","title":"connection__from_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_group","page":"Relationship Classes","title":"connection__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a connection belongs in an investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and investment_group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_stochastic_structure","page":"Relationship Classes","title":"connection__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the stochastic structure of the connections investments variable","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_temporal_block","page":"Relationship Classes","title":"connection__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the temporal resolution of the connections investments variable","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__node__node","page":"Relationship Classes","title":"connection__node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters spanning multiple connection_flow variables to and from multiple nodes.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: compression_factor, connection_flow_delay, connection_linepack_constant, fix_ratio_out_in_connection_flow, fixed_pressure_constant_0, fixed_pressure_constant_1, max_ratio_out_in_connection_flow and min_ratio_out_in_connection_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node","page":"Relationship Classes","title":"connection__to_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the connection can output to, and holds most connection_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node__investment_group","page":"Relationship Classes","title":"connection__to_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which connection capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node__user_constraint","page":"Relationship Classes","title":"connection__to_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__user_constraint","page":"Relationship Classes","title":"connection__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Relationship required to involve a connections investment variables in a user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connections_invested_available_coefficient and connections_invested_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_investment_stochastic_structure","page":"Relationship Classes","title":"model__default_investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default stochastic structure used for investment variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_investment_temporal_block","page":"Relationship Classes","title":"model__default_investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default temporal block used for investment variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_stochastic_structure","page":"Relationship Classes","title":"model__default_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default stochastic structure used for model variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_temporal_block","page":"Relationship Classes","title":"model__default_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default temporal block used for model variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__report","page":"Relationship Classes","title":"model__report","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Determines which reports are written for each model and in turn, which outputs are written for each model","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and report","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/Relationship Classes/#model__stochastic_structure","page":"Relationship Classes","title":"model__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which stochastic_structures are included in which models.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__temporal_block","page":"Relationship Classes","title":"model__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which temporal_blocks are included in which models.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__commodity","page":"Relationship Classes","title":"node__commodity","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Define a commodity for a node. Only a single commodity is permitted per node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: commodity and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow\nOnly connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_group","page":"Relationship Classes","title":"node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a node belongs in a investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_stochastic_structure","page":"Relationship Classes","title":"node__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"defines the stochastic structure for node related investments, currently only storages","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_temporal_block","page":"Relationship Classes","title":"node__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"defines the temporal resolution for node related investments, currently only storages","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#node__node","page":"Relationship Classes","title":"node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters for direct interactions between two nodes, e.g. node_state diffusion coefficients.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: diff_coeff","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__stochastic_structure","page":"Relationship Classes","title":"node__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific stochastic_structure is used by the node and all flow variables associated with it. Only one stochastic_structure is permitted per node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__temporal_block","page":"Relationship Classes","title":"node__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the temporal_blocks used by the node and all the flow variables associated with it.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: cyclic_condition and is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__user_constraint","page":"Relationship Classes","title":"node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"specifying this relationship allows a node's demand or node_state to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: demand_coefficient, node_state_coefficient, storages_invested_available_coefficient and storages_invested_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#parent_stochastic_scenario__child_stochastic_scenario","page":"Relationship Classes","title":"parent_stochastic_scenario__child_stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the master stochastic direct acyclic graph, meaning how the stochastic_scenarios are related to each other.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_scenario","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.","category":"page"},{"location":"concept_reference/Relationship Classes/#report__output","page":"Relationship Classes","title":"report__output","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Output object related to a report object are returned to the output database (if they appear in the model as variables)","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: output and report","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: overwrite_results_on_rolling","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/Relationship Classes/#stochastic_structure__stochastic_scenario","page":"Relationship Classes","title":"stochastic_structure__stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which stochastic_scenarios are included in which stochastic_structure, and holds the parameters required for realizing the structure in combination with the temporal_blocks.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_scenario and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: stochastic_scenario_end and weight_relative_to_parents","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__commodity","page":"Relationship Classes","title":"unit__commodity","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters for commodities used by the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: commodity and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: max_cum_in_unit_flow_bound","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node","page":"Relationship Classes","title":"unit__from_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the unit can take input from, and holds most unit_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node__investment_group","page":"Relationship Classes","title":"unit__from_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which unit capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group, node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node__user_constraint","page":"Relationship Classes","title":"unit__from_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which input unit_flows are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node, unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: graph_view_position and unit_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_group","page":"Relationship Classes","title":"unit__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a unit belongs in an investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_stochastic_structure","page":"Relationship Classes","title":"unit__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Sets the stochastic structure for investment decisions - overrides model__default_investment_stochastic_structure.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_structure and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_temporal_block","page":"Relationship Classes","title":"unit__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Sets the temporal resolution of investment decisions - overrides model__default_investment_temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: temporal_block and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__node__node","page":"Relationship Classes","title":"unit__node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters spanning multiple unit_flow variables to and from multiple nodes.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_ratio_in_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_out_in_unit_flow, fix_ratio_out_out_unit_flow, fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, fix_units_on_coefficient_out_out, max_ratio_in_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_out_in_unit_flow, max_ratio_out_out_unit_flow, max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, max_units_on_coefficient_out_out, min_ratio_in_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_out_in_unit_flow, min_ratio_out_out_unit_flow, min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, min_units_on_coefficient_out_out, unit_idle_heat_rate, unit_incremental_heat_rate and unit_start_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node","page":"Relationship Classes","title":"unit__to_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the unit can output to, and holds most unit_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_nonspin_units_shut_down, fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_shut_down, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node__investment_group","page":"Relationship Classes","title":"unit__to_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which unit capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group, node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node__user_constraint","page":"Relationship Classes","title":"unit__to_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which output unit_flows are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node, unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: graph_view_position and unit_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__user_constraint","page":"Relationship Classes","title":"unit__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which units_on variables are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: units_invested_available_coefficient, units_invested_coefficient, units_on_coefficient and units_started_up_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#units_on__stochastic_structure","page":"Relationship Classes","title":"units_on__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific stochastic_structure is used for the units_on variable of the unit. Only one stochastic_structure is permitted per unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_structure and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#units_on__temporal_block","page":"Relationship Classes","title":"units_on__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific temporal_blocks are used by the units_on variable of the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: temporal_block and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized. ","category":"page"},{"location":"concept_reference/has_state/","page":"-","title":"-","text":"The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.","category":"page"},{"location":"concept_reference/unit__commodity/","page":"-","title":"-","text":"To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.","category":"page"},{"location":"concept_reference/unit__commodity/","page":"-","title":"-","text":"Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.","category":"page"},{"location":"concept_reference/model/","page":"-","title":"-","text":"The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).","category":"page"},{"location":"concept_reference/write_lodf_file/","page":"-","title":"-","text":"If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/storage_investment_cost/","page":"-","title":"-","text":"By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/connection__node__node/","page":"-","title":"-","text":"connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1","category":"page"},{"location":"concept_reference/node_state_cap/","page":"-","title":"-","text":"The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.","category":"page"},{"location":"concept_reference/operating_points/","page":"-","title":"-","text":"If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.","category":"page"},{"location":"concept_reference/operating_points/","page":"-","title":"-","text":"Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/tax_out_unit_flow/","page":"-","title":"-","text":"By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/model__default_temporal_block/","page":"-","title":"-","text":"The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/mga_diff_relative/","page":"-","title":"-","text":"Currently, the MGA algorithm (see mga-advanced) only supports absolute differences between MGA variables (e.g. absolute differences between units_invested_available etc.). Hence, the default for this parameter is false and should not be changed for now.","category":"page"},{"location":"concept_reference/connection_emergency_capacity/","page":"-","title":"-","text":"The connection_emergency_capacity parameter represents the maximum post-contingency flow on a monitored connection if ptdf and lodf based security constrained unit commitment is enabled (commodity_physics is set to [commodity_physics_lodf]).","category":"page"},{"location":"concept_reference/connection_emergency_capacity/","page":"-","title":"-","text":"If you set this value, make sure that you also set connection_monitored to true for the involved connection.","category":"page"},{"location":"concept_reference/unit_investment_variable_type_list/","page":"-","title":"-","text":"unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous. ","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/connection_flow_cost/","page":"-","title":"-","text":"By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/roll_forward/","page":"-","title":"-","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.","category":"page"},{"location":"concept_reference/roll_forward/","page":"-","title":"-","text":"In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.","category":"page"},{"location":"concept_reference/write_mps_file_list/","page":"-","title":"-","text":"This parameter value list is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/write_mps_file_list/","page":"-","title":"-","text":"Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\\_mps\\_on\\_no\\_solve, and write\\_mps\\_never.","category":"page"},{"location":"concept_reference/graph_view_position/","page":"-","title":"-","text":"The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.","category":"page"},{"location":"concept_reference/model__stochastic_structure/","page":"-","title":"-","text":"The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.","category":"page"},{"location":"concept_reference/unit__from_node__unit_constraint/","page":"-","title":"-","text":"unit__from_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable to the specified unit from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__from_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint","category":"page"},{"location":"advanced_concepts/powerflow/#ptdf-based-powerflow","page":"PTDF-Based Powerflow","title":"Power transfer distribution factors (PTDF) based DC power flow","text":"","category":"section"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"There are two main methodologies for directly including DC powerflow in unit commitment/energy system models. One method is to directly include the bus voltage angles as variables in the model. This method is described in Nodal lossless DC Powerflow.","category":"page"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"Here we discuss the method of using power transfer distribution factors (PTDF) for DC power flow and line outage distribution factors (lodf) for security constrained unit commitment.","category":"page"},{"location":"advanced_concepts/powerflow/#key-concepts-advanced-ptdf-DC","page":"PTDF-Based Powerflow","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"ptdf: The power transfer distribution factors are a property of the network reactances and their derivation may be found here. ptdf(n, c) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of ptdf(n, c)*net_injection(c). The advantage of this method is that it introduces no additional variables into the problem and instead, introduces only one constraint for each connection whose flow we are interested in monitoring.\nlodf: Line outage distribution factors are a function of the network ptdfs and their derivation is also found here. lodf(c_contingency, c_monitored) represents the fraction of the pre-contingency flow on connection c_contingency that will flow on c_monitored if c_contingency is disconnected. Therefore, the post contingency flow on connection c_monitored is the pre_contingency flow plus lodf(c_contingency, c_monitored)\\*pre_contingency_flow(c_contingency)). Therefore, consideration of N contingencies on M monitored lines introduces N x M constraints into the model. Usually one wishes to contain this number and methods are given below to achieve this.\nDefining your network To identify the network for which ptdfs, lodfs and connection_flows will be calculated according to the ptdf method, one does the following:\nCreate node objects for each bus in the model.\nCreate connection objects representing each line of the network: For each connection specify the connection_reactance parameter and the connection_type parameter. Setting connection_type=connection_type_lossless_bidirectional simplifies the amount of data that needs to be specified for an eletrical network. See connection_type for more details \nSet the connection__to_node and connection__from_node relationships to define the topology of each connection along with the connection_capacity parameter on one or both of these relationships.\nSet the connection_emergency_capacity parameter to define the post contingency rating if lodf-based N-1 security constraints are to be included\nCreate a commodity object and node__commodity relationships for all the nodes that comprise the electrical network for which PTDFs are to be calculated.\nSpecify the commodity_physics parameter for the commodity to :commodity_physics_ptdf if ptdf-based DC load flow is desired with no N-1 security constraints or to :commodity_physics_lodf if it is desired to include lodf-based N-1 security constraints\nTo identify the reference bus(node) specify the node_opf_type parameter for the appropriate node with the value node_opf_type_reference.\nControlling problem size\nThe lines to be monitored are specified by setting the connection_monitored property for each connection for which a flow constraint is to be generated\nThe contingencies to be considered are specified by setting the connection_contingency property for the appropriate connections. For N contingencies and M monitored lines, N x M constraints will be generated.\nIf the lodf(c_contingency, c_monitored) is very small, it means the outage of c_contingency has a small impact on the flow on c_monitoredand there is little point in including this constraint in the model. This can be achieved by setting the commodity_lodf_tolerance commodity parameter. Contingency / Monotired line combinations with lodfs below this value will be ignored, reducing the size of the model.\nIf ptdf(n, c) is very small, it means an injection at n has a small impact on the flow on c and there is little point in considering it. This can be achieved by setting the commodity_ptdf_threshold commodity parameter. Node / Monotired line combinations with ptdfs below this value will be ignored, reducing the number of coefficients in the model.\nTo more easily identify which connections are worth being monitored or which contingencies are worth being considered, you can add the contingency_is_binding output to any of your reports (via a report__output relationship). This will run the model without the security constraints, and instead write a parameter called contingency_is_binding to the output database for each pair of contingency and monitored connection. The value of the parameter will be a (possibly stochastic) time-series where a value of one will indicate that the corresponding security constraint is binding, and zero otherwise.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/#pressure-driven-gas-transfer","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"The generic formulation of SpineOpt is based on a trade based model. However, network physics can be different depending on the traded commodity. This chapter specifically addresses the use of pressure driven gas transfer models and enabling linepack flexibility in SpineOpt. To this date, investments in pressure driven pipelines are not yet supported within SpineOpt. The use of multiple feed-in nodes, e.g. to represent multiple commodity flows through a pipeline is not yet supported.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"For the representation of pressure driven gas transfer, we use the MILP formulation, as described in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. Here, the non-linearities associated with the Weymouth equation are convexified through an outer approximation of the Weymouth equation through fixed pressure points.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/#key-concepts-advanced-gas","page":"Pressure driven gas transfer","title":"Key concept","text":"","category":"section"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"Here, we briefly describe the key objects and relationships required to model pressure driven gas transfers in SpineOpt.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"connection: A connection represents the gas pipeline being modelled. Usually the direction of flow is not known a priory. To ensure that the flow through the gas pipeline is unidirectional, the parameter has_binary_gas_flow needs to be set to true.\nnode: Nodes with different characteristics are used for the representation of pressure driven gas transfer.\nFor each connection, there will be two nodes representing the start and end point of the pipeline. Associated with these nodes are the following parameters: the has_pressure parameter, which needs to be set to true, in order to create the variable node_pressure; the max_node_pressure and min_node_pressure to constrain the pressure variable.\nTo leverage linepack flexibility, a third node is introduced representing the linepack storage of the pipeline. To trigger the storage linepack and hence, node_state variables, the has_state parameter needs to be set to true.\nconnection__to_node and connection__from_node To enable flows through the pipeline and into the linepack storage, each node has to have both these relationships in common with the connection pipeline. These relationships will trigger the generation of connection_flow variables in all possible directions.\nconnection__node__node This relationship is key to the pressure driven gas transfer, holding the information about the pipeline characteristics and bringing the elements into interaction.\nThe parameter connection_linepack_constant holds the linepack constant and triggers the generation of the line pack storage constraint. Note that the first node should be the linepack storage node, while the second node should be a node_group of both, the start and the end node of the pipeline.\nThe linearization of the Weymouth equation through outer approximation relies on the use of fixed pressure points. For this purpose, the two parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 hold the fixed pressure constants and trigger the generation of the constraint_fix_node_pressure_point. The constraint introduces the relationship between pressure and gas flows. Note, that the pressure constants should be entered in a way, that the first node represents the origin node, the second node the destination node. Each connection should have a connection__node__node to each combination of its start and end nodes (and associated parameters). (See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling)\nBy default, pipelines are considered to be passive. However, a compression station between two pipeline pressure nodes can be represented by defining a compression_factor. The relationship should be defined in such a manner, that the first node represents the sending node, the second node represents the receiving node, which pressure is equal or smaller to the pressure at the sending node times the compression factor.\nLastly, to ensure the balance between incoming/outgoing flows and flows into the linepack, the ratio between the flows need to be fixed. The average incoming flows of the node group (of the pressure start and end nodes) have to equal the flows into the linepack storage, and vice versa. Therefore, the fix_ratio_out_in_connection_flow needs to be set to a value (typically 1) for the (pressure group, linepack storage) node pair, and for the (linepack storage, pressure group) node pair.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"A gas pipeline and its connected nodes are illustrated below. A complete mathematical formulation can be found here.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"(Image: Illustration of gas pipeline)","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_in/","page":"-","title":"-","text":"The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/boolean_value_list/","page":"-","title":"-","text":"A list of boolean values (True or False).","category":"page"},{"location":"concept_reference/frac_state_loss/","page":"-","title":"-","text":"The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.","category":"page"},{"location":"concept_reference/connections_invested_avaiable_coefficient/","page":"-","title":"-","text":"The connections_invested_available_coefficient is an optional parameter that can be used to include the connections_invested_available variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_available_coefficient appears as a coefficient for the connections_invested_available variable in the user constraint.","category":"page"},{"location":"concept_reference/unit_capacity/","page":"-","title":"-","text":"To set an upper bound on the commodity flow of a unit in a certain direction, the unit_capacity constraint needs to be defined on a unit__to_node or unit__from_node relationship. By defining the parameter, the unit_flow variables to or from a node or a group of nodes will be constrained by the capacity constraint.","category":"page"},{"location":"concept_reference/unit_capacity/","page":"-","title":"-","text":"Note that if the unit_capacity parameter is defined on a node group, the sum of all unit_flows within the specified node group will be constrained by the unit_capacity.","category":"page"},{"location":"#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"SpineOpt.jl is an integrated energy systems optimization model, striving towards adaptability for a multitude of modelling purposes. The data-driven model structure allows for highly customizable energy system descriptions, as well as flexible temporal and stochastic structures, without the need to alter the model source code directly. The methodology is based on mixed-integer linear programming (MILP), and SpineOpt relies on JuMP.jl for interfacing with the different solvers.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"While, in principle, it is possible to run SpineOpt by itself, it has been designed to be used through the Spine toolbox, and take maximum advantage of the data and modelling workflow management tools therein. Thus, we highly recommend installing Spine toolbox as well, as outlined in the Installation guide.","category":"page"},{"location":"#Getting-Started","page":"Introduction","title":"Getting Started","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"As the name implies, this chapter contains guides for starting to use SpineOpt.jl for the first time. The Installation links to the guides how to install SpineOpt.jl and Spine Toolbox on your computer. The Setting up a workflow for SpineOpt in Spine Toolbox section explains how to set up and run SpineOpt.jl from Spine Toolbox. The Creating Your Own Model section explains how to create a new model from scratch. This includes a list of the necessary Object Classes and Relationship Classes, but for more information, you will probably need to consult the Concept Reference chapter.","category":"page"},{"location":"#Tutorials","page":"Introduction","title":"Tutorials","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"We learn a lot from examples and that is what you will find in the tutorial chapter. The tutorials come in different shapes: videos, written text and example files. The SpineOpt.jl repository includes a folder examples for ready-made example models. Each example is its own sub-folder, where the input data is provided as .json or .sqlite files. This way, you can easily get a feel for how SpineOpt works with pre-made datasets, either through Spine Toolbox, or directly from the Julia REPL.","category":"page"},{"location":"#How-to","page":"Introduction","title":"How to","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"The other parts of the documentation are good as a reference when you know what you are looking for but this chapter adds explanations on how to do specific high-level things that might involve multiple elements (e.g. how to print the model).","category":"page"},{"location":"#Concept-Reference","page":"Introduction","title":"Concept Reference","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter lists and explains all the important data and model structure related concepts to understand in SpineOpt.jl. For a mathematical modelling point of view, see the Mathematical Formulation chapter instead. The Basics of the model structure section briefly explains the general purpose of the most important concepts, like Object Classes and Relationship Classes. Meanwhile, the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections contain detailed explanations of each and every aspect of SpineOpt.jl, organized into the respective sections for clarity.","category":"page"},{"location":"#Mathematical-Formulation","page":"Introduction","title":"Mathematical Formulation","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter provides the mathematical view of SpineOpt.jl, as some of the methodology-related aspects of the model are more easily understood as math than Julia code. The Variables section explains the purpose of each variable in the model, as well as how the variables are related to the different Object Classes and Relationship Classes. The Constraints section contains the mathematical formulation of each constraint, as well as explanations to their purpose and how they are controlled via different Parameters. Finally, the Objective section explains the default objective function used in SpineOpt.jl.","category":"page"},{"location":"#Advanced-Concepts","page":"Introduction","title":"Advanced Concepts","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter explains some of the more complicated aspects of SpineOpt.jl in more detail, hopefully making it easier for you to better understand and apply them in your own modelling. The first few sections focus on aspects of SpineOpt.jl that most users are likely to use, or which are more or less required to understand for advanced use. The Temporal Framework section explains how defining time works in SpineOpt.jl, and how it can be used for different purposes. The Stochastic Framework section details how different stochastic structures can be defined, how they interact with each other, and how this impacts writing Constraints in SpineOpt.jl. The Unit commitment section explains how clustered unit-commitment is defined, while the Ramping and Reserves sections explain how to enable these operational details in your model. The Investment Optimization section explains how to include investment variables in your models, while the User Constraints section details how to include generic data-driven custom constraints.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"The last few sections focus on highly specialized use-cases for SpineOpt.jl, which are unlikely to be relevant for simple modelling tasks. The Decomposition section explains the Benders decomposition implementation included in SpineOpt.jl, as well as how to use it. The remaining sections, namely PTDF-Based Powerflow, Pressure driven gas transfer, Lossless nodal DC power flows, and Representative days with seasonal storages, explain various use-case specific modelling approaches supported by SpineOpt.jl.","category":"page"},{"location":"#Implementation-details","page":"Introduction","title":"Implementation details","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"For those who are interested in how things work under the hood, this chapter explains some parts of the code. Note that this chapter is particularly sensitive to changes in the code and as such might get out of sync. If you do notice a discrepancy, please create an issue in github. That is also the place to be if you don't find what you are looking for in this documentation.","category":"page"},{"location":"concept_reference/output/","page":"-","title":"-","text":"An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/connection_conv_cap_to_flow/","page":"-","title":"-","text":"The connection_conv_cap_to_flow can be used to perform the conversion between the measurement unit of the connection_capacity to the measurement unit of the connection_flow variable. The default of this parameter is 1, i.e. assuming that both are given in the same measurement unit.","category":"page"},{"location":"concept_reference/max_mga_slack/","page":"-","title":"-","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).","category":"page"},{"location":"concept_reference/max_voltage_angle/","page":"-","title":"-","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), an upper bound on the voltage angle can be introduced through the max_voltage_angle parameter, which triggers the generation of the maximum node voltage angle constraint.","category":"page"},{"location":"concept_reference/stochastic_structure/","page":"-","title":"-","text":"The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.","category":"page"},{"location":"concept_reference/stochastic_structure/","page":"-","title":"-","text":"The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.","category":"page"},{"location":"concept_reference/connections_invested_coefficient/","page":"-","title":"-","text":"The connections_invested_coefficient is an optional parameter that can be used to include the connections_invested variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_coefficient appears as a coefficient for the connections_invested variable in the user constraint.","category":"page"},{"location":"concept_reference/db_lp_solver/","page":"-","title":"-","text":"Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/connection_flow_delay/","page":"-","title":"-","text":"The connection_flow_delay parameter denotes the amount of time that it takes for the flow to go through a connection. In other words, the flow that enters the connection is only seen at the other side after connection_flow_delay units of time.","category":"page"},{"location":"concept_reference/constraint_sense_list/","page":"-","title":"-","text":"The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.","category":"page"},{"location":"concept_reference/parent_stochastic_scenario__child_stochastic_scenario/","page":"-","title":"-","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.","category":"page"},{"location":"concept_reference/parent_stochastic_scenario__child_stochastic_scenario/","page":"-","title":"-","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/connection_linepack_constant/","page":"-","title":"-","text":"The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.","category":"page"},{"location":"concept_reference/db_lp_solver_list/","page":"-","title":"-","text":"List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/temporal_block/","page":"-","title":"-","text":"A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_out/","page":"-","title":"-","text":"The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/fix_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/fix_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/right_hand_side/","page":"-","title":"-","text":"Used to specify the right-hand-side, constant term in a user_constraint. See also user_constraint.","category":"page"},{"location":"concept_reference/model__temporal_block/","page":"-","title":"-","text":"The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/unit_incremental_heat_rate/","page":"-","title":"-","text":"Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.","category":"page"},{"location":"concept_reference/unit_incremental_heat_rate/","page":"-","title":"-","text":"To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/#Lossless-nodal-DC-power-flows","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"","category":"section"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"Currently, there are two different methods to represent lossless DC power flows. In the following the implementation of the nodal model is presented, based of node voltage angles.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/#key-concepts-advanced-nodal-DC","page":"Lossless nodal DC power flows","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"In the following, it is described how to set up a connection in order to represent a nodal lossless DC power flow network. Therefore, key object - and relationship classes as well as parameters are introduced.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"connection: A connection represents the electricity line being modelled. A physical property of a connection is its connection_reactance, which is defined on the connection object. Furthermore, if the reactance is given in a p.u. different from the standard unit used (e.g. p.u. = 100MVA), the parameter connection_reactance_base can be used to perform this conversion.\nnode: In a lossless DC power flow model, nodes correspond to buses. To use voltage angles for the representation of a lossless DC model, the has_voltage_angle needs to be true for these nodes (which will trigger the generation of the node_voltage_angle variable). Limits on the voltage angle can be enforced through the max_voltage_angle and min_voltage_angle parameters. The reference node of the system should have a voltage angle equal to zero, assigned through the parameter fix_node_voltage_angle.\nconnection__to_node and connection__from_node : These relationships need to be introduced between the connection and each node, in order to allow power flows (i.e. connection_flow). Furthermore, a capacity limit on the connection line can be introduced on these relationships through the parameter connection_capacity.\nconnection__node__node: To ensure energy conservation across the power line, a fixed ratio between incoming and outgoing flows should be given. The fix_ratio_out_in_connection_flow parameter enforces a fixed ratio between outgoing flows (i.e. to_node) and incoming flows (i.e. from_node). This parameter should be defined for both flow direction.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"The mathematical formulation of the lossless DC power flow model using voltage angles is fully described here.","category":"page"},{"location":"concept_reference/max_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/max_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/model__default_stochastic_structure/","page":"-","title":"-","text":"The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/db_mip_solver_options/","page":"-","title":"-","text":"MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_mip_solver_options map parameter)","category":"page"},{"location":"concept_reference/connection__from_node__unit_constraint/","page":"-","title":"-","text":"connection__from_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable to the specified connection from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__from_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/storage_investment_lifetime/","page":"-","title":"-","text":"Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/storage_investment_lifetime/","page":"-","title":"-","text":"See also Investment Optimization and candidate_storages","category":"page"},{"location":"concept_reference/unit_flow_coefficient/","page":"-","title":"-","text":"The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/unit_flow_coefficient/","page":"-","title":"-","text":"Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.","category":"page"},{"location":"concept_reference/max_iterations/","page":"-","title":"-","text":"When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.","category":"page"},{"location":"concept_reference/storages_invested_avaiable_coefficient/","page":"-","title":"-","text":"The storages_invested_available_coefficient is an optional parameter that can be used to include the storages_invested_available variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_available_coefficient appears as a coefficient for the storages_invested_available variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/unit_conv_cap_to_flow/","page":"-","title":"-","text":"The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable. ","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"The weight_relative_to_parents parameter defines how much weight the stochastic_scenario gets in the Objective function. As a stochastic_structure__stochastic_scenario relationship parameter, different stochastic_structures can use different weights for the same stochastic_scenario. Note that every stochastic_scenario that appears in the model must have a weight_relative_to_parents defined for it related to the used stochastic_structure! See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.)","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"Since the Stochastic Framework in SpineOpt.jl supports stochastic directed acyclic graphs instead of simple stochastic trees, it is possible to define stochastic_structures with converging stochastic_scenarios. In these cases, the child stochastic_scenarios inherint the weight of all of their parents, and the final weight that will appear in the Objective function is calculated as shown below:","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.","category":"page"},{"location":"concept_reference/unit__investment_stochastic_structure/","page":"-","title":"-","text":"The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.","category":"page"},{"location":"concept_reference/unit__investment_stochastic_structure/","page":"-","title":"-","text":"The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/commodity_physics_duration/","page":"-","title":"-","text":"This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.","category":"page"},{"location":"concept_reference/commodity_physics_duration/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/connection__to_node/","page":"-","title":"-","text":"connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/stochastic_structure__stochastic_scenario/","page":"-","title":"-","text":"The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_out/","page":"-","title":"-","text":"The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/db_mip_solver_list/","page":"-","title":"-","text":"List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.","category":"page"}] +[{"location":"concept_reference/write_mps_file/","page":"-","title":"-","text":"This parameter is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/write_mps_file/","page":"-","title":"-","text":"This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\\_mps\\_on\\_no\\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\\_mps\\_never, no file will be written","category":"page"},{"location":"concept_reference/demand/","page":"-","title":"-","text":"The demand parameter represents a \"demand\" or a \"load\" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as \"demand\" or \"load\" for the modelled system, while negative values provide the system with \"influx\" or \"gain\". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects","category":"page"},{"location":"concept_reference/demand/","page":"-","title":"-","text":"The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.","category":"page"},{"location":"tutorial/simple_system/#Simple-System-tutorial","page":"Simple system","title":"Simple System tutorial","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Welcome to Spine Toolbox's Simple System tutorial.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"This tutorial provides a step-by-step guide to setup a simple energy system on Spine Toolbox.","category":"page"},{"location":"tutorial/simple_system/#Introduction","page":"Simple system","title":"Introduction","text":"","category":"section"},{"location":"tutorial/simple_system/#Model-assumptions","page":"Simple system","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Two power plants take fuel from a source node and release electricity to another node in order to supply a demand.\nPower plant 'a' has a capacity of 100 MWh, a variable operating cost of 25 euro/fuel unit, and generates 0.7 MWh of electricity per unit of fuel.\nPower plant 'b' has a capacity of 200 MWh, a variable operating cost of 50 euro/fuel unit, and generates 0.8 MWh of electricity per unit of fuel.\nThe demand at the electricity node is 150 MWh.\nThe fuel node is able to provide infinite energy.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/#Installation-and-upgrades","page":"Simple system","title":"Installation and upgrades","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"If you haven't yet installed the tools yet, please follow the installation guides: ","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"For Spine Toolbox: Spine Toolbox installation guide\nFor SpineOpt: SpineOpt installation guide","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"For Spine Toolbox:\nIf installed with pipx, then use python -m pipx upgrade spinetoolbox\nIf installed from sources using git, then git pull, python -m pip install -U -r requirements.txt\nFor SpineOpt: SpineOpt upgrade guide","category":"page"},{"location":"tutorial/simple_system/#Guide","page":"Simple system","title":"Guide","text":"","category":"section"},{"location":"tutorial/simple_system/#Entering-input-data","page":"Simple system","title":"Entering input data","text":"","category":"section"},{"location":"tutorial/simple_system/#Importing-the-SpineOpt-database-template","page":"Simple system","title":"Importing the SpineOpt database template","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Download the SpineOpt database template and the basic SpineOpt model (right click on the links, then select Save link as...)\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB editor, looking similar to this:","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nThe Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Press Alt + F to display the main menu, select File -> Import..., and then select the template file you previously downloaded (spineopt_template.json). The contents of that file will be imported into the current database, and you should then see classes like 'commodity', 'connection' and 'model' under the root node in the Object tree (on the left). Then import the second file (basic_model_template.json).\nFrom the main menu, select Session -> Commit. Enter 'Import SpineOpt template' as message in the popup dialog, and click Commit.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nThe SpineOpt basic template contains (i) the fundamental entity classes and parameter definitions that SpineOpt recognizes and expects; and (ii) some predefined entities for a common deterministic model with a 'flat' temporal structure.","category":"page"},{"location":"tutorial/simple_system/#Creating-objects","page":"Simple system","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nRight click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.\nEnter the names for the system nodes as seen in the image below, then press Ok. This will create two objects of class node, called fuel_node and electricity_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the unit class, and select Add objects from the context menu. The Add objects dialog will pop up.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nIn SpineOpt, nodes are points where an energy balance takes place, whereas units are energy conversion devices that can take energy from nodes, and release energy to nodes.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Enter the names for the system units as seen in the image below, then press Ok. This will create two objects of class unit, called power_plant_a and power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nTo modify an object after you enter it, right click on it and select Edit... from the context menu.","category":"page"},{"location":"tutorial/simple_system/#Establishing-relationships","page":"Simple system","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the unit__from_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their sending nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b take energy from the fuel_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into the electricity_node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and unit_flow under output, as seen in the image below; then press Ok. This will tell SpineOpt to write the value of the unit_flow optimization variable to the output database, as part of report1.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"note: Note\nIn SpineOpt, outputs represent optimization variables that can be written to the output database as part of a report.","category":"page"},{"location":"tutorial/simple_system/#Specifying-object-parameter-values","page":"Simple system","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Back to Object tree, expand the node class and select electricity_node.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table (typically at the top-center), select the demand parameter and the Base alternative, and enter the value 100 as seen in the image below. This will establish that there's a demand of '100' at the electricity node.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select fuel_node in the Object tree.\nIn the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that the fuel node is not balanced, and thus provide as much fuel as needed.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/#Specifying-relationship-parameter-values","page":"Simple system","title":"Specifying relationship parameter values","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, expand the unit__from_node class and select power_plant_a | fuel_node.\nIn the Relationship parameter table (typically at the bottom-center), select the vom_cost parameter and the Base alternative, and enter the value 25 as seen in the image below. This will set the operating cost for power_plant_a.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select power_plant_b | fuel_node in the Relationship tree.\nIn the Relationship parameter table, select the vom_cost parameter and the Base alternative, and enter the value 50 as seen in the image below. This will set the operating cost for power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | electricity_node.\nIn the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity for power_plant_a.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select power_plant_b | electricity_node in the Relationship tree.\nIn the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity for power_plant_b.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"In Relationship tree, select the unit__node__node class, and come back to the Relationship parameter table.\nIn the Relationship parameter table, select power_plant_a | electricity_node | fuel_node under object name list, fix_ratio_out_in_unit_flow under parameter name, Base under alternative name, and enter 0.7 under value. Repeat the operation for power_plant_b, but this time enter 0.8 under value. This will set the conversion ratio from fuel to electricity for power_plant_a and power_plant_b to 0.7 and 0.8, respectively. It should like the image below.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/simple_system/#Executing-the-workflow","page":"Simple system","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt 1' Tool. You should see the output from SpineOpt in the Julia Console.","category":"page"},{"location":"tutorial/simple_system/#Examining-the-results","page":"Simple system","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"Select the output data store and open the Spine DB editor.\nPress Alt + F to display the main menu, and select Pivot -> Index.\nSelect report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.\nUnder alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.\nThe Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.","category":"page"},{"location":"tutorial/simple_system/","page":"Simple system","title":"Simple system","text":"(Image: image)","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-renewable-energy-targets","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"This advanced concept illustrates how renewable targets can be realized in SpineOpt. ","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-lower-limits-on-renewable-production","page":"Imposing renewable energy targets","title":"Imposing lower limits on renewable production","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-a-lower-bound-on-the-cumulated-flow-of-a-unit-group-by-an-absolute-value","page":"Imposing renewable energy targets","title":"Imposing a lower bound on the cumulated flow of a unit group by an absolute value","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"In the current landscape of energy systems modeling, especially in investment models, it is a common idea to implement a lower limit on the amount of electricity that is generated by renewable sources. SpineOpt allows the user to implement such restrictions by means of the min_total_cumulated_unit_flow_to_node parameter. Which will trigger the creation of the constraint_total_cumulated_unit_flow.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To impose a limit on overall renewable generation over the entire optimization horizon, the following objects, relationships, and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. electricity generation from wind), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with renewable generation","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing electricity demand. (Note: To distinguish e.g. between regions there can also be more than one electricity node)\nunit__to_node: To associate electricity flows with a unit, the relationship between the unit and the electricity node needs to be imposed, to trigger the generation of a electricity-unit_flow variable.\nmin_total_cumulated_unit_flow_to_node: This parameter triggers a lower bound on all cumulated flows from a unit (or a group of units), e.g. the group of all renewable generators, to a node (or node group).","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Let's take a look at a simple example to see how this works. Suppose that we have a system with only one node, which represents the demand for electricity, and two units: a wind farm, and a conventional gas unit. To connect the wind farm to the electricity node, the unit__to_node relationship has to be defined.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"One can then simply define the min_total_cumulated_unit_flow_to_node parameter for the 'windfarm__toelectricity_node' relationship to impose a lower bound on the total generation origination from the wind farm.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Note that the value of this parameter is expected to be given as an absolute value, thus care has to be taken to make sure that the units match with the ones used for the unit_flow variable.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"The main source of flexibility in the use of this constraint lies in the possibility to define the parameter for relationships that link 'nodegroups' and/or 'unitgroups'. For example, by grouping multiple units that are considered renewable sources (e.g. PV, and wind), targets can be implemented across multiple renewable sources. Similarly, by defining multiple electricity nodes, generation targets can be spatially disagreggated.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Limiting-the-cumulated-flow-of-a-unit-group-by-a-share-of-the-demand","page":"Imposing renewable energy targets","title":"Limiting the cumulated flow of a unit group by a share of the demand","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"For convenience, we want to be able to define the min_total_cumulated_unit_flow_to_node, when used to set a renewable target, as a share of the demand. At the moment an absolute lower bound needs to be provided by the user, but we want to automate this preprocessing in SpineOpt. (to be implemented)","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-limit-on-carbon-emissions","page":"Imposing renewable energy targets","title":"Imposing an upper limit on carbon emissions","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-limit-on-carbon-emissions-over-the-entire-optimization-horizon","page":"Imposing renewable energy targets","title":"Imposing an upper limit on carbon emissions over the entire optimization horizon","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To impose a limit on overall carbon emissions over the entire optimization horizon, the following objects, relationships and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with carbon emissions","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. (Note: To distinguish e.g. between regions there can also be more than one carbon node)\nunit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.\nunit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)\nmax_total_cumulated_unit_flow_to_node (and unit__to_node): This parameter triggers a limit on all flows from a unit (or a group of units), e.g. the group of all conventional generators, to a node (or node groups), e.g. considering the atmosphere as a fictive CO2 node, over the entire modelling horizon (e.g. a carbon budget). For example this could be defined on a relationship between a gasplant and a Carbon node, but can also be defined a unit group of all conventional generators and a carbon node. See also: constraint_total_cumulated_unit_flow","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-an-upper-bound-on-the-cumulated-flows-of-a-unit-group-for-a-specific-period-of-time-(advanced-method)","page":"Imposing renewable energy targets","title":"Imposing an upper bound on the cumulated flows of a unit group for a specific period of time (advanced method)","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"If the desired functionality is not to cap emissions over the entire modelling horizon, but rather for specific periods of time (e.g., to impose decreasing carbon caps over time), an alternative method can be used, which will be described in the following.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To illustrate this functionality, we will assume that there is a ficticious cap of 100 for a period of time 2025-2030, and a cap of 50 for the period of time 2030-2035. In this simple example, we will assume that one carbon-emitting unit carbon_unit is present with two outgoing commodity flows, e.g. here electricity and carbon.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Three nodes are required to represent this system: an electricity node, a carbon_cap_1 node (with has_state=true and node_state_cap=100), and a carbon_cap_2 node (with has_state=true and node_state_cap=50).","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Further we introduce the unit__node__node relationships between carbon_unit__carbon_cap1__electricity and carbon_unit__carbon_cap2__electricity. On these relationships, we will define the ratio between emissions and electricity production. In this fictious example, we will assume 0.5 units of emissions per unit of electricity.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"The fix_ratio_out_out parameter will now be defined as a time varying parameter in the following way (simplified representation of TimeSeries parameter):","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"fix_ratio_out_out(carbon_unit__carbon_cap1__electricity) = [2025: 0.5; 2030: 0] fix_ratio_out_out(carbon_unit__carbon_cap2__electricity) = [2025: 0; 2030: 0.5]","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"This way the first emission-cap node carbon_cap1 can only be \"filled\" during the 2025-2030, while carbon_cap2 can only be \"filled\" during the second period 2030-2035. ","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"Note that it would also be possible to have, e.g., one node with time-varying node_state_cap. However, in this case, \"unused\" carbon emissions in the first period of time would be availble for the second period of time.","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/#Imposing-a-carbon-tax","page":"Imposing renewable energy targets","title":"Imposing a carbon tax","text":"","category":"section"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"To include carbon pricing in a model, the following objects, relationships and parameters are relevant:","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"unit: In this case, a unit represents a process (e.g. conversion of Gas to Electricity), where one","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"or multiple unit_flows are associated with carbon emissions","category":"page"},{"location":"advanced_concepts/cumulated_flow_restrictions/","page":"Imposing renewable energy targets","title":"Imposing renewable energy targets","text":"node and tax_in_unit_flow: Besides from nodes required to denote e.g. a fuel node or a supply node, at least one node should be introduced representing carbon emissions. To associate a carbon-tax with all incoming unit_flows, the tax_in_unit_flow parameter can be defined on this node (Note: To distinguish e.g. between regions there can also be more than one carbon node)\nunit__to_node: To associate carbon flows with a unit, the relationship between the unit and the carbon node needs to be imposed, to trigger the generation of a carbon-unit_flow variable.\nunit__node__node and **fix_ratio_out_out **: Ratio between e.g. output and output unit flows; e.g. how carbon intensive an electricity flow of a unit is. The parameter is defined on a unit__node__node relationship, for example (Gasplant, Carbon, Electricity). (Note: For a full list of possible ratios, see also unit__node__node and associated parameters)","category":"page"},{"location":"getting_started/setup_workflow/#Setting-up-a-workflow-for-SpineOpt-in-Spine-Toolbox","page":"Setting up a workflow","title":"Setting up a workflow for SpineOpt in Spine Toolbox","text":"","category":"section"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"The next steps will set up a SpineOpt specific input database by creating a new Spine database, loading a blank SpineOpt template, connecting it to a SpineOpt instance and setting up a database for model results. ","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Create a new Spine Toolbox project in an empty folder of your choice: File –> New project...\nCreate the input database\nDrag an empty Data store from the toolbar to the Design View. \nGive it a name like \"Input DB\". \nSelect SQL database dialect (sqlite is a local file and works without a server). \nClick New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite).\nFor more information about creating and managing Spine Toolbox database, see the documentation","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Fill the Input DB with SpineOpt data format either by:\nDrag a tool Load template from the SpineOpt ribbon to the Design View. \nConnect an arrow from the Load template to the new Input DB. \nMake sure the Load template item from the Design view is selected (then you can edit the properties of that workflow item in the Tool properties window. \nAdd the url link in Available resources to the Tool arguments - you are passing the database address as a command line argument to the load_template.jl script so that it knows where to store the output. \nThen execute the Load template tool. Please note that this process uses SpineOpt to generate the data structure. It takes time, since everything is compiled when running a tool in Julia for the first time in each Julia session. You may also see lot of messages and warnings concernging the compilation, but they should be benign.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"...or by:\nStart Julia (you can start a separate Julia console in Spine Toolbox: go to Consoles –> Start Julia Console). \nCopy the URL address of the Data Store from the 'Data Store Properties' –> a copy icon at the bottom. \nThen run the following script with the right URL address pasted. The process uses SpineOpt itself to build the database structure. Please note that 'using SpineOpt' for the first time for each Julia session takes time - everything is being compiled.\nKnown issue: On Windows, the backslash between directories need to be changed to a double forward slash.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"julia> using SpineOpt\n\njulia> SpineOpt.import_data(\"copied URL address, inside these quotes\", SpineOpt.template(), \"Load SpineOpt template\")","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Drag SpineOpt tool icon to the Design view. \nConnect an arrow from the Input DB to SpineOpt. ","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Create a database for results\nDrag a new Data store from the toolbar to the Design View. \nYou can rename it to e.g. Results. Select SQL database dialect (sqlite is a local file and works without a server). \nClick New Spine DB in the Data Store Properties window and create a new database (and save it, if it's sqlite). \nConnect an arrow from the SpineOpt to Results.","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"Select SpineOpt tool in the Design view. \nAdd the url link for the input data store and the output data store from Available resources to the Tool arguments (in that order).","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"(Image: image)","category":"page"},{"location":"getting_started/setup_workflow/","page":"Setting up a workflow","title":"Setting up a workflow","text":"SpineOpt would be ready to run, but for the Input DB, which is empty of content (it's just a template that contains a SpineOpt specific data structure). The next step goes through setting up and running a simple toy model.","category":"page"},{"location":"concept_reference/fix_nonspin_units_shut_down/","page":"-","title":"-","text":"The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/fix_nonspin_units_shut_down/","page":"-","title":"-","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/nodal_balance_sense/","page":"-","title":"-","text":"nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.","category":"page"},{"location":"tutorial/case_study_a5/#Case-Study-A5-tutorial","page":"Case Study A5","title":"Case Study A5 tutorial","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Welcome to this Spine Toolbox Case Study tutorial. Case Study A5 is one of the Spine Project case studies designed to verify Toolbox and Model capabilities. To this end, it reproduces an already existing study about hydropower on the Skellefte river, which models one week of operation of the fifteen power stations along the river.","category":"page"},{"location":"tutorial/case_study_a5/#Introduction","page":"Case Study A5","title":"Introduction","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Model-assumptions","page":"Case Study A5","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"For each power station in the river, the following information is known:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The capacity, or maximal electricity output. This datum also provides the maximal water discharge as per the efficiency curve (see next point).\nThe efficiency curve, or conversion rate from water to electricity. In this study, a piece-wise linear efficiency with two segments is assumed. Moreover, this curve is monotonically decreasing, i.e., the efficiency in the first segment is strictly greater than the efficiency in the second segment.\nThe maximal reservoir level (maximal amount of water that can be stored in the reservoir).\nThe reservoir level at the beginning of the simulation period and at the end.\nThe minimal amount of water that the plant must discharge at every hour. This is usually zero (except for one of the plants).\nThe downstream plant, or next plant in the river course.\nThe time that it takes for the water to reach the downstream plant. This time can be different depending on whether the water is discharged (goes through the turbine) or spilled.\nThe local inflow, or amount of water that naturally enters the reservoir at every hour. In this study, it is assumed constant over the entire simulation period.\nThe hourly average water discharge. It is assumed that before the beginning of the simulation, this amount of water has constantly been discharged at every hour.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The system is operated so as to maximize the total profit over the planning week, while respecting capacity constraints, maximal reservoir level constrains, etc. Hourly profit per plant is simply computed as the product of the electricity price and the production.","category":"page"},{"location":"tutorial/case_study_a5/#Modelling-choices","page":"Case Study A5","title":"Modelling choices","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"The model of the electric system is fairly simple, only two elements are needed:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"A common electricity node.\nA load unit that takes electricity from that node.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"On the contrary, the model of the river system is more detailed. Each power station in the river is modelled using the following elements:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"An upper water node, located at the entrance of the station.\nA lower water node, located at the exit of the station.\nA power plant unit, that discharges water from the upper node into the lower node, and feeds electricity produced in the process to the common electricity node.\nA spillway connection, that takes spilled water from the upper node and releases it to the downstream upper node.\nA discharge connection, that takes water from the lower node and releases it to the downstream upper node.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Below is a schematic of the model. For clarity, only the Rebnis station is presented in full detail:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing the spineopt database template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nJust remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Case Study A5’) in the corresponding step, so to not mix up the Spine Toolbox projects!","category":"page"},{"location":"tutorial/case_study_a5/#Importing-the-SpineOpt-database-template","page":"Case Study A5","title":"Importing the SpineOpt database template","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Download the SpineOpt database template (right click on the link, then select Save link as...)\nSelect the input Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB Editor, looking similar to image below. (Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThe Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Press Alt + F to display the editor menu, select File -> Import..., and then select the template file you previously downloaded (in case it is not displayed in the folder where you saved it, double-check that you selected). The contents of that file will be imported into the current database, and you should then see classes like ‘commodity’, ‘connection’ and ‘model’ under the root node in the Object tree (on the left).\nFrom the editor menu (Alt + F), select Session -> Commit. Enter ‘Import SpineOpt template’ as message in the popup dialog, and click Commit.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThe SpineOpt template contains the fundamental object and relationship classes, as well as parameter definitions, that SpineOpt recognizes and expects. You can think of it as the generic structure of the model, as opposed to the specific data for a particular instance. In the remainder of this section, we will add that specific data for the Skellefte river.","category":"page"},{"location":"tutorial/case_study_a5/#Entering-data","page":"Case Study A5","title":"Entering data","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nThere are two options in this tutorial to enter data in the Database. The first one is to enter data manually and the second to use the importer functionality. These are described in the next two subsections respectively and produce similar models. The model created when using the importer creates a model with two-segments efficiency curves for converting water to electricity (while the model created when entering the data manually assumes a simplified efficiency curve with a single segment).","category":"page"},{"location":"tutorial/case_study_a5/#Entering-data-manually","page":"Case Study A5","title":"Entering data manually","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Creating-objects","page":"Case Study A5","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To add power plants to the model, stay in the Spine DB Editor and create objects of class unit as follows:\nSelect the list of plant names from the text-box below and copy it to the clipboard (Ctrl+C)\n Rebnis_pwr_plant\n Sadva_pwr_plant\n Bergnäs_pwr_plant\n Slagnäs_pwr_plant\n Bastusel_pwr_plant\n Grytfors_pwr_plant\n Gallejaur_pwr_plant\n Vargfors_pwr_plant\n Rengård_pwr_plant\n Båtfors_pwr_plant\n Finnfors_pwr_plant\n Granfors_pwr_plant\n Krångfors_pwr_plant\n Selsfors_pwr_plant\n Kvistforsen_pwr_plant\nGo to Object tree (on the top left of the window, usually), right-click on unit and select Add objects from the context menu. This will open the Add objects dialog.\nSelect the first cell under the object name column and press Ctrl+V. This will paste the list of plant names from the clipboard into that column; the object class name column will be filled automatically with ‘unit‘. The form should now be looking similar to this: (Image: image)\nClick Ok.\nBack in the Spine DB Editor, under Object tree, double click on unit to confirm that the objects are effectively there.\nCommit changes with the message ‘Add power plants’.\nAdd discharge and spillway connections by creating objects of class connection with the following names:\nRebnistoBergnäsdisch SadvatoBergnäsdisch BergnästoSlagnäsdisch SlagnästoBastuseldisch BastuseltoGrytforsdisch GrytforstoGallejaurdisch GallejaurtoVargforsdisch VargforstoRengårddisch RengårdtoBåtforsdisch BåtforstoFinnforsdisch FinnforstoGranforsdisch GranforstoKrångforsdisch KrångforstoSelsforsdisch SelsforstoKvistforsendisch Kvistforsentodownstreamdisch RebnistoBergnässpill SadvatoBergnässpill BergnästoSlagnässpill SlagnästoBastuselspill BastuseltoGrytforsspill GrytforstoGallejaurspill GallejaurtoVargforsspill VargforstoRengårdspill RengårdtoBåtforsspill BåtforstoFinnforsspill FinnforstoGranforsspill GranforstoKrångforsspill KrångforstoSelsforsspill SelsforstoKvistforsenspill Kvistforsentodownstreamspill\nAdd water nodes by creating objects of class node with the following names:\nRebnisupper Sadvaupper Bergnäsupper Slagnäsupper Bastuselupper Grytforsupper Gallejaurupper Vargforsupper Rengårdupper Båtforsupper Finnforsupper Granforsupper Krångforsupper Selsforsupper Kvistforsenupper Rebnislower Sadvalower Bergnäslower Slagnäslower Bastusellower Grytforslower Gallejaurlower Vargforslower Rengårdlower Båtforslower Finnforslower Granforslower Krångforslower Selsforslower Kvistforsenlower\nNext, create the following objects (all names in lower-case):\ninstance of class model.\nwater and electricity of class commodity.\nelectricity_node of class node.\nelectricity_load of class unit.\nsome_week of class temporal_block.\ndeterministic of class stochastic_structure.\nrealization of class stochastic_scenario.\nFinally, create the following objects to get results back from SpineOpt (again, all names in lower-case):\nmy_report of class report.\nunit_flow, connection_flow, and node_state of class output.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nTo modify an object after you enter it, right click on it and select Edit... from the context menu.","category":"page"},{"location":"tutorial/case_study_a5/#Specifying-object-parameter-values","page":"Case Study A5","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To specify the general behaviour of our model, stay in the Spine DB Editor and enter model parameter values as follows:\nSelect the model parameter value data (i.e. select all, Ctrl+A) from the file below and copy it to the clipboard (Ctrl+C): cs-a5-model-parameter-values.txt\nSelect instance in the Object tree and inspect the table in Object parameter value (on the top-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order): \n object_class_name | object_name | parameter_name | alternative_name | value | database\nSelect the first cell under object_class_name and press Ctrl+V. This will paste the model parameter value data from the clipboard into the table. The form should be looking like this: (Image: image)\nSpecify the resolution of our temporal block some_week in the same way using the data below: cs-a5-temporal_block-parameter-values.txt\nSpecify the behaviour of all system nodes with the data below, where:\ndemand represents the local inflow (negative in most cases).\nfix_node_state represents fixed reservoir levels (at the beginning and the end).\nhas_state indicates whether or not the node is a reservoir (true for all the upper nodes).\nstate_coeff is the reservoir 'efficienty' (always 1, meaning that there aren't any loses).\nnode_state_cap is the maximum level of the reservoirs.\nTo do this in one single step, simply select node in the Object tree and paste the following values in the first empty cell: cs-a5-node-parameter-values.txt","category":"page"},{"location":"tutorial/case_study_a5/#Establishing-relationships","page":"Case Study A5","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"tip: Tip\nTo enter the same text on several cells, copy the text into the clipboard, then select all target cells and press Ctrl+V.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class unit__from_node to represent that a power plant receives water from the station's upper water node, and that the electricity load takes electricity from the common electricity node. Both the power plants and the electricity load belong to the class unit.\nSelect the list of unit and node names from below and copy it to the clipboard (Ctrl+C). cs-a5-unit__from_node.txt\nIn the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), right-click on unit__from_node and select Add relationships from the context menu. This will open the Add relationships dialog.\nSelect the first cell under the unit column and press Ctrl+V. This will paste the list of plant and node names from the clipboard into the table. The form should be looking like this: (Image: image) \nClick Ok.\nBack in the Spine DB Editor, under Relationship tree, double click on unit__from_node to confirm that the relationships are effectively there.\nFrom the main menu (Alt + F), select Session -> Commit to open the Commit changes dialog. Enter ‘Add from nodes of power plants‘ as the commit message and click Commit.\nCreate relationships of the class unit__to_node to represent that a power plant releases water to the station's lower water node, and that the power plants supply electricity to the common electricity node. Use the following data and do as before: cs-a5-unit__to_node.txt","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nAt this point, you might be wondering what's the purpose of the unit__node__node relationship class. Shouldn't it be enough to have unit__from_node and unit__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the conversion process that happens in the unit, where the water from one node is turned into electricty for another node. And for this purpose, we use a relationship parameter value on the unit__node__node relationships (see Specifying relationship parameter values).","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class connection__from_node to represent that water can be either discharged or spilled. If discharged, it is taken from the lower water node of the station, if spilled it is taken from the upper water node of the station. Use the following data and do as before: cs-a5-connection__from_node.txt\nCreate relationships of the class connection__to_node to represent that both discharge and spill are released into the upper node of the next downstream station. Use the following data and do as before: cs-a5-connection__to_node.txt","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nAt this point, you might be wondering what's the purpose of the connection__node__node relationship class. Shouldn't it be enough to have connection__from_node and connection__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the delay in the river branches. And for this purpose, we use a relationship parameter value on the connection__node__node relationships (see Specifying relationship parameter values).","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Create relationships of the class node__commodity to represent that each node has to be in balance, for water nodes with respect to water, for electricity nodes with respect to electricity. This way, you link all nodes to either the commocity water or the commodity electricity. Use the following data and do as before: cs-a5-node__commodity.txt\nDefine that all nodes in our model have to be balanced at each time step. To do this, you create a relationship of the class model__default_temporal_block between the model instance and the temporalblock `someweek` in the same way as before.\nDefine that our model is deterministic. To do this, you create a relationship of the class model__default_stochastic_structure between the model instance and the stochastic structure deterministic, as well as a relationship of class stochastic_structure__stochastic_scenario between the stochastid structure deterministic and the stochastic scenario realization in the same way as before.\nIn order to get the results from running Spine Opt written to the ouput database, create relationships of the class report__output between the report my_report and each of the following output objects: unit_flow, connection_flow, and node_state. In addition, you also need to create a relationship of the class model__report between the model instance and the report my_report.","category":"page"},{"location":"tutorial/case_study_a5/#Specifying-parameter-values-of-the-relationships","page":"Case Study A5","title":"Specifying parameter values of the relationships","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Finally, the values of all parameters have to be entered. Specify the capacity of all hydropower plants, and their respective variable operating cost by entering unit__from_node parameter values as follows:\nSelect the data from the text-box below and copy it to the clipboard (Ctrl+C): cs-a5-unit__from_node-relationship-parameter-values.txt\nIn the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), and click on unit__from_node. Then, go to Relationship parameter value (on the bottom-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order): \n relationship_class_name | object_name_list | parameter_name | alternative_name | value | database\nSelect the first cell under relationship_class_name and press Ctrl+V. This will paste the parameter value data from the clipboard into the table.\nSpecify the conversion ratio between discharged water and generated electricity for each hydropower station as well as a similar conversion rate (set to 1) to represent that water cannot be lost between upper and lower water nodes. Use the following data to enter the parameter values unit__from_node: cs-a5-unit__node__node-relationship-parameter-values.txt\nSpecify the average discharge and spillage in the first hours of the simulation. Use the following data to enter the parameter values connection__from_node: cs-a5-connection__from_node-relationship-parameter-values.txt\nFinally, specify the delay (the time it takes for the water to run between water nodes) and the transfer ratio (being equal to 1) of different water connections. Use the following data to enter the parameter values connection__node_node: cs-a5-connection__node__node-relationship-parameter-values.txt\nWhen you're ready, commit all changes to the database via the main menu (Alt + F).","category":"page"},{"location":"tutorial/case_study_a5/#Using-the-Importer","page":"Case Study A5","title":"Using the Importer","text":"","category":"section"},{"location":"tutorial/case_study_a5/#Additional-Steps-for-Project-Setup","page":"Case Study A5","title":"Additional Steps for Project Setup","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Drag the Data Connection icon (Image: image) from the tool bar and drop it into the Design View. This will open the Add Data connection dialogue. Type in ‘Data Connection’ and click on Ok.\nTo import the model into the Spine database, you need to create an Import specification. Create an Import specification by clicking on the small arrow next to the Importer item (in the Main section of the toolbar) and press New. The Importer specification editor will pop-up.\nType ‘Import Model’ as the name of the specification. Save the specification by using Ctrl+S and close the window.\nDrag the newly created Import Model Importer item icon (Image: image) from the tool bar and drop it into the Design View. This will open the Add Importer dialogue. Type in ‘Import Model’ and click on Ok.\nConnect ‘Data Connection’ with ‘Import Model’ by first clicking on one of the Data Connection’s connectors and then on one of the Importer’s connectors. Connect similarly the importer with the input database. Now the project should look similar to this: (Image: image)\nFrom the main menu, select File -> Save project.","category":"page"},{"location":"tutorial/case_study_a5/#Importing-the-model","page":"Case Study A5","title":"Importing the model","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Download the data and the accompanying mapping (right click on the links, then select Save link as...).\nAdd a reference to the file containing the model.\nSelect the Data Connection item in the Design View to show the Data Connection properties window (on the right side of the window usually).\nIn Data Connection Properties, click on , click on the icon furthest to the left Add file references and select the previously downloaded Excel file.\nNext, double click on the Import model in the Design view. A window called Select connector for Import Model will pop-up, select Excel and klick OK. Next, still in the Importer specification editor, click on the main menu icon in the top right (or Press Alt + F to automatically display it) and import the mappings previously downloaded (by clicking on Import mappings). Finally, save by clicking Ctrl+S and exit the Importer specification editor.","category":"page"},{"location":"tutorial/case_study_a5/#Executing-the-workflow","page":"Case Study A5","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Once the workflow is defined and input data is in place, the project is ready to be executed. Hit the Execute project button (Image: image) on the tool bar.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"You should see ‘Executing All Directed Acyclic Graphs’ printed in the Event log (on the lower left by default). SpineOpt output messages will appear in the Process Log panel in the middle. After some processing, ‘DAG 1/1 completed successfully’ appears and the execution is complete.","category":"page"},{"location":"tutorial/case_study_a5/#Examining-the-results","page":"Case Study A5","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"Select the output data store and open the Spine DB editor.","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"To checkout the flow on the electricity load (i.e., the total electricity production in the system), go to Object tree, expand the unit object class, and select electricity_load, as illustrated in the picture above. Next, go to Relationship parameter value and double-click the first cell under value. The Parameter value editor will pop up. You should see something like this:","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"(Image: image)","category":"page"},{"location":"tutorial/case_study_a5/","page":"Case Study A5","title":"Case Study A5","text":"note: Note\nIf you have used the importer to instantiate the model you can easily modify the parameters in the model worksheet, run the project and observe the differences in the results. If you need to make changes directly to the input database, in order for the importer not to overwrite them, you will need to dissassociate the importer from the input DB (right click in the connecting yellow arrow between the two items and click on remove).","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/#How-does-the-model-update-itself-after-rolling?","page":"How does the model update itself","title":"How does the model update itself after rolling?","text":"","category":"section"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In SpineOpt, constraints, objective and bounds update themselves automatically whenever the model rolls. To picture this, imagine you have a rolling model with two windows, corresponding to the first and second days of 2023, and daily resolution. (In other words, each window consists of a single time-slice that covers the entire day.) Also, imagine you have a node where the demand is a time-series defined as follows:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"timestamp value\n2023-01-01 5\n2023-01-02 10","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"To simplify things, let's say the nodal balance constraint in SpineOpt has the following form:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"sum of flows entering the node - sum of flows leaving the node == node's demand\n(for each t in the current window)","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"You would expect the rhs of this constraint to be 5 for the first window, and 10 for the second window. That is indeed the case, but the way this works under the hood is quite 'magical' so to say.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In SpineOpt, the rhs of the above constraint would be written (roughly) using the following julia expression:","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"demand[(node=n, t=t, more arguments...)]","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Notice the brackets ([]) around the named-tuple with the arguments. Without these (i.e., demand(node=n, t=t, more arguments...)) the expression would evaluate to a number, and the constraint would be static (non-self-updating). But with the brackets, instead of a number, the expression evaluates to a special object of type Call. The important thing about the Call is it remembers the arguments, including the t.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Right before the constraint is passed to the solver, SpineOpt 'realizes' the Call with the current value of t, and computes the actual rhs. So for the first window, where t is the first day in 2023, it will be 5.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"Now, whenever SpineOpt rolls forward to solve the next window, it updates the value of t by adding the roll_forward value. (This allows SpineOpt to reuse the same time-slices in all the windows.) But when this happens, the Call is also checked to see if it would return something different now that t has been rolled. And if that's the case, the constraint is automatically updated to reflect the change. In our example, the rhs would become 10 because t is now the second day.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"In sum, without the brackets, the constraint would be lhs == 5 (and it would never change), whereas with the brackets, the constraint becomes lhs == the demand at the current value of t.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"And the above is valid not only for rhs, but also for any coefficient in any constraint or objective, and for any variable bound.","category":"page"},{"location":"implementation_details/how_does_the_model_update_itself/","page":"How does the model update itself","title":"How does the model update itself","text":"To see how all this is actually implemented, we suggest you to look at the code of SpineInterface. The starting point is the implementation of Base.getindex for the Parameter type so that writing, e.g., demand[...arguments...] returns a Call that remembers the arguments. From then, we proceed to extend JuMP.jl to handle our Call objects within constraints and objective. The last bit is perhaps the most complex, and consists in storing callbacks inside TimeSlice objects whenever they are used to retrieve the value of a Parameter to build a model. The callbacks are carefully crafted to update a specific part of that model (e.g., a variable coefficient, a variable bound, a constraint rhs). Whenever the TimeSlice rolls, depending on how much it rolls, the appropriate callbacks are called resulting in the model being properly updated. That's roughly it! Hopefully this brief introduction helps (but please contact us if you need more guidance).","category":"page"},{"location":"concept_reference/unit__unit_constraint/","page":"-","title":"-","text":"unit__user_constraint is a two-dimensional relationship between a unit and a user_constraint. The relationship specifies that a variable or variable(s) associated only with the unit (not a unit_flow for example) are involved in the constraint. For example, the units_on_coefficient defined on unit__user_constraint specifies the coefficient of the unit's units_on variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/unit__unit_constraint/","page":"-","title":"-","text":"See also user_constraint","category":"page"},{"location":"concept_reference/max_gap/","page":"-","title":"-","text":"This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"To use representative periods in your model, do the following:","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.\nDefine a set of temporal_block objects, each corresponding to one representative period.\nSpecify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.\nAssociate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.","category":"page"},{"location":"concept_reference/representative_periods_mapping/","page":"-","title":"-","text":"See also Representative days with seasonal storages.","category":"page"},{"location":"concept_reference/operating_cost/","page":"-","title":"-","text":"By defining the operating_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for operating costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/connection_resistance/","page":"-","title":"-","text":"The per unit resistance of a transmission line. Currently unimplemented!","category":"page"},{"location":"concept_reference/db_mip_solver/","page":"-","title":"-","text":"Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_standard uses the standard algorithm.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_benders uses the Benders decomposition algorithm (see Decomposition.","category":"page"},{"location":"concept_reference/model_type/","page":"-","title":"-","text":"spineopt_mga uses the Model to Generate Alternatives algorithm.","category":"page"},{"location":"concept_reference/units_on_cost/","page":"-","title":"-","text":"By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.","category":"page"},{"location":"concept_reference/compression_factor/","page":"-","title":"-","text":"This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.","category":"page"},{"location":"concept_reference/connection_type_list/","page":"-","title":"-","text":"connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details","category":"page"},{"location":"concept_reference/model__default_investment_stochastic_structure/","page":"-","title":"-","text":"The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/units_started_up_coefficient/","page":"-","title":"-","text":"The units_started_up_coefficient is an optional parameter that can be used to include the units_started_up variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_started_up_coefficient appears as a coefficient for the units_started_up variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/minimum_operating_point/","page":"-","title":"-","text":"The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.","category":"page"},{"location":"concept_reference/minimum_operating_point/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/units_on_coefficient/","page":"-","title":"-","text":"The units_on_coefficient is an optional parameter that can be used to include the units_on variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_on_coefficient appears as a coefficient for the units_on variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/curtailment_cost/","page":"-","title":"-","text":"By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"diff_coeff(node1=n1, node2=n2),","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways","category":"page"},{"location":"concept_reference/diff_coeff/","page":"-","title":"-","text":"diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/ramp_down_limit/","page":"-","title":"-","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/fix_storages_invested/","page":"-","title":"-","text":"Used primarily to fix the value of the storages_invested variable which represents the point-in-time storage investment decision variable at a node and how many candidate storages are invested-in in a particular timeslice at the corresponding node.","category":"page"},{"location":"concept_reference/fix_storages_invested/","page":"-","title":"-","text":"See also Investment Optimization, candidate_storages and storage_investment_variable_type","category":"page"},{"location":"concept_reference/shut_down_cost/","page":"-","title":"-","text":"By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/node__temporal_block/","page":"-","title":"-","text":"This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.","category":"page"},{"location":"concept_reference/node__temporal_block/","page":"-","title":"-","text":"For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.","category":"page"},{"location":"concept_reference/tax_in_unit_flow/","page":"-","title":"-","text":"By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/min_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_out/","page":"-","title":"-","text":"The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/unit__node__node/","page":"-","title":"-","text":"While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.","category":"page"},{"location":"concept_reference/unit__node__node/","page":"-","title":"-","text":"In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.","category":"page"},{"location":"concept_reference/fix_unit_flow_op/","page":"-","title":"-","text":"If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.","category":"page"},{"location":"concept_reference/connection__investment_stochastic_structure/","page":"-","title":"-","text":"The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.","category":"page"},{"location":"concept_reference/connection__investment_stochastic_structure/","page":"-","title":"-","text":"The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/upward_reserve/","page":"-","title":"-","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/fix_units_on/","page":"-","title":"-","text":"The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.","category":"page"},{"location":"concept_reference/unit__from_node/","page":"-","title":"-","text":"It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/unit_availability_factor/","page":"-","title":"-","text":"To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.","category":"page"},{"location":"concept_reference/fix_connections_invested_available/","page":"-","title":"-","text":"The fix_connections_invested_available parameter represents a forced connection investment.","category":"page"},{"location":"concept_reference/fix_connections_invested_available/","page":"-","title":"-","text":"In other words, it is the fix value of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/stochastic_scenario/","page":"-","title":"-","text":"Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.","category":"page"},{"location":"tutorial/webinars/#Webinars","page":"Webinars","title":"Webinars","text":"","category":"section"},{"location":"tutorial/webinars/","page":"Webinars","title":"Webinars","text":"SpinOpt tutorial covers the entire process from installing Spine Toolbox and SpineOpt, creating and running a model with these tools and manipulating databases.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_in/","page":"-","title":"-","text":"The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows. ","category":"page"},{"location":"concept_reference/Parameters/#Parameters","page":"Parameters","title":"Parameters","text":"","category":"section"},{"location":"concept_reference/Parameters/#balance_type","page":"Parameters","title":"balance_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for how the :nodal_balance constraint should be handled.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: balance_type_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: balance_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_connections_invested","page":"Parameters","title":"benders_starting_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of connections invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_storages_invested","page":"Parameters","title":"benders_starting_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of storages invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#benders_starting_units_invested","page":"Parameters","title":"benders_starting_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the number of units invested during the first Benders iteration","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#big_m","page":"Parameters","title":"big_m","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Sufficiently large number used for linearization bilinear terms, e.g. to enforce bidirectional flow for gas pipielines","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1000000","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.","category":"page"},{"location":"concept_reference/Parameters/#block_end","page":"Parameters","title":"block_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The end time for the temporal_block. Can be given either as a DateTime for a static end point, or as a Duration for an end point relative to the start of the current optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.","category":"page"},{"location":"concept_reference/Parameters/#block_start","page":"Parameters","title":"block_start","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The start time for the temporal_block. Can be given either as a DateTime for a static start point, or as a Duration for an start point relative to the start of the current optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.","category":"page"},{"location":"concept_reference/Parameters/#candidate_connections","page":"Parameters","title":"candidate_connections","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The number of connections that may be invested in","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The candidate_connections parameter denotes the possibility of investing on a certain connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value of nothing means that the connection can't be invested in, because it's already in operation. An integer value represents the maximum investment possible at any point in time, as a factor of the connection_capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In other words, candidate_connections is the upper bound of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/Parameters/#candidate_storages","page":"Parameters","title":"candidate_storages","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the maximum number of new storages which may be invested in","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and storage_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#candidate_units","page":"Parameters","title":"candidate_units","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Number of units which may be additionally constructed","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#commodity_lodf_tolerance","page":"Parameters","title":"commodity_lodf_tolerance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum absolute value of the line outage distribution factor (LODF) that is considered meaningful.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/Parameters/#commodity_physics","page":"Parameters","title":"commodity_physics","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines if the commodity follows lodf or ptdf physics.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: commodity_physics_none","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: commodity_physics_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#commodity_physics_duration","page":"Parameters","title":"commodity_physics_duration","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For how long the commodity_physics should apply relative to the start of the window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#commodity_ptdf_threshold","page":"Parameters","title":"commodity_ptdf_threshold","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum absolute value of the power transfer distribution factor (PTDF) that is considered meaningful.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.001","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/Parameters/#compression_factor","page":"Parameters","title":"compression_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The compression factor establishes a compression from an origin node to a receiving node, which are connected through a connection. The first node corresponds to the origin node, the second to the (compressed) destination node. Typically the value is >=1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is specific to the use of pressure driven gas transfer. To represent a compression between two nodes in the gas network, the compression_factor can be defined. This factor ensures that the pressure of a node is equal to (or lower than) the pressure at the sending node times the compression_factor. The relationship connection__node__node that hosts this parameter should be defined in a way that the first node represents the origin node and the second node represents the compressed node.","category":"page"},{"location":"concept_reference/Parameters/#connection_availability_factor","page":"Parameters","title":"connection_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability of the connection, acting as a multiplier on its connection_capacity. Typically between 0-1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.","category":"page"},{"location":"concept_reference/Parameters/#connection_capacity","page":"Parameters","title":"connection_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limits the connection_flow variable to the to_node. to_node can be a group of nodes, in which case the sum of the connection_flow is constrained.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.","category":"page"},{"location":"concept_reference/Parameters/#connection_contingency","page":"Parameters","title":"connection_contingency","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for defining a contingency connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#connection_conv_cap_to_flow","page":"Parameters","title":"connection_conv_cap_to_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for connection_capacity unit conversions in the case the connection_capacity value is incompatible with the desired connection_flow units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_conv_cap_to_flow can be used to perform the conversion between the measurement unit of the connection_capacity to the measurement unit of the connection_flow variable. The default of this parameter is 1, i.e. assuming that both are given in the same measurement unit.","category":"page"},{"location":"concept_reference/Parameters/#connection_emergency_capacity","page":"Parameters","title":"connection_emergency_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The maximum post-contingency flow on a monitored connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_emergency_capacity parameter represents the maximum post-contingency flow on a monitored connection if ptdf and lodf based security constrained unit commitment is enabled (commodity_physics is set to [commodity_physics_lodf]).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If you set this value, make sure that you also set connection_monitored to true for the involved connection.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_coefficient","page":"Parameters","title":"connection_flow_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"defines the user constraint coefficient on the connection flow variable in the to direction","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node__user_constraint and connection__to_node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_flow_coefficient is an optional parameter that can be used to include the connection_flow variable from or to a node in a user_constraint via the connection__from_node__user_constraint and connection__to_node__user_constraint relationships. Essentially, connection_flow_coefficient appears as a coefficient for the connection_flow variable from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_cost","page":"Parameters","title":"connection_flow_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable costs of a flow through a connection. E.g. EUR/MWh of energy throughput.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_delay","page":"Parameters","title":"connection_flow_delay","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Delays the connection_flows associated with the latter node in respect to the connection_flows associated with the first node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"0h\", \"type\" => \"duration\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_flow_delay parameter denotes the amount of time that it takes for the flow to go through a connection. In other words, the flow that enters the connection is only seen at the other side after connection_flow_delay units of time.","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_non_anticipativity_margin","page":"Parameters","title":"connection_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which connection_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_flow_non_anticipativity_time","page":"Parameters","title":"connection_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the connection_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_intact_flow_non_anticipativity_margin","page":"Parameters","title":"connection_intact_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which connection_intact_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_intact_flow_non_anticipativity_time","page":"Parameters","title":"connection_intact_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the connection_intact_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_cost","page":"Parameters","title":"connection_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit investment cost for the connection over the connection_investment_lifetime","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_lifetime","page":"Parameters","title":"connection_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the minimum investment lifetime of a connection. Once invested, it remains in service for this long","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/#connection_investment_variable_type","page":"Parameters","title":"connection_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether the investment variable is integer variable_type_integer or continuous variable_type_continuous","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: variable_type_integer","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.","category":"page"},{"location":"concept_reference/Parameters/#connection_linepack_constant","page":"Parameters","title":"connection_linepack_constant","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The linepack constant is a property of gas pipelines and relates the linepack to the pressure of the adjacent nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.","category":"page"},{"location":"concept_reference/Parameters/#connection_monitored","page":"Parameters","title":"connection_monitored","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for defining a contingency connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When using ptdf-based load flow by setting commodity_physics to either commodity_physics_ptdf or commodity_physics_ptdf, a constraint is created for each connection for which connection_monitored = true. Thus, to monitor the ptdf-based flow on a particular connection connection_monitored must be set to true.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow","category":"page"},{"location":"concept_reference/Parameters/#connection_reactance","page":"Parameters","title":"connection_reactance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit reactance of a connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node. ","category":"page"},{"location":"concept_reference/Parameters/#connection_reactance_base","page":"Parameters","title":"connection_reactance_base","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If the reactance is given for a p.u. (e.g. p.u. = 100MW), the connection_reactance_base can be set to perform this conversion (e.g. *100).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"As the connection_reactance is often given on a per unit basis, often different than the units used elsewhere, the connection_reactance_base parameter serves as a conversion factor, scaling the connection_reactance with its p.u..","category":"page"},{"location":"concept_reference/Parameters/#connection_resistance","page":"Parameters","title":"connection_resistance","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit resistance of a connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The per unit resistance of a transmission line. Currently unimplemented!","category":"page"},{"location":"concept_reference/Parameters/#connection_type","page":"Parameters","title":"connection_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector between a normal and a lossless bidirectional connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: connection_type_normal","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: connection_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"relationship: connection__from_node\nrelationship: connection__to_node\nparameter: connection_capacity (defined on connection__from_node and/or connection__to_node)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"reciprocal connection__from_node and connection__to_node relationships are created if they don't exist\na new connection__node__node relationship is created if none exists already\nfix_ratio_out_in_connection_flow parameter is created with the value of 1 if no existing parameter found (therefore this value can be overridden)\nThe first connection_capacity parameter found is copied to connection__from_nodes and connection__to_nodes without a defined connection_capacity.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_available_coefficient","page":"Parameters","title":"connections_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of connections_invested_available in the specific user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_big_m_mga","page":"Parameters","title":"connections_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate connections.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_coefficient","page":"Parameters","title":"connections_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of connections_invested in the specific user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_coefficient is an optional parameter that can be used to include the connections_invested variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_coefficient appears as a coefficient for the connections_invested variable in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_mga","page":"Parameters","title":"connections_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: connections_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The connections_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of connections_invested_mga is set to true, investment decisions in this connection, or group of connections, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#connections_invested_mga_weight","page":"Parameters","title":"connections_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weightd sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#constraint_sense","page":"Parameters","title":"constraint_sense","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for the sense of the user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: ==","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: constraint_sense_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The constraint_sense parameter determines the sense of a custom user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See User constraints for details.","category":"page"},{"location":"concept_reference/Parameters/#curtailment_cost","page":"Parameters","title":"curtailment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs for curtailing generation. Essentially, accrues costs whenever unit_flow not operating at its maximum available capacity. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the curtailment_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit's available capacity exceeds its activity (i.e., the unit_flow variable) over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#cyclic_condition","page":"Parameters","title":"cyclic_condition","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If the cyclic condition is set to true for a storage node, the node_state at the end of the optimization window has to be larger than or equal to the initial storage state.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The cyclic_condition parameter is used to enforce that the storage level at the end of the optimization window is higher or equal to the storage level at the beginning optimization. If the cyclic_condition parameter is set to true for a node__temporal_block relationship, and the has_state parameter of the corrresponding node is set to true, the constraint_cyclic_node_state will be triggered.","category":"page"},{"location":"concept_reference/Parameters/#db_lp_solver","page":"Parameters","title":"db_lp_solver","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Solver for MIP problems. Solver package must be added and pre-configured in Julia. Overrides lp_solver RunSpineOpt kwarg","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: HiGHS.jl","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: db_lp_solver_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/Parameters/#db_lp_solver_options","page":"Parameters","title":"db_lp_solver_options","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map parameter containing LP solver option name option value pairs. See solver documentation for supported solver options","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => Any[Any[\"HiGHS.jl\", Dict{String, Any}(\"data\" => Any[Any[\"presolve\", \"on\"], Any[\"timelimit\", 300.01]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"Clp.jl\", Dict{String, Any}(\"data\" => Any[Any[\"LogLevel\", 0.0]], \"type\" => \"map\", \"indextype\" => \"str\")]], \"type\" => \"map\", \"indextype\" => \"str\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_lp_solver_options map parameter)","category":"page"},{"location":"concept_reference/Parameters/#db_mip_solver","page":"Parameters","title":"db_mip_solver","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Solver for MIP problems. Solver package must be added and pre-configured in Julia. Overrides mip_solver RunSpineOpt kwarg","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: HiGHS.jl","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: db_mip_solver_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the Julia solver package to be used to solve Mixed Integer Programming Problems (MIPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Cbc.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support MIP problems. Solver options are specified using the db_mip_solver_options parameter for the model. Note also that if run_spineopt() is called with the mip_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/Parameters/#db_mip_solver_options","page":"Parameters","title":"db_mip_solver_options","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map parameter containing MIP solver option name option value pairs for MIP. See solver documentation for supported solver options","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => Any[Any[\"HiGHS.jl\", Dict{String, Any}(\"data\" => Any[Any[\"presolve\", \"on\"], Any[\"miprelgap\", 0.01], Any[\"threads\", 0.0], Any[\"timelimit\", 300.01]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"Cbc.jl\", Dict{String, Any}(\"data\" => Any[Any[\"ratioGap\", 0.01], Any[\"logLevel\", 0.0]], \"type\" => \"map\", \"indextype\" => \"str\")], Any[\"CPLEX.jl\", Dict{String, Any}(\"data\" => Any[Any[\"CPXPARAMEPGAP\", 0.01]], \"type\" => \"map\", \"indextype\" => \"str\")]], \"type\" => \"map\", \"index_type\" => \"str\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_mip_solver_options map parameter)","category":"page"},{"location":"concept_reference/Parameters/#demand","page":"Parameters","title":"demand","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Demand for the commodity of a node. Energy gains can be represented using negative demand.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand parameter represents a \"demand\" or a \"load\" of a commodity on a node. It appears in the node injection constraint, with positive values interpreted as \"demand\" or \"load\" for the modelled system, while negative values provide the system with \"influx\" or \"gain\". When the node is part of a group, the fractional_demand parameter can be used to split demand into fractions, when desired. See also: Introduction to groups of objects","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand parameter can also be included in custom user_constraints using the demand_coefficient parameter for the node__user_constraint relationship.","category":"page"},{"location":"concept_reference/Parameters/#demand_coefficient","page":"Parameters","title":"demand_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"coefficient of the specified node's demand in the specified user constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The demand_coefficient is an optional parameter that can be used to include the demand of the a node in a user_constraint via the node__user_constraint relationship. Essentially, demand_coefficient appears as a coefficient for the demand parameter of the connected node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#diff_coeff","page":"Parameters","title":"diff_coeff","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Commodity diffusion coefficient between two nodes. Effectively, denotes the diffusion power per unit of state from the first node to the second.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The diff_coeff parameter represents diffusion of a commodity between the two nodes in the node__node relationship. It appears as a coefficient on the node_state variable in the node injection constraint, essentially representing diffusion power per unit of state. Note that the diff_coeff is interpreted as one-directional, meaning that if one defines","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"diff_coeff(node1=n1, node2=n2),","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"there will only be diffusion from n1 to n2, but not vice versa. Symmetric diffusion is likely used in most cases, requiring defining the diff_coeff both ways","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"diff_coeff(node1=n1, node2=n2) == diff_coeff(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/Parameters/#downward_reserve","page":"Parameters","title":"downward_reserve","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Identifier for nodes providing downward reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/Parameters/#duration_unit","page":"Parameters","title":"duration_unit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the base temporal unit of the model. Currently supported values are either an hour or a minute.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: hour","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: duration_unit_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"concept_reference/Parameters/#equal_investments","page":"Parameters","title":"equal_investments","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether all entities in the group must have the same investment decision.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#fix_binary_gas_connection_flow","page":"Parameters","title":"fix_binary_gas_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_flow_binary variable, and hence pre-determine the direction of flow in the connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The binary flow of a gas pipelines for pressure driven gas transfer is enables through the binary variable binary_gas_connection_flow and the big_m constant. To fix this binary variable, i.e. pre-define the direction of gas through the pipelines, the fix_binary_gas_connection_flow parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_connection_flow","page":"Parameters","title":"fix_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connection_flow parameter fixes the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/#fix_connection_intact_flow","page":"Parameters","title":"fix_connection_intact_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the connection_intact_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connection_intact_flow parameter can be used to fix the values of the connection_intact_flow variable to preset values. If set to a Scalar type value, the connection_intact_flow variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/Parameters/#fix_connections_invested","page":"Parameters","title":"fix_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connections_invested variable accordingly","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connections_invested parameter can be used to fix the values of the connections_invested variable to preset values. If set to a Scalar type value, the connections_invested variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See Investment Optimization for more information about the investment framework in SpineOpt.jl.","category":"page"},{"location":"concept_reference/Parameters/#fix_connections_invested_available","page":"Parameters","title":"fix_connections_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connectionsinvestedavailable variable accordingly","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_connections_invested_available parameter represents a forced connection investment.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In other words, it is the fix value of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_pressure","page":"Parameters","title":"fix_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_pressure variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_state","page":"Parameters","title":"fix_node_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_state variable to the provided value. Can be used for e.g. fixing boundary conditions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.","category":"page"},{"location":"concept_reference/Parameters/#fix_node_voltage_angle","page":"Parameters","title":"fix_node_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixes the corresponding node_voltage_angle variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.","category":"page"},{"location":"concept_reference/Parameters/#fix_nonspin_units_shut_down","page":"Parameters","title":"fix_nonspin_units_shut_down","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the nonspin_units_shut_down variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_nonspin_units_shut_down parameter simply fixes the value of the nonspin_units_shut_down variable to the provided value. As such, it determines directly how many member units are involved in providing downward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_nonspin_units_started_up","page":"Parameters","title":"fix_nonspin_units_started_up","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the nonspin_units_started_up variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_in_in_unit_flow","page":"Parameters","title":"fix_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_in_out_unit_flow","page":"Parameters","title":"fix_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_in_connection_flow","page":"Parameters","title":"fix_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_in_unit_flow","page":"Parameters","title":"fix_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#fix_ratio_out_out_unit_flow","page":"Parameters","title":"fix_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#fix_storages_invested","page":"Parameters","title":"fix_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to fix the value of the storages_invested variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the storages_invested variable which represents the point-in-time storage investment decision variable at a node and how many candidate storages are invested-in in a particular timeslice at the corresponding node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_storages and storage_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_storages_invested_available","page":"Parameters","title":"fix_storages_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to fix the value of the storagesinvestedavailable variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also candidate_storages and Investment Optimization","category":"page"},{"location":"concept_reference/Parameters/#fix_unit_flow","page":"Parameters","title":"fix_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.","category":"page"},{"location":"concept_reference/Parameters/#fix_unit_flow_op","page":"Parameters","title":"fix_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the unit_flow_op variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If operating_points is defined on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub-variables, unit_flow_op one for each operating point, with an additional index, i to reference the specific operating point. fix_unit_flow_op can thus be used to fix the value of one or more of the variables as desired.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_invested","page":"Parameters","title":"fix_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_invested variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the units_invested variable which represents the point-in-time unit investment decision variable and how many candidate units are invested-in in a particular timeslice.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_units_invested_available","page":"Parameters","title":"fix_units_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_invested_available variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on","page":"Parameters","title":"fix_units_on","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fix the value of the units_on variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on parameter simply fixes the value of the units_on variable to the provided value. As such, it determines directly how many members of the specific unit will be online throughout the model when a single value is selected. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_in_in","page":"Parameters","title":"fix_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_in_out","page":"Parameters","title":"fix_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the fix_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_out and max_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_out_in","page":"Parameters","title":"fix_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the fix_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_in and max_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#fix_units_on_coefficient_out_out","page":"Parameters","title":"fix_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the fix_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#fixed_pressure_constant_0","page":"Parameters","title":"fixed_pressure_constant_0","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed pressure points for pipelines for the outer approximation of the Weymouth approximation. The direction of flow is the first node in the relationship to the second node in the relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/Parameters/#fixed_pressure_constant_1","page":"Parameters","title":"fixed_pressure_constant_1","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed pressure points for pipelines for the outer approximation of the Weymouth approximation. The direction of flow is the first node in the relationship to the second node in the relationship.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/Parameters/#fom_cost","page":"Parameters","title":"fom_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Fixed operation and maintenance costs of a unit. Essentially, a cost coefficient on the existing units (incl. number_of_units and units_invested_available) and unit_capacity parameters. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.","category":"page"},{"location":"concept_reference/Parameters/#forced_availability_factor","page":"Parameters","title":"forced_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability factor due to outages/deratings.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection and unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#frac_state_loss","page":"Parameters","title":"frac_state_loss","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Self-discharge coefficient for node_state variables. Effectively, represents the loss power per unit of state.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.","category":"page"},{"location":"concept_reference/Parameters/#fractional_demand","page":"Parameters","title":"fractional_demand","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The fraction of a node group's demand applied for the node in question.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whenever a node is a member of a group, the fractional_demand parameter represents its share of the group's demand.","category":"page"},{"location":"concept_reference/Parameters/#fuel_cost","page":"Parameters","title":"fuel_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable fuel costs than can be attributed to a unit_flow. E.g. EUR/MWh","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#graph_view_position","page":"Parameters","title":"graph_view_position","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"An optional setting for tweaking the position of the different elements when drawing them via Spine Toolbox Graph View.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection, node and unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node, connection__to_node, unit__from_node__user_constraint, unit__from_node, unit__to_node__user_constraint and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.","category":"page"},{"location":"concept_reference/Parameters/#has_binary_gas_flow","page":"Parameters","title":"has_binary_gas_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter needs to be set to true in order to represent bidirectional pressure drive gas transfer.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.","category":"page"},{"location":"concept_reference/Parameters/#has_pressure","page":"Parameters","title":"has_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_pressure variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here","category":"page"},{"location":"concept_reference/Parameters/#has_state","page":"Parameters","title":"has_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.","category":"page"},{"location":"concept_reference/Parameters/#has_voltage_angle","page":"Parameters","title":"has_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node has a node_voltage_angle variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here","category":"page"},{"location":"concept_reference/Parameters/#initial_binary_gas_connection_flow","page":"Parameters","title":"initial_binary_gas_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_flow_binary variable, and hence pre-determine the direction of flow in the connection.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connection_flow","page":"Parameters","title":"initial_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connection_intact_flow","page":"Parameters","title":"initial_connection_intact_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the connection_intact_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__from_node and connection__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connections_invested","page":"Parameters","title":"initial_connections_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connections_invested variable at the beginning","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_connections_invested_available","page":"Parameters","title":"initial_connections_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Setting a value fixes the connectionsinvestedavailable variable at the beginning","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: connection","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_pressure","page":"Parameters","title":"initial_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_pressure variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_state","page":"Parameters","title":"initial_node_state","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_state variable to the provided value.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_node_voltage_angle","page":"Parameters","title":"initial_node_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initializes the corresponding node_voltage_angle variable to the provided value","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_nonspin_units_shut_down","page":"Parameters","title":"initial_nonspin_units_shut_down","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the nonspin_units_shut_down variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_nonspin_units_started_up","page":"Parameters","title":"initial_nonspin_units_started_up","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the nonspin_units_started_up variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_storages_invested","page":"Parameters","title":"initial_storages_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to initialze the value of the storages_invested variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_storages_invested_available","page":"Parameters","title":"initial_storages_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to initialze the value of the storagesinvestedavailable variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_unit_flow","page":"Parameters","title":"initial_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_unit_flow_op","page":"Parameters","title":"initial_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the unit_flow_op variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_invested","page":"Parameters","title":"initial_units_invested","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_invested variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_invested_available","page":"Parameters","title":"initial_units_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_invested_available variable","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#initial_units_on","page":"Parameters","title":"initial_units_on","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Initialize the value of the units_on variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#is_active","page":"Parameters","title":"is_active","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If false, the object is excluded from the model if the tool filter object activity control is specified","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: true","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity, connection, model, node, output, report, stochastic_scenario, stochastic_structure, temporal_block, unit and user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__stochastic_structure, node__temporal_block, unit__from_node, unit__to_node, units_on__stochastic_structure and units_on__temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not. ","category":"page"},{"location":"concept_reference/Parameters/#is_non_spinning","page":"Parameters","title":"is_non_spinning","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node is acting as a non-spinning reserve","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/Parameters/#is_renewable","page":"Parameters","title":"is_renewable","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether the unit is renewable - used in the minimum renewable generation constraint within the Benders master problem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.","category":"page"},{"location":"concept_reference/Parameters/#is_reserve_node","page":"Parameters","title":"is_reserve_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether a node is acting as a reserve_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/Parameters/#max_cum_in_unit_flow_bound","page":"Parameters","title":"max_cum_in_unit_flow_bound","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Set a maximum cumulative upper bound for a unit_flow","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)","category":"page"},{"location":"concept_reference/Parameters/#max_gap","page":"Parameters","title":"max_gap","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the maximum optimality gap for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.05","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This determines the optimality convergence criterion and is the benders gap tolerance for the master problem in a decomposed investments model. The benders gap is the relative difference between the current objective function upper bound(zupper) and lower bound (zlower) and is defined as 2*(zupper-zlower)/(zupper + zlower). When this value is lower than max_gap the benders algorithm will terminate having achieved satisfactory optimality.","category":"page"},{"location":"concept_reference/Parameters/#max_iterations","page":"Parameters","title":"max_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the maximum number of iterations for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 10.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.","category":"page"},{"location":"concept_reference/Parameters/#max_mga_iterations","page":"Parameters","title":"max_mga_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Define the number of mga iterations, i.e. how many alternative solutions will be generated.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.","category":"page"},{"location":"concept_reference/Parameters/#max_mga_slack","page":"Parameters","title":"max_mga_slack","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the maximum slack by which the alternative solution may differ from the original solution (e.g. 5% more than initial objective function value)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.05","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).","category":"page"},{"location":"concept_reference/Parameters/#max_node_pressure","page":"Parameters","title":"max_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum allowed gas pressure at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), an upper bound on the pressure can be introduced through the max_node_pressure parameter, which triggers the generation of the maxmimum node pressure constraint.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_in_in_unit_flow","page":"Parameters","title":"max_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_in_out_unit_flow","page":"Parameters","title":"max_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_in_connection_flow","page":"Parameters","title":"max_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_in_unit_flow","page":"Parameters","title":"max_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#max_ratio_out_out_unit_flow","page":"Parameters","title":"max_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#max_total_cumulated_unit_flow_from_node","page":"Parameters","title":"max_total_cumulated_unit_flow_from_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the maximum cumulated flows of a unit group from a node group e.g max consumption of certain commodity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#max_total_cumulated_unit_flow_to_node","page":"Parameters","title":"max_total_cumulated_unit_flow_to_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the maximum cumulated flows of a unit group to a node group, e.g. total GHG emissions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_in_in","page":"Parameters","title":"max_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_in_out","page":"Parameters","title":"max_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_out_in","page":"Parameters","title":"max_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#max_units_on_coefficient_out_out","page":"Parameters","title":"max_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the max_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#max_voltage_angle","page":"Parameters","title":"max_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum allowed voltage angle at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), an upper bound on the voltage angle can be introduced through the max_voltage_angle parameter, which triggers the generation of the maximum node voltage angle constraint.","category":"page"},{"location":"concept_reference/Parameters/#maximum_capacity_invested_available","page":"Parameters","title":"maximum_capacity_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Upper bound on the capacity invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#maximum_entities_invested_available","page":"Parameters","title":"maximum_entities_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Upper bound on the number of entities invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_down_time","page":"Parameters","title":"min_down_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum downtime of a unit after it shuts down.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/Parameters/#min_iterations","page":"Parameters","title":"min_iterations","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the minimum number of iterations for the model. Currently only used for the master problem within a decomposed structure","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_node_pressure","page":"Parameters","title":"min_node_pressure","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum allowed gas pressure at node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), a lower bound on the pressure can be introduced through the min_node_pressure parameter, which triggers the generation of the minimum node pressure constraint.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_in_in_unit_flow","page":"Parameters","title":"min_ratio_in_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between two unit_flows coming into the unit from the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_in_out_unit_flow","page":"Parameters","title":"min_ratio_in_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an incoming unit_flow from the first node and an outgoing unit_flow to the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_in_connection_flow","page":"Parameters","title":"min_ratio_out_in_connection_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an outgoing connection_flow to the first node and an incoming connection_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: connection__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_in_unit_flow","page":"Parameters","title":"min_ratio_out_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between an outgoing unit_flow to the first node and an incoming unit_flow from the second node.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the [min_ratio_out_in_unit_flow] parameter triggers the generation of the constraint_min_ratio_out_in_unit_flow and corresponds to a lower bound of the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce e.g. a minimum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the min_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/Parameters/#min_ratio_out_out_unit_flow","page":"Parameters","title":"min_ratio_out_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio between two unit_flows going from the unit into the two nodes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/Parameters/#min_total_cumulated_unit_flow_from_node","page":"Parameters","title":"min_total_cumulated_unit_flow_from_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the minimum cumulated flows of a unit group from a node group.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows. ","category":"page"},{"location":"concept_reference/Parameters/#min_total_cumulated_unit_flow_to_node","page":"Parameters","title":"min_total_cumulated_unit_flow_to_node","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Bound on the minimum cumulated flows of a unit group to a node group, e.g. total renewable production.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/Parameters/#min_unit_flow","page":"Parameters","title":"min_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Set lower bound of the unit_flow variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_in_in","page":"Parameters","title":"min_units_on_coefficient_in_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_in_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_in_out","page":"Parameters","title":"min_units_on_coefficient_in_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_in_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_out_in","page":"Parameters","title":"min_units_on_coefficient_out_in","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_out_in_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/Parameters/#min_units_on_coefficient_out_out","page":"Parameters","title":"min_units_on_coefficient_out_out","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for the units_on variable impacting the min_ratio_out_out_unit_flow constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/Parameters/#min_up_time","page":"Parameters","title":"min_up_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum uptime of a unit after it starts up.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/Parameters/#min_voltage_angle","page":"Parameters","title":"min_voltage_angle","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum allowed voltage angle at node. ","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), a lower bound on the pressure can be introduced through the min_voltage_angle parameter, which triggers the generation of the minimum node voltage angle constraint.","category":"page"},{"location":"concept_reference/Parameters/#minimum_capacity_invested_available","page":"Parameters","title":"minimum_capacity_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Lower bound on the capacity invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#minimum_entities_invested_available","page":"Parameters","title":"minimum_entities_invested_available","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Lower bound on the number of entities invested available in the group at any point in time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: investment_group","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#minimum_operating_point","page":"Parameters","title":"minimum_operating_point","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum level for the unit_flow relative to the units_on online capacity.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the minimum_operating_point parameter will trigger the creation of the Constraint on minimum operating point. It sets a lower bound on the value of the unit_flow variable for a unit that is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/Parameters/#minimum_reserve_activation_time","page":"Parameters","title":"minimum_reserve_activation_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration a certain reserve product needs to be online/available","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves","category":"page"},{"location":"concept_reference/Parameters/#model_end","page":"Parameters","title":"model_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the last timestamp to be modelled. Rolling optimization terminates after passing this point.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"2000-01-02T00:00:00\", \"type\" => \"date_time\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/Parameters/#model_start","page":"Parameters","title":"model_start","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines the first timestamp to be modelled. Relative temporal_blocks refer to this value for their start and end.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"2000-01-01T00:00:00\", \"type\" => \"date_time\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/Parameters/#model_type","page":"Parameters","title":"model_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to identify model objects as relating to the master problem or operational sub problems (default)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: spineopt_standard","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: model_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter controls the low-level algorithm that SpineOpt uses to solve the underlying optimization problem. Currently three values are possible:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_standard uses the standard algorithm.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_benders uses the Benders decomposition algorithm (see Decomposition.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"spineopt_mga uses the Model to Generate Alternatives algorithm.","category":"page"},{"location":"concept_reference/Parameters/#mp_min_res_gen_to_demand_ratio","page":"Parameters","title":"mp_min_res_gen_to_demand_ratio","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum ratio of renewable generation to demand for this commodity - used in the minimum renewable generation constraint within the Benders master problem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A unit can be marked as a renewable generation source by setting is_renewable to true.","category":"page"},{"location":"concept_reference/Parameters/#mp_min_res_gen_to_demand_ratio_slack_penalty","page":"Parameters","title":"mp_min_res_gen_to_demand_ratio_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Penalty for violating the minimum renewable generation to demand ratio.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: commodity","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.","category":"page"},{"location":"concept_reference/Parameters/#nodal_balance_sense","page":"Parameters","title":"nodal_balance_sense","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for nodal_balance constraint sense.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: ==","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: constraint_sense_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"nodal_balance_sense determines whether or not a node is able to naturally consume or produce energy. The default value, ==, means that the node is unable to do any of that, and thus it needs to be perfectly balanced. The vale >= means that the node is a sink, that is, it can consume any amounts of energy. The value <= means that the node is a source, that is, it can produce any amounts of energy.","category":"page"},{"location":"concept_reference/Parameters/#node_opf_type","page":"Parameters","title":"node_opf_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for the reference node (slack bus) when PTDF-based DC load-flow is enabled.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: node_opf_type_normal","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: node_opf_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to identify the reference node (or slack bus) when ptdf based dc load flow is enabled (commodity_physics set to commodity_physics_ptdf or commodity_physics_lodf. To identify the reference node, set node_opf_type = :node_opf_type_reference","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also powerflow.","category":"page"},{"location":"concept_reference/Parameters/#node_slack_penalty","page":"Parameters","title":"node_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty cost for node_slack_pos and node_slack_neg variables. The slack variables won't be included in the model unless there's a cost defined for them.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.","category":"page"},{"location":"concept_reference/Parameters/#node_state_cap","page":"Parameters","title":"node_state_cap","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The maximum permitted value for a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.","category":"page"},{"location":"concept_reference/Parameters/#node_state_coefficient","page":"Parameters","title":"node_state_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's state variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_coefficient is an optional parameter that can be used to include the node_state variable of a node in a user_constraint via the node__user_constraint relationship. Essentially, node_state_coefficient appears as a coefficient for the node_state variable of the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#node_state_min","page":"Parameters","title":"node_state_min","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The minimum permitted value for a node_state variable.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The node_state_min parameter sets the lower bound for the node_state variable, if one has been enabled by the has_state parameter. For reserve nodes with minimum_reserve_activation_time, the node_state_min is considered also via a special constraint.","category":"page"},{"location":"concept_reference/Parameters/#number_of_units","page":"Parameters","title":"number_of_units","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Denotes the number of 'sub units' aggregated to form the modelled unit.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The default value for this parameter is 1.","category":"page"},{"location":"concept_reference/Parameters/#online_variable_type","page":"Parameters","title":"online_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for how the units_on variable is represented within the model.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: unit_online_variable_type_linear","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: unit_online_variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values \"unit_online_variable_type_binary\", \"unit_online_variable_type_integer\", \"unit_online_variable_type_linear\" and \"unit_online_variable_type_none\".","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment). ","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\\_online\\_variable\\_type\\_integer.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If unit\\_online\\_variable\\_type\\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.","category":"page"},{"location":"concept_reference/Parameters/#operating_points","page":"Parameters","title":"operating_points","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Decomposes the flow variable into a number of separate operating segment variables. Used to in conjunction with unit_incremental_heat_rate and/or user_constraints","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#ordered_unit_flow_op","page":"Parameters","title":"ordered_unit_flow_op","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether the segments of this unit flow are ordered as per the rank of their operating points.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.","category":"page"},{"location":"concept_reference/Parameters/#output_db_url","page":"Parameters","title":"output_db_url","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Database url for SpineOpt output.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: report","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.","category":"page"},{"location":"concept_reference/Parameters/#output_resolution","page":"Parameters","title":"output_resolution","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Temporal resolution of the output variables associated with this output.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: output","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The output_resolution parameter indicates the resolution at which output values should be reported.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.","category":"page"},{"location":"concept_reference/Parameters/#overwrite_results_on_rolling","page":"Parameters","title":"overwrite_results_on_rolling","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Whether or not results from further windows should overwrite results from previous ones.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: true","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: report__output","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.","category":"page"},{"location":"concept_reference/Parameters/#ramp_down_limit","page":"Parameters","title":"ramp_down_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limit the maximum ramp-down rate of an online unit, given as a fraction of the unitcapacity. [rampdown_limit] = %/t, e.g. 0.2/h","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the ramp_down_limit parameter limits the maximum decrease in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/Parameters/#ramp_up_limit","page":"Parameters","title":"ramp_up_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Limit the maximum ramp-up rate of an online unit, given as a fraction of the unitcapacity. [rampup_limit] = %/t, e.g. 0.2/h","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/Parameters/#representative_periods_mapping","page":"Parameters","title":"representative_periods_mapping","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Map from date time to representative temporal block name","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specifies the names of temporal_block objects to use as representative periods for certain time ranges. This indicates the model to define operational variables only for those representative periods, and map variables from normal periods to representative ones. The idea behind this is to reduce the size of the problem by using a reduced set of variables, when one knows that some reduced set of time periods can be representative for a larger one.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that only operational variables other than node_state are sensitive to this parameter. In other words, the model always create node_state variables and investment variables for all time periods, regardless of whether or not representative_periods_mapping is specified for any temporal_block.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To use representative periods in your model, do the following:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Define one temporal_block for the 'normal' periods as you would do if you weren't using representative periods.\nDefine a set of temporal_block objects, each corresponding to one representative period.\nSpecify representative_periods_mapping for the 'normal' temporal_block as a map, from consecutive date-time values to the name of a representative temporal_block.\nAssociate all the above temporal_block objects to elements in your model (e.g., via node__temporal_block and/or units_on__temporal_block relationships), to map their operational variables from normal periods, to the variable from the representative period.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Representative days with seasonal storages.","category":"page"},{"location":"concept_reference/Parameters/#reserve_procurement_cost","page":"Parameters","title":"reserve_procurement_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Procurement cost for reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#resolution","page":"Parameters","title":"resolution","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Temporal resolution of the temporal_block. Essentially, divides the period between block_start and block_end into TimeSlices with the input resolution.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: Dict{String, Any}(\"data\" => \"1h\", \"type\" => \"duration\")","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.","category":"page"},{"location":"concept_reference/Parameters/#right_hand_side","page":"Parameters","title":"right_hand_side","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The right-hand side, constant term in a user_constraint. Can be time-dependent and used e.g. for complicated efficiency approximations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to specify the right-hand-side, constant term in a user_constraint. See also user_constraint.","category":"page"},{"location":"concept_reference/Parameters/#roll_forward","page":"Parameters","title":"roll_forward","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines how much the model moves ahead in time between solves in a rolling optimization. Without this parameter, everything is solved in as a single optimization.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.","category":"page"},{"location":"concept_reference/Parameters/#shut_down_cost","page":"Parameters","title":"shut_down_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs of shutting down a 'sub unit', e.g. EUR/shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the shut_down_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit shuts down over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#shut_down_limit","page":"Parameters","title":"shut_down_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ramp-down during shutdowns","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/#start_up_cost","page":"Parameters","title":"start_up_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Costs of starting up a 'sub unit', e.g. EUR/startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#start_up_limit","page":"Parameters","title":"start_up_limit","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum ramp-up during startups","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Parameters/#state_coeff","page":"Parameters","title":"state_coeff","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Represents the commodity content of a node_state variable in respect to the unit_flow and connection_flow variables. Essentially, acts as a coefficient on the node_state variable in the :node_injection constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.","category":"page"},{"location":"concept_reference/Parameters/#stochastic_scenario_end","page":"Parameters","title":"stochastic_scenario_end","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A Duration for when a stochastic_scenario ends and its child_stochastic_scenarios start. Values are interpreted relative to the start of the current solve, and if no value is given, the stochastic_scenario is assumed to continue indefinitely.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_cost","page":"Parameters","title":"storage_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines the investment cost per unit state_cap over the investment life of a storage","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_lifetime","page":"Parameters","title":"storage_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum lifetime for storage investment decisions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_storages","category":"page"},{"location":"concept_reference/Parameters/#storage_investment_variable_type","page":"Parameters","title":"storage_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether the storage investment variable is continuous (usually representing capacity) or integer (representing discrete units invested)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: variable_type_integer","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_storages.","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_available_coefficient","page":"Parameters","title":"storages_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's storages invested available variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_big_m_mga","page":"Parameters","title":"storages_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate storages.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_coefficient","page":"Parameters","title":"storages_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the specified node's storage investment variable in the specified user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_coefficient is an optional parameter that can be used to include the storages_invested variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_coefficient appears as a coefficient for the storages_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_mga","page":"Parameters","title":"storages_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: storages_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#storages_invested_mga_weight","page":"Parameters","title":"storages_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weighted-sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#tax_in_unit_flow","page":"Parameters","title":"tax_in_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for incoming unit_flows on this node. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_in_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction to_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#tax_net_unit_flow","page":"Parameters","title":"tax_net_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for net incoming and outgoing unit_flows on this node. Incoming flows accrue positive net taxes, and outgoing flows accrue negative net taxes.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.","category":"page"},{"location":"concept_reference/Parameters/#tax_out_unit_flow","page":"Parameters","title":"tax_out_unit_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Tax costs for outgoing unit_flows from this node. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#unit_availability_factor","page":"Parameters","title":"unit_availability_factor","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Availability of the unit, acting as a multiplier on its unit_capacity. Typically between 0-1.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To indicate that a unit is only available to a certain extent or at certain times of the optimization, the unit_availability_factor can be used. A typical use case could be an availability timeseries for a variable renewable energy source. By default the availability factor is set to 1. The availability is, among others, used in the constraint_units_available.","category":"page"},{"location":"concept_reference/Parameters/#unit_capacity","page":"Parameters","title":"unit_capacity","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Maximum unit_flow capacity of a single 'sub_unit' of the unit.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To set an upper bound on the commodity flow of a unit in a certain direction, the unit_capacity constraint needs to be defined on a unit__to_node or unit__from_node relationship. By defining the parameter, the unit_flow variables to or from a node or a group of nodes will be constrained by the capacity constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that if the unit_capacity parameter is defined on a node group, the sum of all unit_flows within the specified node group will be constrained by the unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#unit_conv_cap_to_flow","page":"Parameters","title":"unit_conv_cap_to_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Optional coefficient for unit_capacity unit conversions in the case the unit_capacity value is incompatible with the desired unit_flow units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable. ","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_coefficient","page":"Parameters","title":"unit_flow_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a unit_flow variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node__user_constraint and unit__to_node__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_non_anticipativity_margin","page":"Parameters","title":"unit_flow_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which unit_flow variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#unit_flow_non_anticipativity_time","page":"Parameters","title":"unit_flow_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the unit_flow variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#unit_idle_heat_rate","page":"Parameters","title":"unit_idle_heat_rate","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Flow from node1 per unit time and per units_on that results in no additional flow to node2","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/Parameters/#unit_incremental_heat_rate","page":"Parameters","title":"unit_incremental_heat_rate","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Standard piecewise incremental heat rate where node1 is assumed to be the fuel and node2 is assumed to be electriciy. Assumed monotonically increasing. Array type or single coefficient where the number of coefficients must match the dimensions of unit_operating_points","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_cost","page":"Parameters","title":"unit_investment_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Investment cost per 'sub unit' built.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_lifetime","page":"Parameters","title":"unit_investment_lifetime","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Minimum lifetime for unit investment decisions.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/Parameters/#unit_investment_variable_type","page":"Parameters","title":"unit_investment_variable_type","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Determines whether investment variable is integer or continuous.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: unit_investment_variable_type_continuous","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: unit_investment_variable_type_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/Parameters/#unit_start_flow","page":"Parameters","title":"unit_start_flow","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Flow from node1 that is incurred when a unit is started up.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__node__node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/Parameters/#units_invested_available_coefficient","page":"Parameters","title":"units_invested_available_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the units_invested_available variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_invested_big_m_mga","page":"Parameters","title":"units_invested_big_m_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"bigmmga should be chosen as small as possible but sufficiently large. For unitsinvestedmga an appropriate bigmmga would be twice the candidate units.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)","category":"page"},{"location":"concept_reference/Parameters/#units_invested_coefficient","page":"Parameters","title":"units_invested_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of the units_invested variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_coefficient is an optional parameter that can be used to include the units_invested variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_coefficient appears as a coefficient for the units_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/Parameters/#units_invested_mga","page":"Parameters","title":"units_invested_mga","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Defines whether a certain variable (here: units_invested) will be considered in the maximal-differences of the mga objective","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/Parameters/#units_invested_mga_weight","page":"Parameters","title":"units_invested_mga_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Used to scale mga variables. For weightd sum mga method, the length of this weight given as an Array will determine the number of iterations.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_on_coefficient","page":"Parameters","title":"units_on_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a units_on variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_on_coefficient is an optional parameter that can be used to include the units_on variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_on_coefficient appears as a coefficient for the units_on variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#units_on_cost","page":"Parameters","title":"units_on_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Objective function coefficient on units_on. An idling cost, for example","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the units_on_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit is online over the current optimization window. It can be used to represent an idling cost or any fixed cost incurred when a unit is online.","category":"page"},{"location":"concept_reference/Parameters/#units_on_non_anticipativity_margin","page":"Parameters","title":"units_on_non_anticipativity_margin","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Margin by which units_on variable can differ from the value in the previous window during non_anticipativity_time.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#units_on_non_anticipativity_time","page":"Parameters","title":"units_on_non_anticipativity_time","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Period of time where the value of the units_on variable has to be fixed to the result from the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: unit","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This is intended to model \"slow\" units whose commitment decision needs to be taken in advance, e.g., in \"day-ahead\" mode, and cannot be changed afterwards.","category":"page"},{"location":"concept_reference/Parameters/#units_started_up_coefficient","page":"Parameters","title":"units_started_up_coefficient","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Coefficient of a units_started_up variable for a custom user_constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 0.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The units_started_up_coefficient is an optional parameter that can be used to include the units_started_up variable of a unit in a user_constraint via the unit__user_constraint relationship. Essentially, units_started_up_coefficient appears as a coefficient for the units_started_up variable of the unit in the user constraint.","category":"page"},{"location":"concept_reference/Parameters/#upward_reserve","page":"Parameters","title":"upward_reserve","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Identifier for nodes providing upward reserves","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/Parameters/#user_constraint_slack_penalty","page":"Parameters","title":"user_constraint_slack_penalty","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A penalty for violating a user constraint.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: user_constraint","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#version","page":"Parameters","title":"version","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't).","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 9","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: settings","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#vom_cost","page":"Parameters","title":"vom_cost","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Variable operating costs of a unit_flow variable. E.g. EUR/MWh.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: unit__from_node and unit__to_node","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/Parameters/#weight","page":"Parameters","title":"weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Weighting factor of the temporal block associated with the objective function","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: temporal_block","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so. ","category":"page"},{"location":"concept_reference/Parameters/#weight_relative_to_parents","page":"Parameters","title":"weight_relative_to_parents","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight of the stochastic_scenario in the objective function relative to its parents.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1.0","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Relationship Classes: stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight_relative_to_parents parameter defines how much weight the stochastic_scenario gets in the Objective function. As a stochastic_structure__stochastic_scenario relationship parameter, different stochastic_structures can use different weights for the same stochastic_scenario. Note that every stochastic_scenario that appears in the model must have a weight_relative_to_parents defined for it related to the used stochastic_structure! See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Since the Stochastic Framework in SpineOpt.jl supports stochastic directed acyclic graphs instead of simple stochastic trees, it is possible to define stochastic_structures with converging stochastic_scenarios. In these cases, the child stochastic_scenarios inherint the weight of all of their parents, and the final weight that will appear in the Objective function is calculated as shown below:","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.","category":"page"},{"location":"concept_reference/Parameters/#window_duration","page":"Parameters","title":"window_duration","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The duration of the window in case it differs from roll_forward","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"TODO","category":"page"},{"location":"concept_reference/Parameters/#window_weight","page":"Parameters","title":"window_weight","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The weight of the window in the rolling subproblem","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: 1","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"To use weighted rolling representative periods Benders, do the following.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.\nSpecify window_weight as an array of n + 1 floating point values, representing the weight of each window.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Note that it the problem rolls n times, then you have n + 1 windows.","category":"page"},{"location":"concept_reference/Parameters/#write_lodf_file","page":"Parameters","title":"write_lodf_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether the LODF values should be written to a results file.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/Parameters/#write_mps_file","page":"Parameters","title":"write_mps_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A selector for writing an .mps file of the model.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: write_mps_file_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"This parameter controls when to write a diagnostic model file in MPS format. If set to write_mps_always, the model will always be written in MPS format to the current directory. If set to write\\_mps\\_on\\_no\\_solve, the MPS file will be written when the model solve terminates with a status of false. If set to write\\_mps\\_never, no file will be written","category":"page"},{"location":"concept_reference/Parameters/#write_ptdf_file","page":"Parameters","title":"write_ptdf_file","text":"","category":"section"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"A boolean flag for whether the LODF values should be written to a results file.","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Default value: false","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Uses Parameter Value Lists: boolean_value_list","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"Related Object Classes: model","category":"page"},{"location":"concept_reference/Parameters/","page":"Parameters","title":"Parameters","text":"If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/unit__to_node__unit_constraint/","page":"-","title":"-","text":"unit__to_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable from the specified unit to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__to_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"Used to control specific pre-processing actions on connections. Currently, the primary purpose of connection_type is to simplify the data that is required to define a simple bi-directional, lossless line. If connection_type=:connection_type_lossless_bidirectional, it is only necessary to specify the following minimum data:","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"relationship: connection__from_node\nrelationship: connection__to_node\nparameter: connection_capacity (defined on connection__from_node and/or connection__to_node)","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"If connection_type=:connection_type_lossless_bidirectional the following pre-processing actions are taken:","category":"page"},{"location":"concept_reference/connection_type/","page":"-","title":"-","text":"reciprocal connection__from_node and connection__to_node relationships are created if they don't exist\na new connection__node__node relationship is created if none exists already\nfix_ratio_out_in_connection_flow parameter is created with the value of 1 if no existing parameter found (therefore this value can be overridden)\nThe first connection_capacity parameter found is copied to connection__from_nodes and connection__to_nodes without a defined connection_capacity.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"If you want to change the solver for your optimization problem in SpineOpt, here is some guidance:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"You can change the solvers in your input datastore using the db_lp_solver and db_mip_solver parameter values of the model object.\nYou can specify solver options via the db_lp_solver_options and db_mip_solver_options parameters respectively. These are map parameters where the first key is the solver name exactly as the db_mip_solver or db_lp_solver name, the second key is the solver option name and the value is the option value.\nYou can get a head start by copying the default map values for db_lp_solver_options and db_mip_solver_options. You can access the default values by clicking on the 'Object parameter definition' tab.\nIf you were trying to change the solver using the arguments to run_spineopt(), this is not the recommended way and will soon be deprecated.\nThe solver name corresponds to the name of the Julia package that you will need to install. Some like HiGHs.jl are self contained and include the binaries. Others like CPLEX.jl and Gurobi.jl you will need to point the package to your locally installed binaries - the julia packages have the instructions to do this.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"The first option is the easiest. The more advanced way of using the solver options is illustrated below.","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"Set the model parameter values to choose the solvers and set the solver options:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"This is what the solver options map parameter value looks like:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"To get a head start with solver options, you can copy their default map values from the parameter definition tab like this:","category":"page"},{"location":"how_to/change_the_solver/","page":"Change the solver","title":"Change the solver","text":"(Image: image)","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.","category":"page"},{"location":"concept_reference/unit__to_node/","page":"-","title":"-","text":"It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/connection_investment_cost/","page":"-","title":"-","text":"By defining the connection_investment_cost parameter for a specific connection, a cost term will be added to the objective function whenever a connection investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/min_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_in_out_unit_flow parameter triggers the generation of the constraint_min_ratio_in_out_unit_flow and enforces a lower bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes, see) in this relationship represents the from_node, i.e. the incoming flow to the unit, and the second node (or group of nodes) represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio_slack_penalty/","page":"-","title":"-","text":"A penalty for violating the mp_min_res_gen_to_demand_ratio. If set, then the lower bound on the fraction of the total system demand that must be supplied by RES becomes a 'soft' constraint. A new cost term is added to the objective, mutlitplying the penalty by the slack.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#Representative-days-with-seasonal-storages","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In order to reduce the problem size, representative periods are often used in optimization models. However, this often limits the ability to properly account for seasonal storages.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In SpineOpt, we provide functionality to use representative days with seasonal storages.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#general_idea_rep_period_seasonal_Storage","page":"Representative days with seasonal storages","title":"General idea","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"The general idea is to mimick the seasonal effects throughout a non-representative period, e.g. a year of optimization, by introducing a specific sequence of the representative periods.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/#Usage_rep_period_seasonal_Storage","page":"Representative days with seasonal storages","title":"Usage of representative days and seasonal storages for investment problems","text":"","category":"section"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"Assuming you already have an investment model with a certain temporal structure that works, you can turn it into a representative periods model with the following steps.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"Identify the nodes and units whose flows and statuses you want to model using representative periods, as well as their associated temporal_blocks.\nSelect the representative periods. For example if you are modelling a year, you can select a few weeks (one in summer, one in winder, and one in mid season).\nFor each representative period, create a temporal_block specifying block_start, block_end and resolution.\nAssociate these temporal_blocks to the nodes and units identified in step 1, via node__temporal_block and units_on__temporal_block relationships.\nFinally, for each original temporal_block associated to these nodes and units (those identified in step 1), specify the value of the representative_periods_mapping parameter. This should be a map where each entry associates a date-time to the name of one of the representative period temporal_blocks created in step 3. More specifically, an entry with t as the key and b as the value means that time slices from the original block starting at t, are 'represented' by time slices from the b block. In other words, time slices between t and t plus the duration of b are represented by b.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"In SpineOpt, this will be interpreted in the following way:","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"All operational variables, with the exception of the node_state variable, will be created only for the representative periods. For the non-representative periods, SpineOpt will use the variable of the corresponding representative period according to the value of the representative_periods_mapping parameter.\nThe node_state variable and the investment variables will be created for all periods, representative and non-representative.","category":"page"},{"location":"advanced_concepts/representative_days_w_seasonal_storage/","page":"Representative days with seasonal storages","title":"Representative days with seasonal storages","text":"The SpinePeriods.jl package provides an alternative, perhaps simpler way to setup a representative periods model based on the automatic selection and ordering of periods.","category":"page"},{"location":"concept_reference/unit_investment_cost/","page":"-","title":"-","text":"By defining the unit_investment_cost parameter for a specific unit, a cost term will be added to the objective function whenever a unit investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/number_of_units/","page":"-","title":"-","text":"Defines how many members a certain unit object represents. Typically this parameter takes a binary (UC) or integer (clustered UC) value. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). It is possible to allow the model to increase the number_of_units itself, through Investment Optimization","category":"page"},{"location":"concept_reference/number_of_units/","page":"-","title":"-","text":"The default value for this parameter is 1.","category":"page"},{"location":"concept_reference/is_renewable/","page":"-","title":"-","text":"A boolean value indicating whether a unit is a renewable energy source (RES). If true, then the unit contributes to the share of the demand that is supplied by RES in the context of mp_min_res_gen_to_demand_ratio.","category":"page"},{"location":"concept_reference/_example/","page":"-","title":"-","text":"AN EXAMPLE DESCRIPTION FOR HOW THE AUTOGENERATION OF CONCEPT REFERENCE BASED ON SPINEOPT TEMPLATE WORKS","category":"page"},{"location":"concept_reference/_example/","page":"-","title":"-","text":"References to other sections, e.g. node are handled like this. Don't use the grave accents around the reference name, as it breaks the reference! Grave accents in Documenter.jl refer to docstrings in the code instead of sections in the documentation.","category":"page"},{"location":"concept_reference/start_up_cost/","page":"-","title":"-","text":"By defining the start_up_cost parameter for a specific unit, a cost term will be added to the objective function whenever this unit starts up over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/report__output/","page":"-","title":"-","text":"The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/storages_invested_coefficient/","page":"-","title":"-","text":"The storages_invested_coefficient is an optional parameter that can be used to include the storages_invested variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_coefficient appears as a coefficient for the storages_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/output_db_url/","page":"-","title":"-","text":"The output_db_url parameter is the url of the databse to write the results of the model run. It overrides the value of the second argument passed to run_spineopt.","category":"page"},{"location":"concept_reference/connection_reactance_base/","page":"-","title":"-","text":"As the connection_reactance is often given on a per unit basis, often different than the units used elsewhere, the connection_reactance_base parameter serves as a conversion factor, scaling the connection_reactance with its p.u..","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"concept_reference/user_constraint/","page":"-","title":"-","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"concept_reference/units_on__stochastic_structure/","page":"-","title":"-","text":"The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.","category":"page"},{"location":"concept_reference/units_on__stochastic_structure/","page":"-","title":"-","text":"The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/is_non_spinning/","page":"-","title":"-","text":"By setting the parameter is_non_spinning to true, a node is treated as a non-spinning reserve node. Note that this is only to differentiate spinning from non-spinning reserves. It is still necessary to set is_reserve_node to true. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/node__stochastic_structure/","page":"-","title":"-","text":"The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.","category":"page"},{"location":"concept_reference/node__stochastic_structure/","page":"-","title":"-","text":"The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/tax_net_unit_flow/","page":"-","title":"-","text":"By defining the tax_net_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with the net total of all unit_flow variables with the direction to_node for this specific node minus all unit_flow variables with direction from_node.","category":"page"},{"location":"concept_reference/report/","page":"-","title":"-","text":"A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/model_start/","page":"-","title":"-","text":"Together with the model_end parameter, it is used to define the temporal horizon of the model. For a single solve optimization, it marks the timestamp from which the relative offset in a temporal_block is defined by the block_start parameter. In the rolling optimization framework, it does this for the first optimization window.","category":"page"},{"location":"concept_reference/model_start/","page":"-","title":"-","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/constraint_sense/","page":"-","title":"-","text":"The constraint_sense parameter determines the sense of a custom user constraint.","category":"page"},{"location":"concept_reference/constraint_sense/","page":"-","title":"-","text":"See User constraints for details.","category":"page"},{"location":"concept_reference/connection_flow_coefficient/","page":"-","title":"-","text":"The connection_flow_coefficient is an optional parameter that can be used to include the connection_flow variable from or to a node in a user_constraint via the connection__from_node__user_constraint and connection__to_node__user_constraint relationships. Essentially, connection_flow_coefficient appears as a coefficient for the connection_flow variable from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"The fix_unit_flow parameter fixes the value of the unit_flow variable to the provided value, if the parameter is defined.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"Common uses for the parameter include e.g. providing initial values for the unit_flow variable, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the unit_flow variable is only fixed for time steps with defined fix_unit_flow parameter values.","category":"page"},{"location":"concept_reference/fix_unit_flow/","page":"-","title":"-","text":"Other uses can include e.g. a constant or time-varying exogenous commodity flow from or to a unit.","category":"page"},{"location":"concept_reference/fix_connection_flow/","page":"-","title":"-","text":"The fix_connection_flow parameter fixes the value of the connection_flow variable.","category":"page"},{"location":"concept_reference/connection_contingency/","page":"-","title":"-","text":"Specifies that the connection in question is to be included as a contingency when security constrained unit commitment is enabled. When using security constrained unit commitment by setting commodity_physics to commodity_physics_lodf, an N-1 security constraint is created for each monitored line (connection_monitored = true) for each specified contingency (connection_contingency = true).","category":"page"},{"location":"concept_reference/connection_contingency/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/output_resolution/","page":"-","title":"-","text":"The output_resolution parameter indicates the resolution at which output values should be reported.","category":"page"},{"location":"concept_reference/output_resolution/","page":"-","title":"-","text":"If null (the default), then results are reported at the highest available resolution from the model. If output_resolution is a duration value, then results are aggregated at that resolution before being reported. At the moment, the aggregation is simply performed by taking the average value.","category":"page"},{"location":"concept_reference/max_node_pressure/","page":"-","title":"-","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), an upper bound on the pressure can be introduced through the max_node_pressure parameter, which triggers the generation of the maxmimum node pressure constraint.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_in/","page":"-","title":"-","text":"The min_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the min_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/unit_investment_lifetime/","page":"-","title":"-","text":"Duration parameter that determines the minimum duration of unit investment decisions. Once a unit has been invested-in, it must remain invested-in for unit_investment_lifetime. Note that unit_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/unit_investment_lifetime/","page":"-","title":"-","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/connection/","page":"-","title":"-","text":"The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"The window_weight parameter, defined for a model object, is used in the Benders decomposition algorithm with representative periods. In this setup, the subproblem rolls over a series of possibly disconnected windows, corresponding to the representative periods. Each of these windows can have a different weight, for example, equal to the fraction of the full model horizon that it represents. Chosing a good weigth can help the solution be more accurate.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"To use weighted rolling representative periods Benders, do the following.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"Specify roll_forward as an array of n duration values, so the subproblem rolls over representative periods.\nSpecify window_weight as an array of n + 1 floating point values, representing the weight of each window.","category":"page"},{"location":"concept_reference/window_weight/","page":"-","title":"-","text":"Note that it the problem rolls n times, then you have n + 1 windows.","category":"page"},{"location":"concept_reference/connection_monitored/","page":"-","title":"-","text":"When using ptdf-based load flow by setting commodity_physics to either commodity_physics_ptdf or commodity_physics_ptdf, a constraint is created for each connection for which connection_monitored = true. Thus, to monitor the ptdf-based flow on a particular connection connection_monitored must be set to true.","category":"page"},{"location":"concept_reference/connection_monitored/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/min_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_out_out_unit_flow parameter triggers the generation of the constraint_min_ratio_out_out_unit_flow and enforces a lower bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a minimum ratio between two products of a unit u, e.g. setting the minimum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/fix_nonspin_units_started_up/","page":"-","title":"-","text":"The fix_nonspin_units_started_up parameter simply fixes the value of the nonspin_units_started_up variable to the provided value. As such, it determines directly how many member units are involved in providing upward reserve commodity flows to the node to which it is linked by the unit__to_node relationship.","category":"page"},{"location":"concept_reference/fix_nonspin_units_started_up/","page":"-","title":"-","text":"When a single value is selected, this value is kept constant throughout the model. It is also possible to provide a timeseries of values, which can be used for example to impose initial conditions by providing a value only for the first timestep included in the model.","category":"page"},{"location":"getting_started/creating_your_own_model/#Creating-Your-Own-Model","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"This part of the guide shows first an example how to insert objects and their parameter data. Then it shows what other objects, relationships and parameter data needs to be added for a very basic model. Lastly, the model instance is run.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"This section explains the process of creating a SpineOpt.jl model from scratch in order to give you an understanding of the underlying principles of the data structure, etc. If you simply want to try something out quickly to see results, check out the Example Models section. Furthermore, if you're in a hurry, the Archetypes section provides you with some pre-made templates for the different parts of a SpineOpt.jl model to get you started quickly.","category":"page"},{"location":"getting_started/creating_your_own_model/#Creating-a-SpineOpt-model-instance","page":"Creating Your Own Model","title":"Creating a SpineOpt model instance","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"First, open the database editor by double-clicking the Input DB. \nRight click on model in the Object tree. \nChoose Add objects. \nThen, add a model object by writing a name to the object name field. You can use e.g. instance. \nClick ok.\nThe model object in SpineOpt is an abstraction that represents the model itself. Every SpineOpt database needs to have at least one model object.\nThe model object holds general information about the optimization. The whole range of functionalities is explained in Advanced Concepts chapter - in here a minimal set of parameters is used.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-parameter-values-to-the-model-instance","page":"Creating Your Own Model","title":"Add parameter values to the model instance","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Select the model object instance from the object tree.\nGo to the Object parameter value tab.\nEvery parameter value belongs to a specific alternative. This allows to hold multiple values for the same parameter of a particular object. The alternative values are used to create scenarios. Choose, Base for all parameter values (Base is required in Spine Toolbox - all other alternatives can be chosen freely).\nThen define a model_start time and a model_end time. \nDouble-click on the empty row under parameter_name and select model_start. \nA None should appear in value column. \nTo asign a start date value, right-click on None and open the editor (cannot be entered directly, since the datatype needs to be changed). \nThe parameter type of model_start is of type Datetime. \nSet the value to e.g. 2019-01-01T00:00:00. \nProceed accordingly for the model_end. ","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image) ","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Further reading on adding parameter values can be found here.","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-other-necessary-objects-and-parameter-data-for-the-objects.","page":"Creating Your Own Model","title":"Add other necessary objects and parameter data for the objects.","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Add all objects and their parameter data by replicating what has been done in the picture below. Do it the same way as explained above with the following caveats.\nWhilst most object names can be freely defined by the user, there is one object name in the example below that needs to be written exactly since it is used internally by SpineOpt: unit_flow. \nThe parameter_name can be selected from a drop down menu.\nThe date time and time series parameter data can be added by using right-click to access the Edit... dialog. When creating the time series, use the fixed resolution with Start time of the model run and with 1h resolution. Then only values need to be entered (or copy pasted) and time stamps come automatically.\nParameter balance_type needs to have value balance_type_none in the gas node, since it allows the node to create energy (natural gas) against a price and therefore the energy balance is not maintained.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Define-temporal-and-stochastic-structures","page":"Creating Your Own Model","title":"Define temporal and stochastic structures","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"To specify the temporal structure for SpineOpt, you need to define temporal_block objects. Think of a temporal_block as a distinctive way of 'slicing' time across the model horizon.\nTo link the temporal structure to the spatial structure, you need to specify node__temporal_block relationships, establishing which temporal__block applies to each node. This relationship is added by right-clicking the node__temporal_block in the relationship tree and then using the add relationships... dialog. Double clicking on an empty cell gives you the list of valid objects. The relationship name is automatically formed, but you can change it if that is desirable.\nTo keep things simple at this point, let's just define one temporal_block for our model and apply it to all nodes. We add the object hourly_temporal_block of type temporal_block following the same procedure as before and establish node__temporal_block relationships between node_gas and hourly_temporal_block, and electricity_node and hourly_temporal_block.\nIn practical terms, the above means that there energy flows over gas_node and electricity_node for each 'time-slice' comprised in hourly_temporal_block.\nSimilarly with the stochastic structure, each node is assigned a deterministic stochastic_structure. ","category":"page"},{"location":"getting_started/creating_your_own_model/#Define-the-spatial-structure","page":"Creating Your Own Model","title":"Define the spatial structure","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"To specify the spatial structure for SpineOpt, you will need to use the node, unit, and connection objects added before.\nNodes can be understood as spatial aggregators. In combination with units and connections, they form the energy network.\nUnits in SpineOpt represent any kind of conversion process. As one example, a unit can represent a power plant that converts the flow of a commodity fuel into an electricity and/or heat flow.\nConnections on the other hand describe the transport of goods from one location to another. Electricity lines and gas pipelines are examples of such connections. This example does not use connections.\nThe database should have an object gas_turbine for the unit object class and objects node_gas and node_elec for the node object class.\nNext, define how the unit and the nodes interact with each other: create a unit__from_node relationship between gas_turbine and node_gas, and unit__to_node relationships between gas_turbine and node_elec.\nIn practical terms, the above means that there is an energy flow going from node_gas into node_elec, through the gas_turbine.","category":"page"},{"location":"getting_started/creating_your_own_model/#Add-remaining-relationships-and-parameter-data-for-the-relationships.","page":"Creating Your Own Model","title":"Add remaining relationships and parameter data for the relationships.","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Similar to adding the objects and their parameter data, add the relationships and their parameter data based on the picture below. \nThe capacity of the gas_turbine has to be sufficient to meet the highest demand for electricity, otherwise the model will be infeasible (it is possible to set penalty values, but they are not included in this example).\nThe parameter fix_ratio_in_out_unit_flow forces the ratio between an input and output flow to be a constant. This is one way to establish an efficiency for a conversion process.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#Run-the-model","page":"Creating Your Own Model","title":"Run the model","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Select SpineOpt \nPress Execute selection.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/#If-it-fails","page":"Creating Your Own Model","title":"If it fails","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Double-check that the data is correct\nTry to see what the problem might be\nAsk help from the discussion forum","category":"page"},{"location":"getting_started/creating_your_own_model/#Explore-the-results","page":"Creating Your Own Model","title":"Explore the results","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Double-clicking the Results database.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image) ","category":"page"},{"location":"getting_started/creating_your_own_model/#Create-and-run-scenarios-and-build-the-model-further","page":"Creating Your Own Model","title":"Create and run scenarios and build the model further","text":"","category":"section"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"Create a new alternative\nAdd parameter data for the new alternative\nConnect alternatives under a scenario. Toolbox modifies Base data with the data from the alternatives in the same scenario.\nExecute multiple scenarios in parallel. First run in a new Julia instance will need to compile SpineOpt taking some time.","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"getting_started/creating_your_own_model/","page":"Creating Your Own Model","title":"Creating Your Own Model","text":"(Image: image)","category":"page"},{"location":"concept_reference/unit__investment_temporal_block/","page":"-","title":"-","text":"unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.","category":"page"},{"location":"concept_reference/unit__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/write_ptdf_file/","page":"-","title":"-","text":"If this parameter value is set to true, a diagnostics file containing all the network power transfer distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/max_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_in_out_unit_flow parameter triggers the generation of the constraint_max_ratio_in_out_unit_flow and sets an upper bound on the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node, i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flow to the node group el_heat (consisting of the two nodes el and heat), the max_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/connection_investment_lifetime/","page":"-","title":"-","text":"connection_investment_lifetime is the minimum amount of time that a connection has to stay in operation once it's invested-in. Only after that time, the connection can be decomissioned. Note that connection_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/unit/","page":"-","title":"-","text":"The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.","category":"page"},{"location":"concept_reference/fix_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_in_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_in_unit_flow and fixes the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/fix_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a fixed share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the fix_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/has_binary_gas_flow/","page":"-","title":"-","text":"This parameter is necessary for the use of pressure driven gas transfer, for which the direction of flow is not known a priori. The parameter has_binary_gas_flow is a booelean method parameter, which - when set to true - triggers the generation of the binary variables binary_gas_connection_flow, which (together with the big_m parameter) forces the average flow through a pipeline to be unidirectional.","category":"page"},{"location":"concept_reference/max_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_out_unit_flow parameter triggers the generation of the constraint_max_ratio_out_out_unit_flow and sets an upper bound on the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a maximum ratio between two products of a unit u, e.g. setting the maximum share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"concept_reference/min_node_pressure/","page":"-","title":"-","text":"If a node has a node_pressure variable (see also the parameter has_pressure and this chapter), a lower bound on the pressure can be introduced through the min_node_pressure parameter, which triggers the generation of the minimum node pressure constraint.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastic-Framework","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Scenario-based stochastics in unit commitment and economic dispatch models typically only consider branching scenario trees. However, sometimes the available stochastic data doesn't span over the entire desired modelling horizon, or all the modelled phenomena. Especially with increasing interest in energy system integration and sector coupling, stochastic data of consistent quality and/or length might be hard to come by.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"While these data issues can be circumvented by either cloning stochastic data across multiple scenario branches or generating dummy forecasts, they can result in inflated problem sizes. Furthermore, Ensuring realistic correlations between generated forecasts is extremely difficult, especially across multiple energy sectors.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The stochastic framework in SpineOpt.jl aims to support stochastic directed acyclic graphs (DAGs) instead of only branching trees, allowing for scenarios to converge later on in the modelled horizon. In addition, the framework allows for slightly different stochastic scenario graphs for different variables, making it easier to define e.g. variables common between all stochastic scenarios.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Key-concepts","page":"Stochastic Framework","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we briefly describe the key concepts required to understand the stochastic framework:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario is essentially just a label for an alternative period of time, describing one possiblity of what may come to pass. Even in deterministic modelling with SpineOpt.jl, a single stochastic_scenario is required for labelling the deterministic timeline.\nStochastic DAG is the directed acyclic graph describing the parent_stochastic_scenario__child_stochastic_scenario relationships between the stochastic scenarios. The key difference between a stochastic DAG and a traditional stochastic tree is that the scenarios are allowed to have multiple parents, making it possible to converge scenarios into each other in addition to branching.\nStochastic path is a unique sequence of stochastic scenarios for traversing the stochastic DAG. Every (finite) stochastic DAG has a limited number of full stochastic paths that traverse it from roots (scenarios without parents) to leaves (scenarios without children). Here, we use the term stochastic path to refer to any subset of scenarios within a full stochastic path.\nstochastic_structure is essentially a \"realization\" of the stochastic DAG, with additional information like the stochastic_scenario_end and weight_relative_to_parents Parameters. These become relevant when we start discussing interactions between different stochastic structures.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above figure presents an example stochastic DAG with the individual stochastic scenarios labelled from s0-s8. An example full stochastic path [s0, s1, s5, s8] is highlighted in red, while an example stochastic path [s2, s4, s7] is highlighted in blue.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#General-idea-in-brief","page":"Stochastic Framework","title":"General idea in brief","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The major issue with stochastic DAGs compared to stochastic trees, is that indexing constraints that include variables from multiple time steps (henceforth referred to as \"dynamic constraints\") needs rethinking. With stochastic trees, constraints can always be unambiguously indexed using (stochastic_scenario, last_time_step), since all stochastic scenarios only have a single parent. However, this is no longer the case for stochastic DAGs, as illustrated in the figures below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"\n","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The example on the left illustrates the \"traditional\" indexing in branching stochastic trees, where backtracking through the tree always leads to unambiguous (stochastic_scenario, time_step) indices. The example on the right shows a similar situation in a stochastic DAG, where backtracking through the DAG leads to four different (stochastic_scenario, time_step) indices, and thus requires four constraints to be generated and indexed.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastic-path-indexing","page":"Stochastic Framework","title":"Stochastic path indexing","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"As discussed in the previous section, dynamic constraints in stochastic DAGs cannot be unambiguously indexed using a single (stochastic_scenario, time_step). However, they can be unambiguously indexed using (stochastic_path, time_step), where the stochastic path is the unique sequence of stochastic scenarios traversing the DAG. Since there are only a limited number of ways to traverse the DAG, represented by the full stochastic paths, we can identify the number of unique paths necessary for constraint generation as follows:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG from roots to leaves.\nFind all the stochastic scenarios that are active on all the time steps included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active stochastic scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-dynamic-constraint-generation","page":"Stochastic Framework","title":"Example dynamic constraint generation","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above figure shows examples of two different dynamic constraints generated in a stochastic DAG: the red constraint including variables from timesteps t4-t5 and the blue constraint including variables from timesteps t1, t3. The full stochastic paths for traversing the above DAG are as follows:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s0, s1, s5, s8]\n[s0, s2, s3, s5, s8]\n[s0, s2, s4, s6, s8]\n[s0, s2, s4, s7, s8]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"For the red constraint, the stochastic scenarios s5-s8 are active on the time steps t4-t5. All the above full stochastic paths include at least two of the active stochastic scenarios, but full paths 1 and 2 both produce an identical path [s5, s8], so the set of unique stochastic paths for the red constraint becomes:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s5, s8]\n[s6, s8]\n[s7, s8]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"There are no paths [s5, s6], [s5, s7], [s6, s7] since following the DAG one cannot start from s5 and end up in s6, even though these stochastic scenarios are active.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The blue constraint illustrates a case where the time step range is non-continuous. The active stochastic scenarios on t1, t3 are s1, s2, s4, s5, so again by comparing these to the full stochastic paths we get:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"[s1, s5]\n[s2, s5]\n[s2, s4]","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"In this case, the full stochastic paths 3 and 4 both produce the path [s2, s4], so only three unique constraints need to be generated. Again, the path [s1, s4] is invalid, since the DAG cannot be traversed from s1 to s4.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Interaction-between-different-stochastic-structures","page":"Stochastic Framework","title":"Interaction between different stochastic structures","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Stochastic path indexing in constraints also allows for \"distorting\" the stochastic DAG in different parts of the model. As long as the stochastic DAG itself isn't changed, meaning the parent_stochastic_scenario__child_stochastic_scenario relationships and the resulting full stochastic paths, we can actually define different stochastic structures and still be able to handle constraint generation between them. This is due to the fact that when determining the stochastic paths, it makes no difference whether we're looking at the same stochastic_structure at different time steps, or at two stochastic structures, one of which has been delayed, on the same time step. This is illustrated by the figure below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"The above represents constraint generation over two stochastic structures, where the lower stochastic_structure has been delayed in respect to the one above. Nevertheless, the procedure for finding the stochastic paths for the constraints remains identical to the previous example:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. As long as the DAG remains the same between all the involved stochastic structures, the pathing remains the same.\nFind all the stochastic scenarios that are active on all the stochastic structures and time steps included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Stochastics-in-the-model-data-structure","page":"Stochastic Framework","title":"Stochastics in the model data structure","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"While the Key concepts and General idea in brief sections go over the stochastic framework in SpineOpt.jl in a more general sense, here we'll go over how to set up stochastics using SpineOpt.jl data structure. Simple step-by-step examples are also provided in the Example of deterministic stochastics, Example of branching stochastics, and Example of converging stochastics sections further below. We won't go into too much detail about the related Object Classes, Relationship Classes, or Parameters, since those can be found in their respective sections. Introductions to these concepts can also be found in the Structural object classes and Structural relationship classes sections, if necessary.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Setting-up-the-stochastic-framework","page":"Stochastic Framework","title":"Setting up the stochastic framework","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"As with all things in SpineOpt.jl, you'll want to start with adding the desired number of objects to the relevant Object Classes, as one cannot define relationships over objects that don't exist. For the stochastic framework, this means creating at least one stochastic_scenario and stochastic_structure object each. This needs to be done even if your model is fully deterministic, as even the deterministic structure needs to be labelled for SpineOpt.jl to recognize that it exists.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Next, if your model has multiple stochastic_scenario objects, you'll want to define how they are related using the parent_stochastic_scenario__child_stochastic_scenario relationship. This relationship essentially defines the stochastic DAG, as well as all the possible stochastic paths, explained in the Key concepts section. Unless the parent_stochastic_scenario__child_stochastic_scenario relationship is defined, there won't be a stochastic DAG, and all stochastic_scenario objects will be assumed to be completely independent of each other.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Now that you've set up the desired stochastic_scenario and stochastic_structure objects, as well as defined the stochastic DAG using the parent_stochastic_scenario__child_stochastic_scenario relationship, it's time to define the properties of the stochastic_structure objects using the stochastic_structure__stochastic_scenario relationship, and the stochastic_scenario_end and weight_relative_to_parents Parameters therein. You'll always have to define at least one stochastic_structure__stochastic_scenario relationship, as the stochastic_structure object is what connects the Systemic object classes to the stochastic framework. stochastic_structure__stochastic_scenario relationship holds two key Parameters:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"weight_relative_to_parents defines the coefficient the corresponding stochastic_scenario has in the Objective function, and needs to be defined for each stochastic_scenario included in the stochastic_structure. The weight is relative to the parents of the [stochastic_scenario], and is calculated as presented below.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario_end is a Duration type parameter that tells when the stochastic_scenario ends in relation to the start of the current optimization. When defined, the stochastic_scenario ends at the defined point in time, and spawns its children according to parent_stochastic_scenario__child_stochastic_scenario, if any. Note that this means the children are included in the stochastic_structure, even without an explicit relationship! If stochastic_scenario_end isn't defined, the stochastic_scenario is assumed to go on indefinetely.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Finally, with all the pieces in place, we'll need to connect the defined stochastic_structure objects to the desired objects in the Systemic object classes using the Structural relationship classes like node__stochastic_structure etc. Here, we essentially tell which parts of the modelled system use which stochastic_structure. Since creating each of these relationships individually can be a bit of a pain, there are a few Meta relationship classes like the model__default_stochastic_structure, that can be used to set model-wide defaults that are used if specific relationships are missing.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-deterministic-stochastics","page":"Stochastic Framework","title":"Example of deterministic stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create the simplest possible stochastic frame: the fully deterministic one. See the Deterministic Stochastic Structure archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model. ","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Create a stochastic_scenario called e.g. realization and a stochastic_structure called e.g. deterministic.\nWe can skip the parent_stochastic_scenario__child_stochastic_scenario relationship, since there isn't a stochastic DAG in this example, and the default behaviour of each stochastic_scenario being independent works for our purposes (only one stochastic_scenario anyhow).\nCreate the stochastic_structure__stochastic_scenario relationship for (deterministic, realization), and set its weight_relative_to_parents parameter to 1. We don't need to define the stochastic_scenario_end parameter, as we want the realization to go on indefinitely.\nRelate the deterministic stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-branching-stochastics","page":"Stochastic Framework","title":"Example of branching stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create a simple branching stochastic tree, where one scenario branches into three at a specific point in time. See the Branching Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Create four stochastic_scenario objects called e.g. realization, forecast1, forecast2, and forecast3, and a stochastic_structure called e.g. branching.\nDefine the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (realization, forecast1), (realization, forecast2), and (realization, forecast3).\nCreate the stochastic_structure__stochastic_scenario relationship for (branching, realization), (branching, forecast1), (branching, forecast2), and (branching, forecast3).\nSet the weight_relative_to_parents parameter to 1 and the stochastic_scenario_end parameter e.g. to 6h for the stochastic_structure__stochastic_scenario relationship (branching, realization). Now, the realization stochastic_scenario will end after 6 hours of time steps, and its children (forecast1, forecast2, and forecast3) will become active.\nSet the weight_relative_to_parents Parameters for the (branching, forecast1), (branching, forecast2), and (branching, forecast3) stochastic_structure__stochastic_scenario relationships to whatever you desire, e.g. 0.33 for equal probabilities across all forecasts.\nRelate the branching stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-converging-stochastics","page":"Stochastic Framework","title":"Example of converging stochastics","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Here, we'll demonstrate step-by-step how to create a simple stochastic DAG, where both branching and converging occurs. This example relies on the previous Example of branching stochastics, but adds another stochastic_scenario at the end, which is a child of the forecast1, forecast2, and forecast3 scenarios. See the Converging Stochastic Tree archetype for how the final data structure looks like, as well as how to connect this stochastic_structure to the rest of your model.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Follow the steps 1-5 in the previous Example of branching stochastics, except call the stochastic_structure something different, e.g. converging.\nCreate a new stochastic_scenario called e.g. converged_forecast.\nAlter the stochastic DAG by creating the parent_stochastic_scenario__child_stochastic_scenario relationships for (forecast1, converged_forecast), (forecast2, converged_forecast), and (forecast3, converged_forecast). Now all three forecasts will converge into a single converged_forecast.\nAdd the stochastic_structure__stochastic_scenario relationship for (converging, converged_forecast), and set its weight_relative_to_parents parameter to 1. Now, all the probability mass in forecast1, forecast2, and forecast3 will be summed up back to the converged_forecast.\nSet the stochastic_scenario_end Parameters of the stochastic_structure__stochastic_scenario relationships (converging, forecast1), (converging, forecast2), and (converging, forecast3) to e.g. 1D, so that all three scenarios end at the same time and the converged_forecast becomes active.\nRelate the converging stochastic_structure to all the desired system objects using the appropriate Structural relationship classes, or use the model-level default Meta relationship classes.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Working-with-stochastic-updating-data","page":"Stochastic Framework","title":"Working with stochastic updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Now that we've discussed how to set up stochastics for SpineOpt, let's focus on stochastic data. The most complex form of input data SpineOpt can currently handle is both stochastic and updating, meaning that the values the parameter takes can depend on both the stochastic_scenario, and the analysis time (first time step) of each solve. However, just stochastic or just updating cases are supported as well, using the same input data format.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"In SpineOpt, stochastic data uses the Map data type from SpineInterface.jl. Essentially, Maps are general indexed data containers, which SpineOpt tries to interpret as stochastic data. Every time SpineOpt calls a parameter, it passes the stochastic_scenario and analysis time as keyword arguments to the parameter, but depending on the parameter type, it doesn't necessarily do anything with that information. For Map type parameters, those keyword arguments are used for navigating the indices of the Map to try and find the corresponding value. If the Map doesn't include the stochastic_scenario index it's looking for, it assumes there's no stochastic information in the Map and carries on to search for analysis time indices. This logic is useful for defining both stochastic and updating data, as well as either case by itself, as shown in the following examples.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-stochastic-data","page":"Stochastic Framework","title":"Example of stochastic data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By stochastic data, we mean parameter values that depend only on the stochastic_scenario. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario value\nscenario1 value1\nscenario2 value2","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 in scenario1, and value2 in scenario2. Note that since there's no analysis time index in this example, the values are used regardless of the analysis time.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-updating-data","page":"Stochastic Framework","title":"Example of updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By updating data, we mean parameter values that depend only on the analysis time. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"analysis time value\n2000-01-01T00:00:00 value1\n2000-01-01T12:00:00 value2","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00, and value2 if the first time step of the simulation is after 2000-01-01T12:00:00. Note that since there's no stochastic_scenario index in this example, the values are used regardless of the stochastic_scenario.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Example-of-stochastic-updating-data","page":"Stochastic Framework","title":"Example of stochastic updating data","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"By stochastic updating data, we mean parameter values that depend on both the stochastic_scenario and the analysis time. In such a case, the input data must be formatted as a Map with the following structure","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"stochastic_scenario analysis time value\nscenario1 2000-01-01T00:00:00 value1\nscenario1 2000-01-01T12:00:00 value2\nscenario2 2000-01-01T00:00:00 value3\nscenario2 2000-01-01T12:00:00 value4","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"where the stochastic_scenario indices are simply Strings corresponding to the names of the stochastic_scenario objects, and the analysis time indices are DateTime values. The values can be whatever data types SpineInterface.jl supports, like Constants, DateTimes, Durations, or TimeSeries. In the above example, the parameter will take value1 if the first time step of the current simulation is between 2000-01-01T00:00:00 and 2000-01-01T12:00:00 and the parameter is called in scenario1, and value3 in scenario2. If the first time step of the current simulation is after 2000-01-01T12:00:00, the parameter will take value2 in scenario1, and value4 in scenario2.","category":"page"},{"location":"advanced_concepts/stochastic_framework/#Constraint-generation-with-stochastic-path-indexing","page":"Stochastic Framework","title":"Constraint generation with stochastic path indexing","text":"","category":"section"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Every time a constraint might refer to variables either on different time steps or on different stochastic scenarios (meaning different nodes or units), the constraint needs to use stochastic path indexing in order to be correctly generated for arbitrary stochastic DAGs. In practise, this means following the procedure outlined below:","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Identify all unique full stochastic paths, meaning all the possible ways of traversing the DAG. This is done along with generating the stochastic structure, so no real impact on constraint generation.\nFind all the stochastic scenarios that are active on all the stochastic structures and time slices included in the constraint.\nFind all the unique stochastic paths by intersecting the set of active scenarios with the full stochastic paths.\nGenerate constraints over each unique stochastic path found in step 3.","category":"page"},{"location":"advanced_concepts/stochastic_framework/","page":"Stochastic Framework","title":"Stochastic Framework","text":"Steps 2 and 3 are the crucial ones, and are currently handled by separate constraint__indices functions. Essentially, these functions go through all the variables on all the time steps included in the constraint, collect the set of active stochastic_scenarios on each time step, and then determine the unique active stochastic paths on each time step. The functions pre-form the index set over which the constraint is then generated in the add_constraint_ functions.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Unit-commitment","page":"Unit Commitment","title":"Unit commitment","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To incorporate technical detail about (clustered) unit-commitment statuses of units, the online, started and shutdown status of units can be tracked and constrained in SpineOpt. In the following, relevant relationships and parameters are introduced and the general working principle is described.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Key-concepts-for-unit-commitment","page":"Unit Commitment","title":"Key concepts for unit commitment","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Here, we briefly describe the key concepts involved in the representation of (clustered) unit commitment models:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"units_on is an optimization variable that holds information about the on- or offline status of a unit. Unit commitment restrictions will govern how this variable can change through time.\nunits_on__temporal_block is a relationship linking the units_on variable of this unit to a specific temporal_block object. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized.\nonline_variable_type is a method parameter and can take the values unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear. If the binary value is chosen, the units status is modelled as a binary (classic UC). For clustered unit commitment units, the integer type is applicable. Note that if the parameter is not defined, the default will be linear. If the units status is not crucial, this can reduce the computational burden.\nnumber_of_units defines how many units of a certain unit type are available. Typically this parameter takes a binary (UC) or integer (clustered UC) value. To avoid confusion the following distinction will be made in this document: unit will be used to identify a Spine unit object, which can have multiple members. Together with the unit_availability_factor, this will determine the maximum number of members that can be online at any given time. (Thus restricting the units_on variable). The default value for this parameter is 1. It is possible to allow the model to increase the number_of_units itself, through Investment Optimization\nunit_availability_factor: (number value or time series). Is the fraction of the time that this unit is considered to be available, by acting as a multiplier on the capacity. A time series can be used to indicate the intermittent character of renewable generation technologies.\nmin_up_time: (duration value). Sets the minimum time that a unit has to stay online after a startup. Inclusion of this parameter will trigger the creation of the constraint on Minimum up time (basic version)\nmin_down_time: (duration value). Sets the minimum time that a unit has to stay offline after a shutdown. Inclusion of this parameter will trigger the creation of the constraint on Minimum down time (basic version)\nminimum_operating_point: (number value) limits the minimum value of the unit_flow variable for a unit which is currently online. Inclusion of this parameter will trigger the creation of the Constraint on minimum operating point\nstart_up_cost: \"number value\". Cost associated with starting up a unit.\nshut_down_cost: \"number value\". Cost associated with shutting down a unit.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Illustrative-unit-commitment-examples","page":"Unit Commitment","title":"Illustrative unit commitment examples","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/#Step-1:-defining-the-number-of-members-of-a-unit-type","page":"Unit Commitment","title":"Step 1: defining the number of members of a unit type","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"A spine unit can represent multiple members. This can be incorporated in a model by setting the number_of_units parameter to a specific value. For example, if we define a single unit in a model as follows:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"And we link the unit to a certain node_1 with a unit__to_node relationship.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1_to__node_1","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The single Spine unit defined here, now represents two members. This means that a single unit_flow variable will be created for this unit, but the restrictions as imposed by the Ramping and Reserves framework will be adapted to reflect the fact that there are two members present, thus doubling the total capacity.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-2:-choosing-the-online_variable_type","page":"Unit Commitment","title":"Step 2: choosing the online_variable_type","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Next, we have to decide the online_variable_type for this unit, which will restrict the kind of values that the units_on variable can take. This basically comes down to deciding if we are working in a classical UC framework (unit_online_variable_type_binary), a clustered UC framework (unit_online_variable_type_integer), or a relaxed clustered UC framework (unit_online_variable_type_linear), in which a non-integer number of units can be online.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The classical UC framework can only be applied when the number_of_units equals 1.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-3:-imposing-a-minimum-operating-point","page":"Unit Commitment","title":"Step 3: imposing a minimum operating point","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The output of an online unit to a specific node can be restricted to be above a certain minimum by choosing a value for the minimum_operating_point parameter. This parameter is defined for the unit__to_node relationship, and is given as a fraction of the unit_capacity. If we continue with the example above, and define the following objects, relationships, and parameters:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2\nunit_online_variable_type: \"unit_online_variable_type_integer\"\nunit_1_to__node_1\nminimum_operating_point: 0.2\nunit_capacity: 200","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"It can be seen that in this case the unit_flow form unit_1 to node_1 must for any timestep t be larger than units_on(t) * 02 * 200","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-4:-imposing-a-minimum-up-or-down-time","page":"Unit Commitment","title":"Step 4: imposing a minimum up or down time","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Spine units can also be restricted in their commitment status with minimum up- or down times by choosing a value for the min_up_time or min_down_time respectively. These parameters are defined for the unit object, and should be duration values. We can continue the example and add a minimum up time for the unit:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"unit_1\nnumber_of_units: 2\nunit_online_variable_type: \"unit_online_variable_type_integer\"\nmin_up_time: 2h\nunit_1_to__node_1\nminimum_operating_point: 0.2\nunit_capacity: 200","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Whereas the units_on variable was restricted (before inclusion of the min_up_time parameter) to be smaller than or equal to the number_of_units for any timestep t, it now has to be smaller than or equal to the number_of_units decremented with the units_started_up summed over the timesteps that include t - min_up_time. This implies that a unit which has started up, has to stay online for at least the min_up_time","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To consider a simple example let's assume that we have a model with a resolution of 1h. Suppose that before t, there is no member of the unit online and in timestep t -> t + 1h, one member starts up. Another member starts up in timestep t + 1h \\-> t + 2h. The first startup, along with the minimum up time of 2 hours implies that the units_on variable of this unit has now changed to 1 in timestep t -> t + 1h and can not go back to 0 in timestep t-> t + 1h -> t + 2h. The second startup further restricts the number of units that are allowed to be online, it can be seen that the following restrictions apply when both startups are combined with the minimum up time of 2h:","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"t-> t + 1h : units_on = 1\nt + 1h -> t + 2h: units_on = 2\nt + 2h-> t + 3h: units_on in 12\nt + 3h-> t + 4h: units_on in 012","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The minimum down time restrictions operate in very much the same way, they simply impose that units that have been shut down, have to stay offline for the chosen period of time.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-5:-allocationg-a-cost-to-startups-or-shutdowns","page":"Unit Commitment","title":"Step 5: allocationg a cost to startups or shutdowns","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Costs can be allocated to startups or shutdowns by choosing a value for the start_up_cost or shut_down_cost respectively.","category":"page"},{"location":"advanced_concepts/unit_commitment/#Step-6:-defining-unit-availabilities","page":"Unit Commitment","title":"Step 6: defining unit availabilities","text":"","category":"section"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"By defining a unit_availability_factor, the fact that typical members are not available all the time can be reflected in the model.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Typically, units are not available 100% of the time, due to scheduled maintenance, unforeseen outages, or other things. This can be incorporated in the model by setting the unit_availability_factor to a fractional value. For each timestep in the model, an upper bound is then imposed on the units_on variable, equal to number_of_units * unit_availability_factor. This parameter can not be used when the online_variable_type is binary. It should also be noted that when the online_variable_type is of integer type, the aforementioned product must be integer as well, since it will determine the value of the units_available parameter which is restricted to integer values. The default value for this parameter is 1.","category":"page"},{"location":"advanced_concepts/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The unit_availability_factor can also be taken as a timeseries. By allowing a different availability factor for each timestep in the model, it can perfectly be used to represent intermittent technologies of which the output cannot be fully controlled.","category":"page"},{"location":"concept_reference/commodity_physics/","page":"-","title":"-","text":"This parameter determines the specific formulation used to carry out dc load flow within a model. To enable power transfer distribution factor (ptdf) based load flow for a network of nodes and connections, all nodes must be related to a commodity with commodity_physics set to commodity_physics_ptdf. To enable security constraint unit comment based on ptdfs and line outage distribution factors (lodf) all nodes must be related to a commodity with commodity_physics set to commodity_physics_lodf.","category":"page"},{"location":"concept_reference/commodity_physics/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/connections_invested_big_m_mga/","page":"-","title":"-","text":"The connections_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_connections could suffice.)","category":"page"},{"location":"concept_reference/big_m/","page":"-","title":"-","text":"The big_m parameter is a property of the model object. The bigM method is commonly used for the purpose of recasting non-linear constraints into a mixed-integer reformulation. In SpineOpt, the bigM formulation is used to describe the sign of gas flow through a connection (if a pressure driven gas transfer model is used). The big_m parameter in combination with the binary variable binary_gas_connection_flow is used in the constraints on the gas flow capacity and the fixed node pressure points and ensures that the average flow through a pipeline is only in one direction and is constraint by the fixed pressure points from the outer approximation of the Weymouth equation. See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling for reference.","category":"page"},{"location":"concept_reference/is_active/","page":"-","title":"-","text":"is_acive is a universal, utility parameter that is defined for every object class. When used in conjunction with the activity_control feature, the is_active parameter allows one to control whether or not a specific object is active within a model or not. ","category":"page"},{"location":"concept_reference/vom_cost/","page":"-","title":"-","text":"By defining the vom_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for the variable operation and maintenance costs associated with that unit over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"Within an investments problem candidate_storages determines the upper bound on the storages investment decision variable in constraint storages_invested_available. In constraint node_state_cap the maximum node state will be the product of the storages investment variable and node_state_cap. Thus, the interpretation of candidate_storages depends on storage_investment_variable_type which determines the investment decision variable type. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages of size node_state_cap that may be invested in at the corresponding node. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a maximum storage capacity with node_state_cap being analagous to a scaling parameter.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"Note that candidate_storages is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for storages at the corresponding node. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/candidate_storages/","page":"-","title":"-","text":"See also Investment Optimization and storage_investment_variable_type","category":"page"},{"location":"how_to/define_an_efficiency/#How-to-define-an-efficiency","page":"Define an efficiency","title":"How to define an efficiency","text":"","category":"section"},{"location":"how_to/define_an_efficiency/#relationships-between-the-inputs-and-outputs-of-a-unit","page":"Define an efficiency","title":"relationships between the inputs and outputs of a unit","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The image below shows an overview of the possible relationships between the inputs and outputs of a unit.","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The key capability requirements are:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"Easily define arbitrary numbers of input and output flows\nEasily create piecewise affine linear relationships between any two flows\nAnything more complicated can be done via user_constraints","category":"page"},{"location":"how_to/define_an_efficiency/#unit__node__node-relationship","page":"Define an efficiency","title":"unit__node__node relationship","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"The unit__node__node relationship allows you to constrain two nodes to each other via a number of different parameters.:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"unit_incremental_heat_rate: Input_flow = unit_incremental_heat_rate * output_flow + unit_idle_heat_rate * units_on. It can be piecewise linear, used in conjunction with operating_points with monotonically increasing coefficients (not enforced). Used in conjunction with unit_idle_heat_rate triggers a fixed flow when the unit is online and unit_start_flow triggers a flow on a unit start (start fuel consumption)\nfix_ratio_out_in_unit_flow: equivalent to an efficiency. Output_flow = fix_ratio_out_in_unit_flow x output_flow + fix_units_on_coefficient_out_in * units_on. Ordering of the nodes in the unit__node__node relationship matters. The first node will be the output flow and the second node will be treated as the input flow (consistently with the out_in in the parameter name. A units_on coefficient is added with fix_units_on_coefficient_out_in, \nIn addition to fix_ratio_out_in_unit_flow you have [constraint]_ratio_[direction1]_[direction2]_unit_flow where constraint can be min, max or fix and determines the sense of the constraint (max: <, min: >, fix: =) while direction1 and direction2 are used to interpret the direction of the flows involved. In signifies an input flow to the unit while out signifies an output flow from the unit. For each of these parameters, there is a corresponding [constraint]_[direction1]_[direction2]_units_on_coefficient. For example: max_ratio_in_out_unit_flow creates the following constraint:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"input_flow < max_ratio_in_out_unit_flow * output_flow + max_units_on_coefficient_in_out * units_on","category":"page"},{"location":"how_to/define_an_efficiency/#real-world-example:-Compressed-Air-Energy-Storage","page":"Define an efficiency","title":"real world example: Compressed Air Energy Storage","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"To give a feeling for why these functionalities are useful, consider the following real world example for Compressed Air Energy Storage:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"(Image: image)","category":"page"},{"location":"how_to/define_an_efficiency/#known-issues","page":"Define an efficiency","title":"known issues","text":"","category":"section"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"That does not mean that this implementation is perfect; there are some known issues:","category":"page"},{"location":"how_to/define_an_efficiency/","page":"Define an efficiency","title":"Define an efficiency","text":"Multiple ways to do the same thing (kind of)\nThe ordering of nodes in unit__node__node relationship matters and this can be confusing\nWhen specifying a unit__node__node relationship, currently toolbox doesn’t constrain a user to choosing nodes that are connected to the unit. It’s possible to create a unit__node__node relationship between a unit and nodes where there are no flows. We actually need to define a relationship between two flows, which is really a relationship between a unit__[to/from]_node relationship and a unit__[to/from]_node relationship.\nThere is a long list of parameters (24 in total) [fix/max/min]_ratio_[in/out]_[in/out]_[unit_flow/units_on_coefficient]\nIncremental_heat_rate supports piecewise linear but the ratio constraints don’t","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_out/","page":"-","title":"-","text":"The max_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the max_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_in_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/unit_investment_variable_type/","page":"-","title":"-","text":"Within an investments problem unit_investment_variable_type determines the unit investment decision variable type. Since the unit_flows will be limited to the product of the investment variable and the corresponding unit_capacity for each unit_flow and since candidate_units represents the upper bound of the investment decision variable, unit_investment_variable_type thus determines what the investment decision represents. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested. If unit_investment_variable_type is continuous, candidate_units is more analagous to a capacity with unit_capacity being analagous to a scaling parameter. For example, if unit_investment_variable_type = integer, candidate_units = 4 and unit_capacity for a particular unit_flow = 400 MW, then the investment decision is how many 400 MW units to build. If unit_investment_variable_type = continuous, candidate_units = 400 and unit_capacity for a particular unit_flow = 1 MW, then the investment decision is how much capacity if this particular unit to build. Finally, if unit_investment_variable_type = integer, candidate_units = 10 and unit_capacity for a particular unit_flow = 50 MW, then the investment decision is many 50MW blocks of capacity of this particular unit to build.","category":"page"},{"location":"concept_reference/unit_investment_variable_type/","page":"-","title":"-","text":"See also Investment Optimization and candidate_units","category":"page"},{"location":"concept_reference/storages_invested_big_m_mga/","page":"-","title":"-","text":"The storages_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_storages could suffice.)","category":"page"},{"location":"concept_reference/fix_node_state/","page":"-","title":"-","text":"The fix_node_state parameter simply fixes the value of the node_state variable to the provided value, if one is found. Common uses for the parameter include e.g. providing initial values for node_state variables, by fixing the value on the first modelled time step (or the value before the first modelled time step) using a TimeSeries type parameter value with an appropriate timestamp. Due to the way SpineOpt handles TimeSeries data, the node_state variables are only fixed for time steps with defined fix_node_state parameter values.","category":"page"},{"location":"concept_reference/db_lp_solver_options/","page":"-","title":"-","text":"LP solver options are specified for a model using the db_lp_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Clp.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_lp_solver_options map parameter)","category":"page"},{"location":"concept_reference/fix_connections_invested/","page":"-","title":"-","text":"The fix_connections_invested parameter can be used to fix the values of the connections_invested variable to preset values. If set to a Scalar type value, the connections_invested variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/fix_connections_invested/","page":"-","title":"-","text":"See Investment Optimization for more information about the investment framework in SpineOpt.jl.","category":"page"},{"location":"concept_reference/has_voltage_angle/","page":"-","title":"-","text":"For the use of node-based lossless DC powerflow, each node will be associated with a node_voltage_angle variable. To enable the generation of the variable in the optimization model, the boolean parameter has_voltage_angle should be set true. The voltage angle at a certain node can also be constrained through the parameters max_voltage_angle and min_voltage_angle. More details on the use of lossless nodal DC power flows are described here","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_out/","page":"-","title":"-","text":"The max_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the max_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio/","page":"-","title":"-","text":"For investment models that are solved using the Benders algorithm (i.e., with model_type set to spineopt_benders), mp_min_res_gen_to_demand_ratio represents a lower bound on the fraction of the total system demand that must be supplied by renewable generation sources (RES).","category":"page"},{"location":"concept_reference/mp_min_res_gen_to_demand_ratio/","page":"-","title":"-","text":"A unit can be marked as a renewable generation source by setting is_renewable to true.","category":"page"},{"location":"advanced_concepts/user_constraints/#User-Constraints","page":"User Constraints","title":"User Constraints","text":"","category":"section"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"User constraints allow the user to define arbitrary linear constraints involving most of the problem variables. This section describes this function and how to use it.","category":"page"},{"location":"advanced_concepts/user_constraints/#Key-User-Constraint-Concepts","page":"User Constraints","title":"Key User Constraint Concepts","text":"","category":"section"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"The basic principle: The basic steps involved in forming a user constraint are:","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Creating a user constraint object: One creates a new user_constraint object which will be used as a unique handle for the specific constraint and on which constraint-level parameters will be defined.\nSpecify which variables are involved in the constraint: this generally involves creating a relationship involving the user_constraint object. For example, specifying the relationship unit__from_node__user_constraint specifies that the corresponding unit_flow variable is involved in the constraint. The table below contains a complete list of variables and the corresponding relationships to set.\nSpecify the variable coefficients: this will generally involve specifying a parameter named *_coefficient on the relationship defined above to specify the coefficient on that particular variable in the constraint. For example, to define the coefficient on the unit_flow variable, one specifies the unit_flow_coefficient parameter on the approrpriate unit__from_node__user_constraint relationship. The table below contains a complete list of variables and the corresponding coefficient parameters to set.\nSpecify the right-hand-side constant term: The constraint should be formed in conventional form with all constant terms moved to the right-hand side. The right-hand-side constant term is specified by setting the right_hand_side user_constraint parameter.\nSpecify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are ==, >= and <=.\nCoefficients can be defined on some parameters themselves. For example, one may specify a coefficient on a node's demand parameter. This is done by specifying the relationship node__user_constraint and specifying the demand_coefficient parameter on that relationship","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Piecewise unit_flow coefficients: As described in operating_points, specifying this parameter decomposes the unit_flow variable into a number of sub operating segment variables named unit_flow_op in the model and with an additional index, i for the operating segment. The intention of this functionality is to allow unit_flow coefficients to be defined individually per segment to define a piecewise linear function. To accomplish this, the steps are as described above with the exception that one must define operating_points on the appropriate unit__from_node or unit__to_node as an array type with the dimension corresponding to the number of operating points and then set the unit_flow_coefficient for the appropriate unit__from_node__user_constraint relationship, also as an array type with the same number of elements. Note that if operating points is defined as an array type with more than one elements, unit_flow_coefficient may be defined as either an array or non-array type. However, if operating_points is of non-array type, corresponding unit_flow_coefficients must also be of non-array types.\nVariables, relationships and coefficient guide for user constraints The table below provides guidance regarding what relationships and coefficients to set for various problem variables and parameters.","category":"page"},{"location":"advanced_concepts/user_constraints/","page":"User Constraints","title":"User Constraints","text":"Problem variable / Parameter Name Relationship Parameter\nunit_flow (direction=from_node) unit__from_node__user_constraint unit_flow_coefficient (non-array type)\nunit_flow (direction=to_node) unit__to_node__user_constraint unit_flow_coefficient (non-array type)\nunit_flow_op (direction=from_node) unit__from_node__user_constraint unit_flow_coefficient (array type)\nunit_flow_op (direction=to_node) unit__to_node__user_constraint unit_flow_coefficient (array type)\nconnection_flow (direction=from_node) connection__from_node__user_constraint connection_flow_coefficient\nconnection_flow (direction=to_node) connection__to_node__user_constraint connection_flow_coefficient\nnode_state node__user_constraint node_state_coefficient\nstorages_invested node__user_constraint storages_invested_coefficient\nstorages_invested_available node__user_constraint storages_invested_available_coefficient\ndemand node__user_constraint demand_coefficient\nunits_on unit__user_constraint units_on_coefficient\nunits_started_up unit__user_constraint units_started_up_coefficient\nunits_invested unit__user_constraint units_invested_coefficient\nunits_invested_available unit__user_constraint units_invested_available_coefficient\nconnections_invested connection__user_constraint connections_invested_coefficient\nconnections_invested_available connection__user_constraint connections_invested_available_coefficient","category":"page"},{"location":"concept_reference/storage_investment_variable_type/","page":"-","title":"-","text":"Within an investments problem storage_investment_variable_type determines the storage investment decision variable type. Since a node's node_state will be limited to the product of the investment variable and the corresponding node_state_cap and since candidate_storages represents the upper bound of the storage investment decision variable, storage_investment_variable_type thus determines what the investment decision represents. If storage_investment_variable_type is integer or binary, then candidate_storages represents the maximum number of discrete storages that may be invested-in. If storage_investment_variable_type is continuous, candidate_storages is more analagous to a capacity with node_state_cap being analagous to a scaling parameter. For example, if storage_investment_variable_type = integer, candidate_storages = 4 and node_state_cap = 1000 MWh, then the investment decision is how many 1000h MW storages to build. If storage_investment_variable_type = continuous, candidate_storages = 1000 and node_state_cap = 1 MWh, then the investment decision is how much storage capacity to build. Finally, if storage_investment_variable_type = integer, candidate_storages = 10 and node_state_cap = 100 MWh, then the investment decision is how many 100MWh storage blocks to build.","category":"page"},{"location":"concept_reference/storage_investment_variable_type/","page":"-","title":"-","text":"See also Investment Optimization and candidate_storages.","category":"page"},{"location":"concept_reference/the_basics/#Basics-of-the-model-structure","page":"Basics of the model structure","title":"Basics of the model structure","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"In SpineOpt.jl, the model structure is generated based on the input data, allowing it to be used for a multitude of different problems. Here, we aim to provide you with a basic understanding of the SpineOpt.jl model and data structure, while the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections provide more in-depth explanations of each concept.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-object-classes","page":"Basics of the model structure","title":"Introduction to object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Essentially, Object Classes represents different types of objects or entities that make up the model. For example, every power plant in the model is represented as an object of the object class unit, every power line as an object of the object class connection, and so forth. In order to add any new entity to a model, a new object has to be added to desired object class in the input data.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Each object class has a very specific purpose in SpineOpt.jl, so understanding their differences is key. The Object Classes can be roughly divided into three distinctive groups, namely Systemic object classes, Structural object classes, and Meta object classes.","category":"page"},{"location":"concept_reference/the_basics/#Systemic-object-classes","page":"Basics of the model structure","title":"Systemic object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"As the name implies, system Object Classes are used to describe the system to be modelled. Essentially, they define what you want to model. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"commodity represents different goods to be generated, consumed, transported, etc.\nconnection handles the transfer of commodities between nodes.\nnode ensures the balance of the commodity flows, and can be used to store commodities as well.\nunit handles the generation and consumption of commodities.","category":"page"},{"location":"concept_reference/the_basics/#Structural-object-classes","page":"Basics of the model structure","title":"Structural object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Structural Object Classes are used to define the temporal and stochastic structure of the modelled problem, as well as custom User Constraints. Unlike the above system Object Classes, the structural Object Classes are more about how you want to model, instead of strictly what you want to model. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"stochastic_scenario represents a different forecast or another type of an alternative time period.\nstochastic_structure acts as a handle for a group of stochastic_scenarios with set properties.\ntemporal_block defines a period of time with the desired temporal resolution.\nuser_constraint is an optional custom constraint generated based on the input data.","category":"page"},{"location":"concept_reference/the_basics/#Meta-object-classes","page":"Basics of the model structure","title":"Meta object classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Meta Object Classes are used for defining things on the level of models or above, like model output and even multiple models for problem decompositions. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"model represents an individual model, grouping together all the things relevant for itself.\noutput defines which Variables are output from the model.\nreport groups together multiple output objects.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-relationship-classes","page":"Basics of the model structure","title":"Introduction to relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"While Object Classes define all the objects or entities that make up a model, Relationship Classes define how those entities are related to each other. Thus, Relationship Classes hold no meaning on their own, and always include at least one object class.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Similar to Object Classes, each relationship class has a very specific purpose in SpineOpt.jl, and understanding the purpose of each relationship class is paramount. The Relationship Classes can be roughly divided into Systemic relationship classes, Structural relationship classes, and Meta relationship classes, again similar to Object Classes.","category":"page"},{"location":"concept_reference/the_basics/#Systemic-relationship-classes","page":"Basics of the model structure","title":"Systemic relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Systemic Relationship Classes define how Systemic object classes are related to each other, thus helping define the system to be modelled. Most of these relationships deal with which units and connections interact with which nodes, and how those interactions work. This essentially defines the possible commodity flows to be modelled. Systemic Relationship Classes include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__from_node defines which node the connection can transfer a commodity from.\nconnection__to_node defines which node the connection can transfer a commodity to.\nconnection__node__node holds Parameters for connections between two nodes.\nnode__commodity defines which node holds which commodity.\nnode__node holds parameters for direct node-node interactions, like diffusion of commodities.\nunit__commodity defines which commodity the unit handles.\nunit__from_node defines which node the unit can take an input commodity from.\nunit__to_node defines which node the unit can output a commodity to.\nunit__node__node holds parameters for unit interactions between two nodes.","category":"page"},{"location":"concept_reference/the_basics/#Structural-relationship-classes","page":"Basics of the model structure","title":"Structural relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Structural Relationship Classes primarily relate Structural object classes to Systemic object classes, defining what structures the individual parts of the system use. These are mostly used to determine the temporal and stochastic structures to be used in different parts of the modelled system, or custom User Constraints.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"SpineOpt.jl has a very flexible temporal and stochastic structure, explained in detail in the Temporal Framework and Stochastic Framework sections of the documentation. Unfortunately, this flexibility requires quite a few different structural Relationship Classes, the most important of which are the following basic structural Relationship Classes:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"node__stochastic_structure defines the stochastic_structure used for the node balance.\nnode__temporal_block defines the temporal blocks used for the node balance.\nparent_stochastic_scenario__child_stochastic_scenario defines the stochastic directed acyclic graph (DAG) of the Stochastic Framework.\nstochastic_structure__stochastic_scenario holds parameters for stochastic scenarios in the stochastic_structure.\nunits_on__stochastic_structure defines the stochastic_structure used for the online variable of the unit.\nunits_on__temporal_block defines the temporal blocks used for the online variable of the unit.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Furthermore, there are also a number of advanced structural Relationship Classes, which are only necessary when using some of the optional features of SpineOpt.jl. For Investment Optimization, the following relationships control the stochastic and temporal structures of the investment variables:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the connection.\nconnection__investment_temporal_block defines the temporal blocks used for the investment Variables for the connection.user_constraint.\nnode__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the node.\nnode__investment_temporal_block defines the stochastic_structure used for the investment Variables for the node.\nunit__investment_stochastic_structure defines the stochastic_structure used for the investment Variables for the unit.\nunit__investment_temporal_block defines the temporal blocks used for the investment Variables for the unit.(@ref).","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"For User Constraints, which are essentially generic data-driven custom constraints, the following relationships are used to control which variables are included and with what coefficients: ","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"connection__from_node__user_constraint holds Parameters for the connection_flow variable from the node in question in the custom user_constraint.\nconnection__to_node__user_constraint holds Parameters for the connection_flow variable to the node in question in the custom user_constraint.\nnode__user_constraint holds Parameters for the node_state variable in the custom user_constraint.\nunit__from_node__user_constraint holds Parameters for the unit_flow variable from the node in question in the custom user_constraint.\nunit__to_node__user_constraint holds Parameters for the unit_flow variable to the node in question in the custom user_constraint.","category":"page"},{"location":"concept_reference/the_basics/#Meta-relationship-classes","page":"Basics of the model structure","title":"Meta relationship classes","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Meta Relationship Classes are used for defining model-level settings, like which temporal blocks or stochastic structures are active, and what the model output is. These include:","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"model__default_investment_stochastic_structure defines a default stochastic_structure to be used for investment Variables when no other definitions exist.\nmodel__default_investment_temporal_block defines a default temporal_block to be used for investment Variables when no other definitions exist.\nmodel__default_stochastic_structure defines a default stochastic_structure to be used for nodes and units when no other definitions exist.\nmodel__default_temporal_block defines a default temporal_block to be used for nodes and units when no other definitions exist.\nmodel__report connects each report to the desired model.\nmodel__stochastic_structure defines which stochastic structures are active in which models.\nmodel__temporal_block defines which temporal blocks are active in which models.\nreport__output defines which outputs are part of which report.","category":"page"},{"location":"concept_reference/the_basics/#introduction-to-parameters","page":"Basics of the model structure","title":"Introduction to parameters","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"While the primary function of Object Classes and Relationship Classes is to define the system to be modelled and it's structure, Parameters exist to constrain them. Every parameter is attributed to at least one object class or relationship class, but some appear in many classes whenever they serve a similar purpose.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Parameters accept different types of values depending on their purpose, e.g. whether they act as a flag for some specific functionality or appear as a coefficient in Constraints, so understanding each parameter is key. Most coefficient-type Parameters accept constant, time series, and even stochastic time series form input, but there are some exceptions. Most flag-type Parameters, on the other hand, have a restricted list of acceptable values defined by their Parameter Value Lists.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"The existence of some Constraints is controlled based on if the relevant Parameters are defined. As a rule-of-thumb, a constraint only gets generated if at least one of the Parameters appearing in it is defined, but one should refer to the appropriate Constraints and Parameters sections when in doubt.","category":"page"},{"location":"concept_reference/the_basics/#Introduction-to-groups-of-objects","page":"Basics of the model structure","title":"Introduction to groups of objects","text":"","category":"section"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"Groups of objects are used within SpineOpt for different purposes. To create a group of objects, simply right-click the corresponding Object Class in the Spine Toolbox database editor and select Add object group. Groups are essentially special objects, that act as a single handle for all of its members.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"On the one hand, groups can be used in order to impose constraints on the aggregation of a variable, e.g. on the sum of multiple unit_flow variables. Constraints based on parameters associated with the unit__node__node, unit__to_node, unit__from_node, connection__node__node, connection__to_node, connection__from_node can generally be used for this kind of flow aggregation by defining the parameters on groups of objects, typically node groups. (with the exception of variable fixing parameters, e.g. fix_unit_flow, fix_connection_flow etc.). See for instance constraint_unit_flow_capacity.","category":"page"},{"location":"concept_reference/the_basics/","page":"Basics of the model structure","title":"Basics of the model structure","text":"On the other hand, a node group can be used to for PTDF based powerflows. Here a node group is used to enforce a nodal balance on system level, while suppressing the node balances at individual nodes. See also balance_type and the node balance constraint.","category":"page"},{"location":"concept_reference/model__default_investment_temporal_block/","page":"-","title":"-","text":"model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.","category":"page"},{"location":"concept_reference/model__default_investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/unit_online_variable_type_list/","page":"-","title":"-","text":"unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear. ","category":"page"},{"location":"concept_reference/units_on__temporal_block/","page":"-","title":"-","text":"units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized. ","category":"page"},{"location":"concept_reference/fix_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_in_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_in_unit_flow and fixes the ratio between out and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ngthe fix_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/weight/","page":"-","title":"-","text":"The weight variable, defined for a temporal_block object can be used to assign different weights to different temporal periods that are modeled. It basically determines how important a certain temporal period is in the total cost, as it enters the Objective function. The main use of this parameter is for representative periods, where each representative period represents a specific fraction of a year or so. ","category":"page"},{"location":"concept_reference/unit_idle_heat_rate/","page":"-","title":"-","text":"Used to implement the no-load or idle heat rate of a unit. This is the y-axis offset of the heat rate function and is the fuel consumed per unit time when a unit is online and that results in no additional output. This is defined on the unit__node__node relationship and it is assumed that the input flow from node 1 represents fuel consumption and the output flow to node 2 is the elecrical output. While the units depend on the data, unit_idle_heat_rate is generally expressed in GJ/hr. Used in conjunction with unit_incremental_heat_rate. unit_idle_heat_rate is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"library/#Library","page":"Library","title":"Library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"Documentation for SpineOpt.jl.","category":"page"},{"location":"library/#Contents","page":"Library","title":"Contents","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"Pages = [\"library.md\"]\nDepth = 3","category":"page"},{"location":"library/#Index","page":"Library","title":"Index","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"","category":"page"},{"location":"library/#Public-interface","page":"Library","title":"Public interface","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"run_spineopt\nwrite_report_from_intermediate_results\ngenerate_forced_availability_factor","category":"page"},{"location":"library/#SpineOpt.run_spineopt","page":"Library","title":"SpineOpt.run_spineopt","text":"run_spineopt(url_in, url_out; )\n\nRun SpineOpt using the contents of url_in and write report(s) to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.\n\nArguments\n\nupgrade::Bool=false: whether or not to automatically upgrade the data structure in url_in to latest.\nmip_solver=nothing: a MIP solver to use if no MIP solver specified in the DB.\nlp_solver=nothing: a LP solver to use if no LP solver specified in the DB.\nadd_constraints=m -> nothing: a function that receives the Model object as argument and adds custom user constraints.\nlog_level::Int=3: an integer to control the log level.\noptimize::Bool=true: whether or not to optimise the model (useful for running tests).\nupdate_names::Bool=false: whether or not to update variable and constraint names after the model rolls (expensive).\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nwrite_as_roll::Int=0: if greater than 0 and the run has a rolling horizon, then write results every that many windows.\nuse_direct_model::Bool=false: whether or not to use JuMP.direct_model to build the Model object.\nfilters::Dict{String,String}=Dict(\"tool\" => \"object_activity_control\"): a dictionary to specify filters. Possible keys are \"tool\" and \"scenario\". Values should be a tool or scenario name in the input DB.\nlog_file_path::String=nothing: if not nothing, log all console output to a file at the given path. The file is overwritten at each call.\nresume_file_path::String=nothing: only relevant in rolling horizon optimisations with write_as_roll greater or equal than one. If the file at given path contains resume data from a previous run, start the run from that point. Also, save resume data to that same file as the model rolls and results are written to the output database.\n\nExample\n\nusing SpineOpt\nm = run_spineopt(\n raw\"sqlite:///C:\\path\\to\\your\\inputputdb.sqlite\", \n raw\"sqlite:///C:\\path\\to\\your\\outputdb.sqlite\";\n filters=Dict(\"tool\" => \"object_activity_control\", \"scenario\" => \"scenario_to_run\"),\n alternative=\"your_results_alternative\"\n)\n\n\n\n\n\n","category":"function"},{"location":"library/#SpineOpt.write_report_from_intermediate_results","page":"Library","title":"SpineOpt.write_report_from_intermediate_results","text":"write_report_from_intermediate_results(intermediate_results_folder, default_url; )\n\nCollect results generated on a previous, unsuccessful SpineOpt run from intermediate_results_folder, and write the corresponding report(s) to url_out. A new Spine database is created at url_out if one doesn't exist.\n\nArguments\n\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nlog_level::Int=3: an integer to control the log level.\n\n\n\n\n\n","category":"function"},{"location":"library/#SpineOpt.generate_forced_availability_factor","page":"Library","title":"SpineOpt.generate_forced_availability_factor","text":"generate_forced_availability_factor(url_in, url_out; )\n\nGenerate forced availability factors (due to outages) from the contents of url_in and write them to url_out. At least url_in must point to a valid Spine database. A new Spine database is created at url_out if one doesn't exist.\n\nTo generate forced availability factors for an entity, specify mean_time_to_failure and optionally mean_time_to_repair for that entity as a duration in the input DB.\n\nParameter forced_availability_factor will be written for those entites in the output DB, holding a time series with the availability factor due to forced outages.\n\nArguments\n\nalternative::String=\"\": if non empty, write results to the given alternative in the output DB.\nfilters::Dict{String,String}=Dict(\"tool\" => \"object_activity_control\"): a dictionary to specify filters. Possible keys are \"tool\" and \"scenario\". Values should be a tool or scenario name in the input DB.\n\nExample\n\nusing SpineOpt\nm = generate_forced_availability_factor(\n raw\"sqlite:///C:\\path\\to\\your\\inputputdb.sqlite\", \n raw\"sqlite:///C:\\path\\to\\your\\outputdb.sqlite\"\n)\n\n\n\n\n\n","category":"function"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Internals","page":"Library","title":"Internals","text":"","category":"section"},{"location":"library/#Variable-library","page":"Library","title":"Variable library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"unit_flow_indices","category":"page"},{"location":"library/#SpineOpt.unit_flow_indices","page":"Library","title":"SpineOpt.unit_flow_indices","text":"unit_flow_indices(\n unit=anything,\n node=anything,\n direction=anything,\n s=anything\n t=anything\n)\n\nA list of NamedTuples corresponding to indices of the unit_flow variable where the keyword arguments act as filters for each dimension.\n\n\n\n\n\n","category":"function"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Constraint-library","page":"Library","title":"Constraint library","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"library/#Objective","page":"Library","title":"Objective","text":"","category":"section"},{"location":"library/","page":"Library","title":"Library","text":"TODO","category":"page"},{"location":"concept_reference/fix_ratio_out_out_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_out_out_unit_flow and fixes the ratio between outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the nodes (or group of nodes) in this relationship represent the to_node's', i.e. outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of out1 over out2, where out1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/fix_ratio_out_out_unit_flow/","page":"-","title":"-","text":"To enforce a fixed ratio between two products of a unit u, e.g. fixing the share of produced electricity flowing to node el to 0.4 of the production of heat flowing to node heat, the fix_ratio_out_out_unit_flow parameter would be set to 0.4 for the relationship u__el__heat.","category":"page"},{"location":"mathematical_formulation/constraints/#Constraints","page":"Constraints","title":"Constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Balance-constraint","page":"Constraints","title":"Balance constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_nodal_balance","page":"Constraints","title":"Nodal balance","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodal_balance!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_injection","page":"Constraints","title":"Node injection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnode_injection!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_state_capacity","page":"Constraints","title":"Node state capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodestatecapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_cyclic_node_state","page":"Constraints","title":"Cyclic condition on node state variable","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcyclicnodestate!","category":"page"},{"location":"mathematical_formulation/constraints/#Unit-operation","page":"Constraints","title":"Unit operation","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In the following, the operational constraints on the variables associated with units will be elaborated on. The static constraints, in contrast to the dynamic constraints, are addressing constraints without sequential time-coupling. It should however be noted that static constraints can still perform temporal aggregation.","category":"page"},{"location":"mathematical_formulation/constraints/#static-constraints-unit","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The fundamental static constraints for units within SpineOpt relate to the relationships between commodity flows from and to units and to limits on the unit flow capacity.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_unit_flow","page":"Constraints","title":"Conversion constraint / limiting flow shares inprocess / relationship in process","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"A unit can have different commodity flows associated with it. The most simple relationship between these flows is a linear relationship between input and/or output nodes/node groups. SpineOpt holds constraints for each combination of flows and also for the type of relationship, i.e. whether it is a maximum, minimum or fixed ratio between commodity flows. Note that node groups can be used in order to aggregate flows, i.e. to give a ratio between a combination of units flows.","category":"page"},{"location":"mathematical_formulation/constraints/#ratio_unit_flow","page":"Constraints","title":"Ratios between flows of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiounitflow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_flow_capacity","page":"Constraints","title":"Bounds on the unit capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowcapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_minimum_operating_point","page":"Constraints","title":"Constraint on minimum operating point","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminimumoperatingpoint!","category":"page"},{"location":"mathematical_formulation/constraints/#Dynamic-constraints","page":"Constraints","title":"Dynamic constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Commitment-constraints","page":"Constraints","title":"Commitment constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For modeling certain technologies/units, it is important to not only have unit_flow variables of different commodities, but also model the online (\"commitment\") status of the unit/technology at every time step. Therefore, an additional variable units_on is introduced. This variable represents the number of online units of that technology (for a normal unit commitment model, this variable might be a binary, for investment planning purposes, this might also be an integer or even a continuous variable). To define the type of a commitment variable, see online_variable_type. Commitment variables will be introduced by the following constraints (with corresponding parameters):","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"constraint on units_on\nconstraint on units_available\nconstraint on the unit state transition\nconstraint on minimum down time\nconstraint on minimum up time\nconstraint on ramp rates\nconstraint on reserve provision","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_available","page":"Constraints","title":"Bound on available units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunits_available!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_on","page":"Constraints","title":"Bound on online units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunits_on!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_state_transition","page":"Constraints","title":"Unit state transition","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitstatetransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_down_time","page":"Constraints","title":"Minimum down time","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmindowntime!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_up_time","page":"Constraints","title":"Minimum up time","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminuptime!","category":"page"},{"location":"mathematical_formulation/constraints/#Ramping-constraints","page":"Constraints","title":"Ramping constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"To include ramping and reserve constraints, it is a pre requisite that minimum operating points and capacity constraints are enforced as described.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For dispatchable units, additional ramping constraints can be introduced. For setting up ramping characteristics of units see Ramping.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ramp_up","page":"Constraints","title":"Ramp up limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintramp_up!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ramp_down","page":"Constraints","title":"Ramp down limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintramp_down!","category":"page"},{"location":"mathematical_formulation/constraints/#Reserve-constraints","page":"Constraints","title":"Reserve constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_res_minimum_node_state","page":"Constraints","title":"Constraint on minimum node state for reserve provision","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-11-20: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Operating-segments","page":"Constraints","title":"Operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_operating_point_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintoperatingpointbounds!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_operating_point_rank","page":"Constraints","title":"Rank operating segments as per the index of operating points","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintoperatingpointrank!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_bounds!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_rank","page":"Constraints","title":"Bounding operating segments to use up its own capacity for activating the next segment","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_rank!","category":"page"},{"location":"mathematical_formulation/constraints/#unit_flow_op_sum","page":"Constraints","title":"Bounding unit flows by summing over operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitflowop_sum!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_unit_pw_heat_rate","page":"Constraints","title":"Unit piecewise incremental heat rate","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitpwheat_rate!","category":"page"},{"location":"mathematical_formulation/constraints/#Bounds-on-commodity-flows","page":"Constraints","title":"Bounds on commodity flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_total_cumulated_unit_flow","page":"Constraints","title":"Bound on cumulated unit flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstrainttotalcumulatedunit_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#Network-constraints","page":"Constraints","title":"Network constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#static-constraints-connection","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_capacity","page":"Constraints","title":"Capacity constraint on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowcapacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_out_in_connection_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiooutinconnectionflow!","category":"page"},{"location":"mathematical_formulation/constraints/#Specific-network-representation","page":"Constraints","title":"Specific network representation","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In the following, the different specific network representations are introduced. While the Static constraints find application in any of the different networks, the following equations are specific to the discussed use cases. Currently, SpineOpt incorporated equations for pressure driven gas networks, nodal lossless DC power flows and PTDF based lossless DC power flow.","category":"page"},{"location":"mathematical_formulation/constraints/#pressure-driven-gas-transfer-math","page":"Constraints","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For gas pipelines it can be relevant a pressure driven gas transfer can be modelled, i.e. to account for linepack flexibility. Generally speaking, the main challenges related to pressure driven gas transfers are the non-convexities associated with the Weymouth equation. In SpineOpt, a convexified MILP representation has been implemented, which as been presented in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. The approximation approach is based on the Taylor series expansion around fixed pressure points.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"In addition to the already known variables, such as connection_flow and node_state, the start and end points of a gas pipeline connection are associated with the variable node_pressure. The variable is triggered by the has_pressure parameter. For more details on how to set up a gas pipeline, see also the advanced concept section on pressure driven gas transfer.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_max_node_pressure","page":"Constraints","title":"Maximum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmaxnodepressure!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_node_pressure","page":"Constraints","title":"Minimum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminnodepressure!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_compression_factor","page":"Constraints","title":"Constraint on the pressure ratio between two nodes","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcompression_ratio!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_fixed_node_pressure_point","page":"Constraints","title":"Outer approximation through fixed pressure points","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintfixnodepressure_point!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_unitary_gas_flow","page":"Constraints","title":"Enforcing unidirectional flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionunitarygas_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_gas_capacity","page":"Constraints","title":"Gas connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowgas_capacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storage_line_pack","page":"Constraints","title":"Linepack storage flexibility","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragelinepack!","category":"page"},{"location":"mathematical_formulation/constraints/#nodal-lossless-DC","page":"Constraints","title":"Node-based lossless DC power flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"For the implementation of the nodebased loss DC powerflow model, a new variable node_voltage_angle is introduced. See also has_voltage_angle. For further explanation on setting up a database for nodal lossless DC power flow, see the advanced concept chapter on Lossless nodal DC power flows.","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_max_node_voltage_angle","page":"Constraints","title":"Maximum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintmaxnodevoltage_angle!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_min_node_voltage_angle","page":"Constraints","title":"Minimum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintminnodevoltage_angle!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_node_voltage_angle","page":"Constraints","title":"Voltage angle to connection flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintnodevoltageangle!","category":"page"},{"location":"mathematical_formulation/constraints/#PTDF-lossless-DC","page":"Constraints","title":"PTDF based DC lossless powerflow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connection_intact_flow_ptdf","page":"Constraints","title":"Connection intact flow PTDF","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionintactflow_ptdf!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_lodf","page":"Constraints","title":"N-1 post contingency connection flow limits","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowlodf!","category":"page"},{"location":"mathematical_formulation/constraints/#Investments","page":"Constraints","title":"Investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#Investments-in-units","page":"Constraints","title":"Investments in units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_unit_lifetime","page":"Constraints","title":"Economic lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-03: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-unit","page":"Constraints","title":"Technical lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_invested_available","page":"Constraints","title":"Available Investment Units","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitsinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_units_invested_transition","page":"Constraints","title":"Investment transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintunitsinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#Investments-in-connections","page":"Constraints","title":"Investments in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_connections_invested_available","page":"Constraints","title":"Available invested-in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionsinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connections_invested_transition","page":"Constraints","title":"Transfer of previous investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionsinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_flow_intact_flow","page":"Constraints","title":"Intact network ptdf-based flows on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionflowintact_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_intact_flow_capacity","page":"Constraints","title":"Intact connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintconnectionintactflow_capacity!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_ratio_out_in_connection_intact_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming intact flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintratiooutinconnectionintact_flow!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_candidate_connection_flow_lb","page":"Constraints","title":"Lower bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcandidateconnectionflow_lb!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_candidate_connection_flow_ub","page":"Constraints","title":"Upper bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintcandidateconnectionflow_ub!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_connection_lifetime","page":"Constraints","title":"Economic lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-connection","page":"Constraints","title":"Technical lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Investments-in-storages","page":"Constraints","title":"Investments in storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Note: can we actually invest in nodes that are not storages? (e.g. new location)","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storages_invested_available","page":"Constraints","title":"Available invested storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragesinvestedavailable!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storages_invested_transition","page":"Constraints","title":"Storage capacity transfer ","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintstoragesinvestedtransition!","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_storage_lifetime","page":"Constraints","title":"Economic lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Technical-lifetime-of-a-storage","page":"Constraints","title":"Technical lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Capacity-transfer","page":"Constraints","title":"Capacity transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#Early-retirement-of-capacity","page":"Constraints","title":"Early retirement of capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints/#User-constraints","page":"Constraints","title":"User constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints/#constraint_user_constraint","page":"Constraints","title":"User constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"@@addconstraintuser_constraint!","category":"page"},{"location":"mathematical_formulation/constraints/#benders_decomposition","page":"Constraints","title":"Benders decomposition","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This section describes the high-level formulation of the benders-decomposed problem.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Taking the simple example of minimising capacity and operating cost for a fleet of units with a linear cost coefficient p^operational_cost:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sum_ust left( p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ sum_nd p^operational_cost_(undst) cdot v^unit_flow_(u n d s t) right) \nst \n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + v^units_invested_available_(u s t)\nright) quad forall u in unit n in node s t\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"So this is a single problem that can't be decoupled over t because the investment variables units_invested_available couple the timesteps together. If units_invested_available were a constant in the problem, then all t's could be solved individually. This is the basic idea in Benders decomposition. We decompose the problem into a master problem and sub problems with the master problem optimising the coupling investment variables which are treated as constants in the sub problems.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The master problem is built by replacing the operational costs (which will be minimised in the sub problem) by a new decision variable, v^sp_objective:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust) + v^sp_objective \nst \n v^sp_objective geq 0\nendaligned\n","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The solution to this problem yields values for the investment variables which are fixed as p^units_invested_available in the sub problem and will be zero in the first iteration.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The sub problem for benders iteration b then becomes :","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sp_obj_b = sum_undst p^operational_cost_(undst) cdot v^unit_flow_(u n d s t)\nst\n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + p^units_invested_available_(b u s t)\nright) \n qquad forall u in unit n in node st qquad mu_(bust)\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This sub problem can be solved individually for each t. This is pretty trivial in this small example but if we consider a single t to be a single rolling horizon instead, decoupling the investment variables means that each rolling horizon can be solved individually rather than having to solve the entire model horizon as a single problem.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"mu_(bust) is the marginal value of the capacity constraint for benders iteration b and can be interpreted as the decrease in the objective function for an additional MW of flow from unit u (in scenario s at time t). Thus, an upper bound on the sub problem objective function is obtained as follows:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"sp_obj_b + sum_undst mu_(bust) cdot p^unit_capacity_(undst) \ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right)","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The above is added to the master problem for the next iteration as a new constraint, called a Benders cut, thus becoming:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ v^sp_objective \n\nst \n\n v^sp_objective geq sp_obj_b \n quad + sum_undst mu_(bust) cdot p^unit_capacity_(undst)\ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right) quad forall b \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"Note the benders cuts are added as inequalities because they represent an upper bound on the value we are going to get for the sub problem objective function by adjusting the master problem variables in that benders iteration. If we consider the example of renewable generation - because it's marginal cost is zero, on the first benders iteration, it could look like there would be a lot of value in increasing the capacity because of the marginal values from the sub problems. However, when the capacity variables are increased accordingly and curtailment occurs in the sub-problems, the marginal values will be zero when curtailment occurs and so, other resources may become optimal in subsequent iterations.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"This is a simple example but it illustrates the general strategy. The algorithm pseudo code looks something like this:","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":" initialise master problem\n initialise sub problem\n solve first master problem\n create master problem variable time series\n solve rolling spine opt model\n save zipped marginal values\n while master problem not converged\n update master problem\n solve master problem\n update master problem variable timeseries for benders iteration b\n rewind sub problem\n update sub problem\n solve rolling spine opt model\n save zipped marginal values\n test for convergence\n end","category":"page"},{"location":"mathematical_formulation/constraints/#constraint_mp_any_invested_cuts","page":"Constraints","title":"Benders cuts","text":"","category":"section"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"The benders cuts for the problem including all investments in candidate connections, storages and units is given below.","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^sp_objective \n geq \n p^sp_obj_(b) + \n sum_ust p^units_invested_available_mv_(bust)\ncdot left( v^units_invested_available_(ust) - p^units_invested_available_(ust) right) \n + sum_cst p^connections_invested_available_mv_(bcst)\ncdot left( v^connections_invested_available_(cst) - p^connections_invested_available_(cst) right) \n + sum_nst p^storages_invested_available_mv_(bnst)\ncdot left( v^storages_invested_available_(nst) - p^storages_invested_available_(nst) right) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints/","page":"Constraints","title":"Constraints","text":"p^sp_obj_(b) is the sub problem objective function value in benders iteration b,\np^units_invested_available_mv is the reduced cost of the units_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a unit of this type, \np^connections_invested_available_mv is the reduced cost of the connections_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a connection of this type, \np^storages_invested_available_mv is the reduced cost of the storages_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a storage node of this type, \np^units_invested_available is the value of the fixed sub problem variable units_invested_available in benders iteration b, \np^connections_invested_available is the value of the fixed sub problem variable connections_invested_available in benders iteration b and \np^storages_invested_available is the value of the fixed sub problem variable storages_invested_available in benders iteration b","category":"page"},{"location":"concept_reference/Object Classes/#Object-Classes","page":"Object Classes","title":"Object Classes","text":"","category":"section"},{"location":"concept_reference/Object Classes/#commodity","page":"Object Classes","title":"commodity","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A good or product that can be consumed, produced, traded. E.g., electricity, oil, gas, water...","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: commodity_lodf_tolerance, commodity_physics_duration, commodity_physics, commodity_ptdf_threshold, is_active, mp_min_res_gen_to_demand_ratio_slack_penalty and mp_min_res_gen_to_demand_ratio","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: node__commodity and unit__commodity","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)","category":"page"},{"location":"concept_reference/Object Classes/#connection","page":"Object Classes","title":"connection","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A transfer of commodities between nodes. E.g. electricity line, gas pipeline...","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: benders_starting_connections_invested, candidate_connections, connection_availability_factor, connection_contingency, connection_investment_cost, connection_investment_lifetime, connection_investment_variable_type, connection_monitored, connection_reactance_base, connection_reactance, connection_resistance, connection_type, connections_invested_big_m_mga, connections_invested_mga_weight, connections_invested_mga, fix_connections_invested_available, fix_connections_invested, forced_availability_factor, graph_view_position, has_binary_gas_flow, initial_connections_invested_available, initial_connections_invested and is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__investment_group, connection__investment_stochastic_structure, connection__investment_temporal_block, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node and connection__user_constraint","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A connection represents a transfer of one commodity over space. For example, an electricity transmission line, a gas pipe, a river branch, can be modelled using a connection.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A connection always takes commodities from one or more nodes, and releases them to one or more (possibly the same) nodes. The former are specificed through the connection__from_node relationship, and the latter through connection__to_node. Every connection inherits the temporal and stochastic structures from the associated nodes. The model will generate connection_flow variables for every combination of connection, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The operation of the connection is specified through a number of parameter values. For example, the capacity of the connection, as the maximum amount of energy that can enter or leave it, is given by connection_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow, and min_ratio_out_in_connection_flow parameters in the connection__node__node relationship. The delay on a connection, as the time it takes for the energy to go from one end to the other, is given by connection_flow_delay.","category":"page"},{"location":"concept_reference/Object Classes/#investment_group","page":"Object Classes","title":"investment_group","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A group of investments that need to be done together.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: equal_investments, maximum_capacity_invested_available, maximum_entities_invested_available, minimum_capacity_invested_available and minimum_entities_invested_available","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__investment_group, connection__to_node__investment_group, node__investment_group, unit__from_node__investment_group, unit__investment_group and unit__to_node__investment_group","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.","category":"page"},{"location":"concept_reference/Object Classes/#model","page":"Object Classes","title":"model","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"An instance of SpineOpt, that specifies general parameters such as the temporal horizon.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: big_m, db_lp_solver_options, db_lp_solver, db_mip_solver_options, db_mip_solver, duration_unit, is_active, max_gap, max_iterations, max_mga_iterations, max_mga_slack, min_iterations, model_end, model_start, model_type, roll_forward, window_duration, window_weight, write_lodf_file, write_mps_file and write_ptdf_file","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: model__default_investment_stochastic_structure, model__default_investment_temporal_block, model__default_stochastic_structure, model__default_temporal_block, model__report, model__stochastic_structure and model__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).","category":"page"},{"location":"concept_reference/Object Classes/#node","page":"Object Classes","title":"node","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A universal aggregator of commodify flows over units and connections, with storage capabilities.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: balance_type, benders_starting_storages_invested, candidate_storages, demand, downward_reserve, fix_node_pressure, fix_node_state, fix_node_voltage_angle, fix_storages_invested_available, fix_storages_invested, frac_state_loss, fractional_demand, graph_view_position, has_pressure, has_state, has_voltage_angle, initial_node_pressure, initial_node_state, initial_node_voltage_angle, initial_storages_invested_available, initial_storages_invested, is_active, is_non_spinning, is_reserve_node, max_node_pressure, max_voltage_angle, min_node_pressure, min_voltage_angle, minimum_reserve_activation_time, nodal_balance_sense, node_opf_type, node_slack_penalty, node_state_cap, node_state_min, state_coeff, storage_investment_cost, storage_investment_lifetime, storage_investment_variable_type, storages_invested_big_m_mga, storages_invested_mga_weight, storages_invested_mga, tax_in_unit_flow, tax_net_unit_flow, tax_out_unit_flow and upward_reserve","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__investment_group, connection__from_node__user_constraint, connection__from_node, connection__node__node, connection__to_node__investment_group, connection__to_node__user_constraint, connection__to_node, node__commodity, node__investment_group, node__investment_stochastic_structure, node__investment_temporal_block, node__node, node__stochastic_structure, node__temporal_block, node__user_constraint, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint and unit__to_node","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.","category":"page"},{"location":"concept_reference/Object Classes/#output","page":"Object Classes","title":"output","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A variable name from SpineOpt that can be included in a report.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active and output_resolution","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: report__output","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/Object Classes/#report","page":"Object Classes","title":"report","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A results report from a particular SpineOpt run, including the value of specific variables.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active and output_db_url","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: model__report and report__output","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A report is essentially a group of outputs from a model, that gets written into the output database as a result of running SpineOpt. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/Object Classes/#settings","page":"Object Classes","title":"settings","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Internal SpineOpt settings. We kindly advise not to mess with this one.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: version","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"TODO","category":"page"},{"location":"concept_reference/Object Classes/#stochastic_scenario","page":"Object Classes","title":"stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A scenario for stochastic optimisation in SpineOpt.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: parent_stochastic_scenario__child_stochastic_scenario and stochastic_structure__stochastic_scenario","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Essentially, a stochastic_scenario is a label for an alternative period of time, describing one possibility of what might come to pass. They are the basic building blocks of the scenario-based Stochastic Framework in SpineOpt.jl, but aren't really meaningful on their own. Only when combined into a stochastic_structure using the stochastic_structure__stochastic_scenario and parent_stochastic_scenario__child_stochastic_scenario relationships, along with Parameters like the weight_relative_to_parents and stochastic_scenario_end, they become meaningful.","category":"page"},{"location":"concept_reference/Object Classes/#stochastic_structure","page":"Object Classes","title":"stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A group of stochastic scenarios that represent a structure.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__investment_stochastic_structure, model__default_investment_stochastic_structure, model__default_stochastic_structure, model__stochastic_structure, node__investment_stochastic_structure, node__stochastic_structure, stochastic_structure__stochastic_scenario, unit__investment_stochastic_structure and units_on__stochastic_structure","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.","category":"page"},{"location":"concept_reference/Object Classes/#temporal_block","page":"Object Classes","title":"temporal_block","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A length of time with a particular resolution.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: block_end, block_start, is_active, representative_periods_mapping, resolution and weight","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__investment_temporal_block, model__default_investment_temporal_block, model__default_temporal_block, model__temporal_block, node__investment_temporal_block, node__temporal_block, unit__investment_temporal_block and units_on__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.","category":"page"},{"location":"concept_reference/Object Classes/#unit","page":"Object Classes","title":"unit","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A conversion of one/many comodities between nodes.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: benders_starting_units_invested, candidate_units, curtailment_cost, fix_units_invested_available, fix_units_invested, fix_units_on, fom_cost, forced_availability_factor, graph_view_position, initial_units_invested_available, initial_units_invested, initial_units_on, is_active, is_renewable, min_down_time, min_up_time, number_of_units, online_variable_type, shut_down_cost, start_up_cost, unit_availability_factor, unit_investment_cost, unit_investment_lifetime, unit_investment_variable_type, units_invested_big_m_mga, units_invested_mga_weight, units_invested_mga, units_on_cost, units_on_non_anticipativity_margin and units_on_non_anticipativity_time","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: unit__commodity, unit__from_node__investment_group, unit__from_node__user_constraint, unit__from_node, unit__investment_group, unit__investment_stochastic_structure, unit__investment_temporal_block, unit__node__node, unit__to_node__investment_group, unit__to_node__user_constraint, unit__to_node, unit__user_constraint, units_on__stochastic_structure and units_on__temporal_block","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A unit represents an energy conversion process, where energy of one commodity can be converted into energy of another commodity. For example, a gas turbine, a power plant, or even a load, can be modelled using a unit.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A unit always takes energy from one or more nodes, and releases energy to one or more (possibly the same) nodes. The former are specificed through the unit__from_node relationship, and the latter through unit__to_node. Every unit has a temporal and stochastic structures given by the units_on__temporal_block and [units_on__stochastic_structure] relationships. The model will generate unit_flow variables for every combination of unit, node, direction (from node or to node), time slice, and stochastic scenario, according to the above relationships.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The operation of the unit is specified through a number of parameter values. For example, the capacity of the unit, as the maximum amount of energy that can enter or leave it, is given by unit_capacity. The conversion ratio of input to output can be specified using any of fix_ratio_out_in_unit_flow, max_ratio_out_in_unit_flow, and min_ratio_out_in_unit_flow. The variable operating cost is given by vom_cost.","category":"page"},{"location":"concept_reference/Object Classes/#user_constraint","page":"Object Classes","title":"user_constraint","text":"","category":"section"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"A generic data-driven custom constraint.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Parameters: constraint_sense, is_active, right_hand_side and user_constraint_slack_penalty","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Related Relationship Classes: connection__from_node__user_constraint, connection__to_node__user_constraint, connection__user_constraint, node__user_constraint, unit__from_node__user_constraint, unit__to_node__user_constraint and unit__user_constraint","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"The user_constraint is a generic data-driven custom constraint, which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant terms of the constraint.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"concept_reference/Object Classes/","page":"Object Classes","title":"Object Classes","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"concept_reference/max_cum_in_unit_flow_bound/","page":"-","title":"-","text":"To impose a limit on the cumulative in flows to a unit for the entire modelling horizon, e.g. to enforce limits on emissions, the max_cum_in_unit_flow_bound parameter can be used. Defining this parameter triggers the generation of the constraint_max_cum_in_unit_flow_bound.","category":"page"},{"location":"concept_reference/max_cum_in_unit_flow_bound/","page":"-","title":"-","text":"Assuming for instance that the total intake of a unit u_A should not exceed 10MWh for the entire modelling horizon, then the max_cum_in_unit_flow_bound would need to take the value 10. (Assuming here that the unit_flow variable is in MW, and the model duration_unit is hours)","category":"page"},{"location":"tutorial/unit_commitment/#Unit-commitment-constraints-tutorial","page":"Unit Commitment","title":"Unit commitment constraints tutorial","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial provides a step-by-step guide to include unit commitment constraints in a simple energy system with Spine Toolbox for SpineOpt.","category":"page"},{"location":"tutorial/unit_commitment/#Introduction","page":"Unit Commitment","title":"Introduction","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Welcome to our tutorial, where we will walk you through the process of adding unit commitment constraints in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.","category":"page"},{"location":"tutorial/unit_commitment/#Model-assumptions","page":"Unit Commitment","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial is built on top of the Simple System. The main changes to that system are:","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The demand at electricity_node is a 24-hour time series instead of a unique value\nThe power_plant_b has new parameters to account for the unit commitment constraints, such as minimum operating point, minimum uptime, and minimum downtime\nThe optimization is done a mixed-integer programming (MIP) to account for the binary nature of the unit commitment decision variables","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"This tutorial includes a step-by-step guide to include the parameters to help analyze the results in SpineOpt and the unit commitment concepts.","category":"page"},{"location":"tutorial/unit_commitment/#Step-1-Update-the-demand","page":"Unit Commitment","title":"Step 1 - Update the demand","text":"","category":"section"},{"location":"tutorial/unit_commitment/#Opening-the-Simple-System-project","page":"Unit Commitment","title":"Opening the Simple System project","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.\nLocate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In this tutorial, you will learn how to add unit commitment constraints to the Simple System using the Spine DB editor, but first let's start by updating the electricity demand from a single value to a 24-hour time series.","category":"page"},{"location":"tutorial/unit_commitment/#Editing-demand-value","page":"Unit Commitment","title":"Editing demand value","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [node] class, and select the electricity_node from the expanded tree.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table, identify the demand parameter which should have a 150 value from the Simple System first run.\nRight click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.\nChange the Parameter type to Time series fixed resolution, Resolution to 1h, and the demand values to the time series as in the image below. You can copy and paste the values from the file: ucelectricitynode_demand.csv\nFinish by pressing OK in the Edit value menu. In the Object parameter table you will see that the value of the demand has changed to Time series.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Editing-the-temporal-block","page":"Unit Commitment","title":"Editing the temporal block","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"You might or might not notice that the Simple System has, by default, a temporal block resolution of 1D (i.e., one day); wait, what! Yes, by default, it has 1D in its template. So, we want to change that to 1h since our unit commitment case study is for a day-ahead dispatch of 24 hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate again the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [temporal_block] class, and select the flat from the expanded tree.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table, identify the resolution parameter which should have a 1D value from the Simple System first run.\nRight click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.\nChange the Duration from 1D to 1h as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Establishing-new-output-relationships","page":"Unit Commitment","title":"Establishing new output relationships","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Since we will have the new unit commitment variables, we want to see the results of these variables and their total cost in the objective function. So, we will create new relationships to report these results:","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and units_on under output. Repete the same procedure for the following outputs as seen in the image below; then press OK.\nThis will write the unit commitment variable values and costs in the objective function to the output database as a part of report1.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow","page":"Unit Commitment","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results","page":"Unit Commitment","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. As expected, the power_plant_a (i.e., the cheapest unit) always covers the demand first until its maximum capacity, and then the power_plant_b (i.e., the more expensive unit) covers the demand that is left. This is the most economical dispatch since the problem has no extra constraints (so far!).","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"To explore the cost results, the pivot table view shows a more user-friendly option to analyze the results. Remember that you can find a description of how to create the pivot table view in the Simple System tutorial here. The cost components in the objective function are shown in the image below. As expected, all the costs are associated with the variable_om_costs since we haven't included the unit-commitment constraints yet.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-2-Include-the-minimum-operating-point","page":"Unit Commitment","title":"Step 2 - Include the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b has a minimum operating point of 10%, meaning that if the power plant is on, it must produce at least 20MW.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minium-operating-point","page":"Unit Commitment","title":"Adding the minium operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nIn Relationship tree, expand the unit__to_node class and select power_plant_b | electricity_node.\nIn the Relationship parameter table (typically at the bottom-center), select the minimum_operating_point parameter and the Base alternative, and enter the value 0.1 as seen in the image below. This will set the minimum operating point of power_plant_b when producing electricity.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-unit-commitment-costs-and-initial-states","page":"Unit Commitment","title":"Adding the unit commitment costs and initial states","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:\nonline_variable_type parameter and the Base alternative, and select the value unit_online_variable_type_binary. This will define that the unit commitment variables will be binary. SpineOpt identifies this situation from the input data and internally changes the model from LP to MIP.\nshut_down_cost parameter and the Base alternative, and enter the value 7. This will establish that there's a cost of '7' EUR per shutdown.\nstart_up_cost parameter and the Base alternative, and enter the value 5. This will establish that there's a cost of '5' EUR per startup.\nunits_on_cost parameter and the Base alternative, and enter the value 3. This will establish that there's a cost of '3' EUR per units on (e.g., idling cost).\ninitial_units_on parameter and the Base alternative, and enter the value 0. This will establish that there are no units 'on' before the first time step.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-operating-point","page":"Unit Commitment","title":"Executing the workflow including the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.\nDo you notice something different in your solver log? Depending on the solver, the output might change, but you should be able to see that the solver is using MIP to solve the problem. For instance, if you are using the solver HiGHS (i.e., the default solver in SpineOpt), then you will see something like \"Solving MIP model with:\" and the Branch and Bound (B&B) tree solution. Since this is a tiny problem, sometimes the solver can find the optimal solution from the presolve step, avoiding going into the B&B step.","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-operating-point","page":"Unit Commitment","title":"Examining the results including the minimum operating point","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Any difference? What happended to the flows in power_plant_a and power_plant_b?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look to the units_on and units_started_up in the image below to get wider perspective.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"So, since power_plant_b needs to be at least producing 20MW when it is 'on', then power_plant_a needs to reduce its output even though it has the lower variable cost, making the total system cost (i.e., objective function) more expensive than in the previous run. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-3-Include-the-minimum-uptime","page":"Unit Commitment","title":"Step 3 - Include the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b also has a minimum uptime of 8 hours, meaning that if the power plant starts up, it must be on at least eight hours.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minimum-uptime","page":"Unit Commitment","title":"Adding the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the min_up_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum uptime is eight hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-uptime","page":"Unit Commitment","title":"Executing the workflow including the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"You know the drill, go ahead :wink:","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-uptime","page":"Unit Commitment","title":"Examining the results including the minimum uptime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Interesting. Don't you think?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look again to the units_on and units_started_up in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"So, since power_plant_b needs to be at least producing 20MW when it is 'on' and also needs to be at least 8h 'on' each time it starts, then power_plant_b starts even before the demand is greater than the capacity of power_plant_a. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/#Step-4-Include-the-minimum-downtime","page":"Unit Commitment","title":"Step 4 - Include the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's assume that the power_plant_b also has a minimum downtime of 8 hours, meaning that if the power plant shuts down, it must be off at least eight hours.","category":"page"},{"location":"tutorial/unit_commitment/#Adding-the-minimum-downtime","page":"Unit Commitment","title":"Adding the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nExpand the [unit] class, and select the power_plant_b from the expanded tree.\nIn the Object parameter table (typically at the top-center), select the min_down_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum downtime is eight hours.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"When you're ready, commit all changes to the database.","category":"page"},{"location":"tutorial/unit_commitment/#Executing-the-workflow-including-the-minimum-downtime","page":"Unit Commitment","title":"Executing the workflow including the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"One last time, don't give up!","category":"page"},{"location":"tutorial/unit_commitment/#Examining-the-results-including-the-minimum-downtime","page":"Unit Commitment","title":"Examining the results including the minimum downtime","text":"","category":"section"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.\nYou can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.\nRemember to select the latest run in the Alternative tree. Expand the Output element if not expanded.\nIn the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.\nThe image below shows the electricity flow results for both power plants. Wow! This result is even more interesting :stuckouttonguewinkingeye:. Do you know what happened?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Let's take a look again to the units_on and units_started_up in the image below. Instead of two start-ups, the power_plant_b only starts once. Why?","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"Since power_plant_b needs to be at least producing 20MW when it is 'on' plus also needs to be at least 8h 'on' each time it starts, and it needs to be at least 8h 'off' if it shutdowns, then power_plant_b never shuts down and stays 'on' after it starts because it is the only way to fulfil the unit commitment constraints. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs (which is zero this time), and the increase in the variable_om_costs due to flow changes.","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"(Image: image)","category":"page"},{"location":"tutorial/unit_commitment/","page":"Unit Commitment","title":"Unit Commitment","text":"If you have completed this tutorial, congratulations! You have mastered the basic concepts of unit commitment using SpineToolbox and SpineOpt. Keep up the good work!","category":"page"},{"location":"concept_reference/fixed_pressure_constant_0/","page":"-","title":"-","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The second fixed pressure constant, which will be multiplied with the pressure of the destination node, is represented by an Array value of the fixed_pressure_constant_0. The first pressure constant corresponds to the related parameter fixed_pressure_constant_1. Note that the fixed_pressure_constant_0 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/min_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the min_ratio_in_in_unit_flow parameter triggers the generation of the constraint_min_ratio_in_in_unit_flow and sets a lower bound for the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/min_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a minimum share of 0.2 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the min_ratio_in_in_unit_flow parameter would be set to 0.2 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"advanced_concepts/mga/#mga-advanced","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"Through modelling to generate alternatives (short MGA), near-optimal solutions can be explored under certain conditions. Currently, SpineOpt supports two methods for MGA are available.","category":"page"},{"location":"advanced_concepts/mga/#Modelling-to-generate-alternative:-Maximally-different-portfolios","page":"Modelling to generate alternatives","title":"Modelling to generate alternative: Maximally different portfolios","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"The idea is that an orginal problem is solved, and subsequently solved again under the condition that the realization of variables should be maximally different from the previous iteration(s), while keeping the objective function within a certain threshold (defined by max_mga_slack).","category":"page"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"In SpineOpt, we choose units_invested_available, connections_invested_available, and storages_invested_available as variables that can be considered for the maximum-difference-problem. The implementation is based on Modelling to generate alternatives: A technique to explore uncertainty in energy-environment-economy models.","category":"page"},{"location":"advanced_concepts/mga/#How-to-set-up-an-MGA-problem","page":"Modelling to generate alternatives","title":"How to set up an MGA problem","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"model: In order to explore an MGA model, you will need one model of type spineopt_mga. You should also define the number of iterations (max_mga_iterations, and the maximum allowed deviation from the original objective function (max_mga_slack).\nat least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.\nTo include the investment decisions in the MGA difference maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.\nThe original MGA formulation is non-convex (maximization problem of an absolute function), but has been linearized through big M method. For this purpose, one should always make sure that units_invested_big_m_mga, connections_invested_big_m_mga, or storages_invested_big_m_mga, respectively, is sufficently large to always be larger the the maximum possible difference per MGA iteration. (Typically the number of candidates could suffice.)\nAs outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.","category":"page"},{"location":"advanced_concepts/mga/#Modelling-to-generate-alternative:-Trade-offs-between-technology-investments","page":"Modelling to generate alternatives","title":"Modelling to generate alternative: Trade-offs between technology investments","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"The idea of this approach is to explore near-optimal solutions that maximize/minimize investment in a certain technology (or multiple technologies simultanesously). ","category":"page"},{"location":"advanced_concepts/mga/#How-to-set-up-an-MGA-problem-2","page":"Modelling to generate alternatives","title":"How to set up an MGA problem","text":"","category":"section"},{"location":"advanced_concepts/mga/","page":"Modelling to generate alternatives","title":"Modelling to generate alternatives","text":"model: In order to explore an MGA model, you will need one model of type spineopt_mga. The maximum allowed deviation from the original objective function should be defined via max_mga_slack. Note that for this method, we don't define an explicit number of iteration via the max_mga_iterations parameter (see also below)\nat least one investment candidate of type unit, connection, or node. For more details on how to set up an investment problem please see: Investment Optimization.\nTo include the investment decisions in the MGA min/maximization, the parameter units_invested_mga, connections_invested_mga, or storages_invested_mga need to be set to true, respectively.\nTo explore near-optimal solutions using this methodology, the units_invested_mga_weight, connections_invested_mga_weight, and storages_invested_mga_weight parameters are used to define near-optimal solutions. For this purpose, these parameters are defined as Arrays, defining the weight of the technology per iterations. Note that the length of these Arrays should be the same for all technologies, as this will correspond to the number of MGA iterations, i.e., the number of near-optimal solutions. To analyze the trade-off between two technology types, we can, e.g., define units_invested_mga_weight for unit group 1 as [-1,-0.5,0], whereas the use the weights [0,-0.5,-1] for the other technology storage group 1 in question. Note that a negative sign will correspond to a minimization of investments in the corresponding technology type, while positive signs correspond to a maximization of the respective technology. In the given example, we would hence first minimize the investments in unit group 1, then minimize the two technologies simultaneuously, and finally only minimize investments in storage group 2.\nAs outputs are used to intermediately store solutions from different MGA runs, it is important that units_invested, connections_invested, or storages_invested, respectively, are defined as output objects in your database.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Temporal-Framework","page":"Temporal Framework","title":"Temporal Framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Spine Model aims to provide a high degree of flexibility in the temporal dimension across different components of the created model. This means that the user has some freedom to choose how the temporal aspects of different components of the model are defined. This freedom increases the variety of problems that can be tackled in Spine: from very coarse, long term models, to very detailed models with a more limited horizon, or a mix of both. The choice of the user on how this flexibility is used will lead to the temporal structure of the model.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The main components of flexibility consist of the following parts:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The horizon that is modeled: end and start time\nTemporal resolution\nPossibility of a rolling optimization window\nSupport for commonly used methods such as representative days","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Part of the temporal flexibility in Spine is due to the fact that these options mentioned above can be implemented differently across different components of the model, which can be very useful when different markets are coupled in a single model. The resolution and horizon of the gas market can for example be taken differently than that of the electricity market. This documentation aims to give the reader insight in how these aspects are defined, and which objects are used for this.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"We start by introducing the relevant objects with their parameters, and the relevant relationship classes for the temporal structure. Afterwards, we will discuss how this setting creates flexibility and will present some of the practical approaches to create a variety of temporal structures.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Objects,-relationships,-and-their-parameters","page":"Temporal Framework","title":"Objects, relationships, and their parameters","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"In this section, the objects and relationships will be discussed that form the temporal structure together.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Objects-relevant-for-the-temporal-framework","page":"Temporal Framework","title":"Objects relevant for the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"For the objects, the relevant parameters will also be introduced, along with the type of values that are allowed, following the format below: ","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"'parameter_name' : \"Allowed value type\"","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model](@ref)-object","page":"Temporal Framework","title":"model object","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Each model object holds general information about the model at hand. Here we only discuss the time related parameters:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"model_start and model_end : \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"These two parameters define the model horizon. A Datetime value is to be taken for both parameters, in which case they directly mark respectively the beginning and end of the modeled time horizon.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"duration_unit (optional): \"minute or hour\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameters gives the unit of duration that is used in the model calculations. The default value for this parameter is 'minute'. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"roll_forward (optional): \"duration value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In the practical approaches presented below, the rolling window optimization will be explained in more detail.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[temporal_block](@ref)-object","page":"Temporal Framework","title":"temporal_block object","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"A temporal block defines the properties of the optimization that is to be solved in the current window. Most importantly, it holds the necessary information about the resolution and horizon of the optimization.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"resolution (optional): \"duration value\" or \"array of duration values\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"block_start (optional): \"duration value\" or \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Indicates the start of this temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"block_end(optional): \"duration value\" or \"Date time value\"","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Indicates the end of this temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Relationships-relevant-for-the-temporal-framework","page":"Temporal Framework","title":"Relationships relevant for the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#[model__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"In this relationship, a model instance is linked to a temporal block. If this relationship doesn't exist - the temporal block is disregarded from this optimization model.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model__default_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__default_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Defines the default temporal block used for model objects, which will be replaced when a specific relationship is defined for a model in model__temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[node__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"node__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship will link a node to a temporal block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[units_on__temporal_block](@ref)-relationship","page":"Temporal Framework","title":"units_on__temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship links the units_on variable of a unit to a temporal block and will therefore govern the time-resolution of the unit's online/offline status.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[unit__investment_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"unit__investment_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This relationship sets the temporal dimensions for investment decisions of a certain unit. The separation between this relationship and the units_on__temporal_block, allows the user for example to give a much finer resolution to a unit's on- or offline status than to it's investment decisions.","category":"page"},{"location":"advanced_concepts/temporal_framework/#[model__default_investment_temporal_block](@ref)-relationship","page":"Temporal Framework","title":"model__default_investment_temporal_block relationship","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Defines the default temporal block used for investment decisions, which will be replaced when a specific relationship is defined for a unit in unit__investment_temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/#General-principle-of-the-temporal-framework","page":"Temporal Framework","title":"General principle of the temporal framework","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The general principle of the Spine modeling temporal structure is that different temporal blocks can be defined and linked to different objects in a model. This leads to great flexibility in the temporal structure of the model as a whole. To illustrate this, we will discuss some of the possibilities that arise in this framework.","category":"page"},{"location":"advanced_concepts/temporal_framework/#One-single-temporal_block","page":"Temporal Framework","title":"One single temporal_block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Single-solve-with-single-block","page":"Temporal Framework","title":"Single solve with single block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The simplest case is a single solve of the entire time horizon (so roll_forward not defined) with a fixed resolution. In this case, only one temporal block has to be defined with a fixed resolution. Each node has to be linked to this temporal_block.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Alternatively, a variable resolution can be defined by choosing an array of durations for the resolution parameter. The sum of the durations in the array then have to match the length of the temporal block. The example below illustrates an optimization that spans one day for which the resolution is hourly in the beginning and then gradually decreases to a 6h resolution at the end.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_block_1\nblock_start: 0h (Alternative DateTime: e.g. 2030-01-01T00:00:00)\nblock_end: 1D (Alternative DateTime: e.g. 2030-01-02T00:00:00)\nresolution: [1h 1h 1h 1h 2h 2h 2h 4h 4h 6h]","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Note that, as mentioned above, the block_start and block_end parameters can also be entered as absolute values, i.e. DateTime values.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Rolling-window-optimization-with-single-block","page":"Temporal Framework","title":"Rolling window optimization with single block","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"A model with a single temporal_block can also be optimized in a rolling horizon framework. In this case, the roll_forward parameter has to be defined in the model object. The roll_forward parameter will then determine how much the optimization moves forward with every step, while the size of the temporal block will determine how large a time frame is optimized in each step. To see this more clearly, let's take a look at an example.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Suppose we want to model a horizon of one week, with a rolling window size of one day. The roll_forward parameter will then be a duration value of 1d. If we take the temporal_block parameters block_start and block_end to be the duration values 0h and 1d respectively, the model will optimize each day of the week separately. However, we could also take the block_end parameter to be 2d. Now the model will start by optimizing day 1 and day 2 together, after which it keeps only the values obtained for the first day, and moves forward to optimize the second and third day together.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Again, a variable resolution can be implemented for the rolling window optimization. The sum of the durations must in this case match the size of the optimized window.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Advanced-usage:-multiple-temporal_block-objects","page":"Temporal Framework","title":"Advanced usage: multiple temporal_block objects","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Single-solve-with-multiple-blocks","page":"Temporal Framework","title":"Single solve with multiple blocks","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Disconnected-time-periods","page":"Temporal Framework","title":"Disconnected time periods","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Multiple temporal blocks can be used to optimize disconnected periods. Let's take a look at an example in which two temporal blocks are defined.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_block_1\nblock_start: 0h\nblock_end: 4h\ntemporal_block_2\nblock_start: 12h\nblock_end: 16h","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"This example will lead to an optimization of the first four hours of the model horizon, and also of hour 12 to 16. By defining exactly the same relationships for the two temporal blocks, an optimization of disconnected periods is achieved for exactly the same model components. This leads to the possibility of implementing the widely used representative days method. If desired, it is possible to choose a different temporal resolution for the different temporal_blocks.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"It is worth noting that dynamic variables like node_state and units_on merit special attention when using disconnected time periods. By default, when trying to access variables Variables outside the defined temporal_blocks, SpineOpt.jl assumes such variables exist but allows them to take any values within specified bounds. If fixed initial conditions for the disconnected periods are desired, one needs to use parameters such as fix_node_state or fix_units_on.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Different-regions/commodities-in-different-resolutions","page":"Temporal Framework","title":"Different regions/commodities in different resolutions","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Multiple temporal blocks can also be used to model different regions or different commodities with a different resolution. This is especially useful when there is a certain region or commodity of interest, while other elements are connected to this but require less detail. For this kind of usage, the relationships that are defined for the temporal blocks will be different, as shown in the example below.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"temporal_blocks\ntemporal_block_1\nresolution: 1h\ntemporal_block_2\nresolution: 2h\nnodes\nnode_1\nnode_2\nnode_temporal_block relationships\nnode_1_temporal_block_1\nnode_2_temporal_block_2","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Similarly, the on- and offline status of a unit can be modeled with a lower resolution than the actual output of that unit, by defining the units_on_temporal_block relationship with a different temporal block than the one used for the node_temporal_block relationship (of the node to which the unit is connected).","category":"page"},{"location":"advanced_concepts/temporal_framework/#Rolling-horizon-with-multiple-blocks","page":"Temporal Framework","title":"Rolling horizon with multiple blocks","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/#Rolling-horizon-with-different-window-sizes","page":"Temporal Framework","title":"Rolling horizon with different window sizes","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Similar to what has been discussed above in Different regions/commodities in different resolutions, different commodities or regions can be modeled with a different resolution in the rolling horizon setting. The way to do it is completely analogous. Furthermore, when using the rolling horizon framework, a different window size can be chosen for the different modeled components, by simply using a different block_end parameter. However, using different block_ends e.g. for interconnected regions should be treated with care, as the variables for each region will only be generated for their respective temporal_block, which in most cases will lead to inconsistent linking constraints.","category":"page"},{"location":"advanced_concepts/temporal_framework/#Putting-it-all-together:-rolling-horizon-with-variable-resolution-that-differs-for-different-model-components","page":"Temporal Framework","title":"Putting it all together: rolling horizon with variable resolution that differs for different model components","text":"","category":"section"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"Below is an example of an advanced use case in which a rolling horizon optimization is used, and different model components are optimized with a different resolution. By choosing the relevant parameters in the following way:","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"model\nroll_forward: 4h\ntemporal_blocks\ntemporal_block_A\nresolution: [1h 1h 2h 2h 2h 3h 3h]\nblock_end: 14h\ntemporal_block_B\nresolution: [2h 2h 4h 6h]\nblock_end: 14h\nnodes\nnode_1\nnode_2\nnode_temporal_block relationships\nnode_1_temporal_block_A\nnode_2_temporal_block_B","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"The two model components that are considered have a different resolution, and their own resolution is also varying within the optimization window. Note that in this case the two optimization windows have the same size, but this is not strictly necessary. The image below visualizes the first two window optimizations of this model.","category":"page"},{"location":"advanced_concepts/temporal_framework/","page":"Temporal Framework","title":"Temporal Framework","text":"(Image: temporal structure)","category":"page"},{"location":"concept_reference/fix_binary_gas_connection_flow/","page":"-","title":"-","text":"The binary flow of a gas pipelines for pressure driven gas transfer is enables through the binary variable binary_gas_connection_flow and the big_m constant. To fix this binary variable, i.e. pre-define the direction of gas through the pipelines, the fix_binary_gas_connection_flow parameter can be used.","category":"page"},{"location":"concept_reference/connection_capacity/","page":"-","title":"-","text":"Defines the upper bound on the corresponding connection_flow variable. If the connection is a candidate connection, the effective connection_flow upper bound is the product of the investment variable, connections_invested_available and connection_capacity. If ptdf based dc load flow is enabled, connection_capacity represents the normal rating of a connection (line) while connection_emergency_capacity represents the maximum post contingency flow.","category":"page"},{"location":"concept_reference/fix_units_invested/","page":"-","title":"-","text":"Used primarily to fix the value of the units_invested variable which represents the point-in-time unit investment decision variable and how many candidate units are invested-in in a particular timeslice.","category":"page"},{"location":"concept_reference/fix_units_invested/","page":"-","title":"-","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"The candidate_connections parameter denotes the possibility of investing on a certain connection.","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"The default value of nothing means that the connection can't be invested in, because it's already in operation. An integer value represents the maximum investment possible at any point in time, as a factor of the connection_capacity.","category":"page"},{"location":"concept_reference/candidate_connections/","page":"-","title":"-","text":"In other words, candidate_connections is the upper bound of the connections_invested_available variable.","category":"page"},{"location":"concept_reference/connection__to_node__unit_constraint/","page":"-","title":"-","text":"connection__to_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable from the specified connection to the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__to_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/is_reserve_node/","page":"-","title":"-","text":"By setting the parameter is_reserve_node to true, a node is treated as a reserve node in the model. Units that are linked through a unit__to_node relationship will be able to provide balancing services to the reserve node, but within their technical feasibility. The mathematical formulation holds a chapter on Reserve constraints and the general concept of setting up a model with reserves is described in Reserves.","category":"page"},{"location":"concept_reference/storages_invested_mga/","page":"-","title":"-","text":"The storages_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of storages_invested_mga is set to true, investment decisions in this connection, or group of storages, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/units_on_non_anticipativity_time/","page":"-","title":"-","text":"The units_on_non_anticipativity_time parameter defines the duration, starting from the begining of the optimisation window, where units_on variables need to be fixed to the result of the previous window.","category":"page"},{"location":"concept_reference/units_on_non_anticipativity_time/","page":"-","title":"-","text":"This is intended to model \"slow\" units whose commitment decision needs to be taken in advance, e.g., in \"day-ahead\" mode, and cannot be changed afterwards.","category":"page"},{"location":"mathematical_formulation/objective_function/#Objective-function","page":"Objective","title":"Objective function","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The objective function of SpineOpt expresses the minimization of the total system costs associated with maintaining and operating the considered energy system.","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n min obj = v_unit_investment_costs + v_connection_investment_costs + v_storage_investment_costs\n + v_fixed_om_costs + v_variable_om_costs + v_fuel_costs + v_start_up_costs \n + v_shut_down_costs + v_res_proc_costs \n + v_renewable_curtailment_costs + v_connection_flow_costs + v_taxes +\nv_objective_penalties\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Note that each cost term is reflected here as a separate variable that can be expressed mathematically by the equations below. All cost terms are weighted by the associated scenario and temporal block weights. To enhance readability and avoid writing a product of weights in every cost term, all weights are combined in a single weight parameter p_weight(). As such, the indices associated with each weight parameter indicate which weights are included.","category":"page"},{"location":"mathematical_formulation/objective_function/#Unit-investment-costs","page":"Objective","title":"Unit investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account unit investments in the objective function, the parameter unit_investment_cost can be defined. For all tuples of (unit, scenario, timestep) in the set units_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a unit is invested in during the current optimization window. The total unit investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_unit_investment_costs \n = sum_substack(ust) in units_invested_available_indices\n u in ind(p_unit_investment_cost)\n v_units_invested(u s t) cdot p_unit_investment_cost(ust) cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Connection-investment-costs","page":"Objective","title":"Connection investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account connection investments in the objective function, the parameter connection_investment_cost can be defined. For all tuples of (connection, scenario, timestep) in the set connections_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a connection is invested in during the current optimization window. The total connection investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_connection_investment_costs \n = sum_substack(connst) in connections_invested_available_indices conn in ind(p_connection_investment_cost)\n v_connections_invested(conn s t) cdot p_connection_investment_cost(connst) cdot p_weight(connst) \nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Storage-investment-costs","page":"Objective","title":"Storage investment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To take into account storage investments in the objective function, the parameter storage_investment_cost can be defined. For all tuples of (node, scenario, timestep) in the set storages_invested_available_indices for which this parameter is defined, an investment cost term is added to the objective function if a node storage is invested in during the current optimization window. The total storage investment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_storage_investment_costs \n = sum_substack(nst) in storages_invested_available_indices n in ind(p_storage_investment_cost)\n v_storages_invested(n s t) cdot p_storage_investment_cost(nst) cdot p_weight(nst) \nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Fixed-O-and-M-costs","page":"Objective","title":"Fixed O&M costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Fixed operation and maintenance costs associated with a specific unit can be accounted for by defining the parameters fom_cost and unit_capacity. For all tuples of (unit, {node,node_group}, direction) for which these parameters are defined, and for which tuples (unit, scenario, timestep) exist in the set units_on_indices, a fixed O&M cost term is added to the objective function. Note that, as the units_on_indices are used to retrieve the relevant time slices, the unit of the fom_cost parameter should be given per resolution of the units_on. The total fixed O&M costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_fixed_om_costs \n = \nsum_substack(ust) in units_on_indices\ntext sum_substack(und) in ind(p_unit_capacity) u in ind(p_fom_cost) \n leftp_number_of_units(ust) + sum_substack(ust) in units_invested_available_indices t in t_overlaps_t(t) v_units_invested_available(u s t) right \n cdot p_unit_capacity(undst)\n cdot p_fom_cost(ust)\n p_weight(t) cdot\n p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Variable-O-and-M-costs","page":"Objective","title":"Variable O&M costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Variable operation and maintenance costs associated with a specific unit can be accounted for by defining the parameter (vom_cost). For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a variable O&M cost term is added to the objective function. As the parameter vom_cost is a dynamic parameter, the cost term is multiplied with the duration of each timestep. The total variable O&M costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_variable_om_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_vom_cost)\n v_unit_flow(u n d s t) cdot p_vom_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Fuel-costs","page":"Objective","title":"Fuel costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Fuel costs associated with a specific unit can be accounted for by defining the parameter fuel_cost. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a fuel cost term is added to the objective function. As the parameter fuel_cost is a dynamic parameter, the cost term is multiplied with the duration of each timestep. The total fuel costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_fuel_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_fuel_cost)\n v_unit_flow(u n d s t) cdot p_fuel_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Connection-flow-costs","page":"Objective","title":"Connection flow costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To account for operational costs associated with flows over a specific connection, the connection_flow_cost parameter can be defined. For all tuples of (conn, {node,node_group}, direction, scenario, timestep) in the set connection_flow_indices for which this parameter is defined, a connection flow cost term is added to the objective function. The total connection flow costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_connection_flow_costs \n = sum_substack(connndst) in connection_flow_indices conn in ind(p_connection_flow_cost)\nv_connection_flow (conn n d s t) cdot p_connection_flow_cost(connst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Start-up-costs","page":"Objective","title":"Start up costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Start up costs associated with a specific unit can be included by defining the start_up_cost parameter. For all tuples of (unit, scenario, timestep) in the set units_on_indices for which this parameter is defined, a start up cost term is added to the objective function. The total start up costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_start_up_costs \n = sum_substack(ust) in units_on_indices u in ind(p_start_up_cost)\n v_units_started_up(u s t) cdot p_start_up_cost(ust)cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Shut-down-costs","page":"Objective","title":"Shut down costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Shut down costs associated with a specific unit can be included by defining the shut_down_cost parameter. For all tuples of (unit, scenario, timestep) in the set units_on_indices for which this parameter is defined, a shut down cost term is added to the objective function. The total shut down costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_shut_down_costs \n = sum_substack(ust) in units_on_indices u in ind(p_shut_down_cost)\nv_units_shut_down(ust) cdot p_start_up_cost(ust)cdot p_weight(ust)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Reserve-procurement-costs","page":"Objective","title":"Reserve procurement costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The procurement costs for reserves provided by a specific unit can be accounted for by defining the reserve_procurement_cost parameter. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which this parameter is defined, a reserve procurement cost term is added to the objective function. The total reserve procurement costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_res_proc_costs \n = sum_substack(undst) in unit_flow_indices (und) in ind(p_reserve_procurement_cost)\nv_unit_flow(u n d s t) cdot p_reserve_procurement_cost(undst) cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Renewable-curtailment-costs","page":"Objective","title":"Renewable curtailment costs","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"The curtailment costs of renewable units can be accounted for by defining the parameters curtailment_cost and unit_capacity. For all tuples of (unit, {node,node_group}, direction) for which these parameters are defined, and for which tuples (unit, scenario, timestep_long) exist in the set units_on_indices, and for which tuples (unit, {node,node_group}, direction, scenario, timestep_short) exist in the set unit_flow_indices, a renewable curtailment cost term is added to the objective function. The total renewable curtailment costs can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_renewable_curtailment_costs \n = sum_substack(und) in ind(p_unit_capacity) u in ind(p_curtailment_cost)\nsum_substack(ust_long) in units_on_indices\nsum_substack(unst_short) in unit_flow_indices \n ( v_units_available(u s t_long)cdot p_unit_capacity(undst_short) cdot p_unit_conv_cap_to_flow(undst_short) \n - v_unit_flow(u n d s t_short) ) \n cdot p_curtailment_cost(ust_short) cdot p_weight(nst_short) cdot p_duration(t_short)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Taxes","page":"Objective","title":"Taxes","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"To account for taxes on certain commodity flows, the tax unit flow parameters (i.e., tax_net_unit_flow, tax_out_unit_flow and tax_in_unit_flow) can be defined. For all tuples of (unit, {node,node_group}, direction, scenario, timestep) in the set unit_flow_indices for which these parameters are defined, a tax term is added to the objective function. The total taxes can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_taxes \n = sum_substack(undst) in unit_flow_indices n in ind(p_tax_net_unit_flow) d= to_node\nv_unit_flow(u n d s t)cdot p_tax_net_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\n - sum_substack(undst) in unit_flow_indices n in ind(p_tax_net_unit_flow) d= from_node\nv_unit_flow(u n d s t)cdot p_tax_net_unit_flow(nst)cdot p_weight(nst)cdot p_duration(t)\n + sum_substack(undst) in unit_flow_indices n in ind(p_tax_out_unit_flow) d= from_node\n v_unit_flow(u n d s t)cdot p_tax_out_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\n + sum_substack(undst) in unit_flow_indices n in ind(p_tax_in_unit_flow) d= to_node\n v_unit_flow(u n d s t)cdot p_tax_in_unit_flow(nst)cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"mathematical_formulation/objective_function/#Objective-penalties","page":"Objective","title":"Objective penalties","text":"","category":"section"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"Penalty cost terms associated with the slack variables of a specific constraint can be accounted for by defining a node_slack_penalty parameter. For all tuples of ({node,node_group}, scenario, timestep) in the set node_slack_indices for which this parameter is defined, a penalty term is added to the objective function. The total objective penalties can be expressed as:","category":"page"},{"location":"mathematical_formulation/objective_function/","page":"Objective","title":"Objective","text":"beginaligned\n v_objective_penalties \n = sum_substack(ust) in node_slack_indices\nleftv_node_slack_neg(n s t)-v_node_slack_pos(n s t) rightcdot p_node_slack_penalty(nst)cdot p_weight(nst) cdot p_duration(t)\nendaligned","category":"page"},{"location":"concept_reference/cyclic_condition/","page":"-","title":"-","text":"The cyclic_condition parameter is used to enforce that the storage level at the end of the optimization window is higher or equal to the storage level at the beginning optimization. If the cyclic_condition parameter is set to true for a node__temporal_block relationship, and the has_state parameter of the corrresponding node is set to true, the constraint_cyclic_node_state will be triggered.","category":"page"},{"location":"concept_reference/node__investment_temporal_block/","page":"-","title":"-","text":"node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.","category":"page"},{"location":"concept_reference/node__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"tutorial/reserves/#Reserve-definition-tutorial","page":"Reserve requirements","title":"Reserve definition tutorial","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"This tutorial provides a step-by-step guide to include reserve requirements in a simple energy system with Spine Toolbox for SpineOpt.","category":"page"},{"location":"tutorial/reserves/#Introduction","page":"Reserve requirements","title":"Introduction","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Welcome to our tutorial, where we will walk you through the process of adding a new reserve node in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Reserves refer to the capacity or energy that is kept as a backup to ensure the power system's reliability. This reserve capacity can be brought online automatically or manually in the event of unforeseen system disruptions such as generation failure, transmission line failure, or a sudden increase in demand. Operating reserves are essential to ensure that there is always enough generation capacity available to meet demand, even in the face of unforeseen system disruptions.","category":"page"},{"location":"tutorial/reserves/#Model-assumptions","page":"Reserve requirements","title":"Model assumptions","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"The reserve node has a requirement of 20MW for upwards reserve\nPower plants 'a' and 'b' can both provide reserve to this node","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Guide","page":"Reserve requirements","title":"Guide","text":"","category":"section"},{"location":"tutorial/reserves/#Entering-input-data","page":"Reserve requirements","title":"Entering input data","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.\nLocate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.\nSelect the 'input' Data Store item in the Design View.\nGo to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In this tutorial, you will learn how to add a new reserve node to the Simple System.","category":"page"},{"location":"tutorial/reserves/#Creating-objects","page":"Reserve requirements","title":"Creating objects","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.\nRight click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.\nEnter the names for the new reserve node as seen in the image below, then press Ok. This will create a new object of class node, called upward_reserve_node.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Right click on the node class, and select Add object group from the context menu. The Add object group dialog will pop up. In the Group name field write upward_reserve_group to refer to this group. Then, add as a members of the group the nodes electricity_node and upward_reserve_node, as shown in the image below; then press Ok.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"note: Note\n","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In SpineOpt, groups of nodes allow the user to create constraints that involve variables from its members. Later in this tutorial, the group named upward_reserve_group will help to link the flow variables for electricity production and reserve procurement.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Establishing-relationships","page":"Reserve requirements","title":"Establishing relationships","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.\nRight click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nSelect the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into both the upward_reserve_node and the upward_reserve_group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.\nEnter report1 under report, and variable_om_costs under output. Repeat the same procedure in the second line to add the res_proc_costs under output as seen in the image below; then press Ok. This will write the total vom_cost and procurement reserve cost values in the objective function to the output database as a part of report1.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Specifying-object-parameter-values","page":"Reserve requirements","title":"Specifying object parameter values","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Back to Object tree, expand the node class and select upward_reserve_node.\nLocate the Object parameter table (typically at the top-center).\nIn the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:\ndemand parameter and the Base alternative, and enter the value 20. This will establish that there's a demand of '20' at the reverse node.\nis_reserve_node parameter and the Base alternative, and enter the value True. This will establish that it is a reverse node.\nupward_reserve parameter and the Base alternative, then right-click on the value cell and then, in the context menu, select 'Edit...' and select the option True. This will establish the direction of the reserve is upwards.\nnodal_balance_sense parameter and the Base alternative, and enter the value geq. This will establish that the total reserve procurement must be greater or equal than the reserve demand.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Select upward_reserve_group in the Object tree.\nIn the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that there is no need to create an extra balance between the members of the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/#Specifying-relationship-parameter-values","page":"Reserve requirements","title":"Specifying relationship parameter values","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity to provide reserve for power_plant_a.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"note: Note\n","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"The value is equal to the unit capacity defined for the electricity node. However, the value can be lower if the unit cannot provide reserves with its total capacity.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity to provide reserve for power_plant_b.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_group.\nIn the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:\nunit_capacity parameter and the Base alternative, and enter the value 100. This will set the total capacity for power_plant_a in the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_group.\nIn the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:\nunit_capacity parameter and the Base alternative, and enter the value 200. This will set the total capacity for power_plant_b in the group.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"When you're ready, save/commit all changes to the database.","category":"page"},{"location":"tutorial/reserves/#Executing-the-workflow","page":"Reserve requirements","title":"Executing the workflow","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Go back to Spine Toolbox's main window, and hit the Execute project button (Image: image) from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).\nSelect the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.","category":"page"},{"location":"tutorial/reserves/#Examining-the-results","page":"Reserve requirements","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables or use a pivot table.\nFor the pivot table, press Alt + F for the shortcut to the hamburger menu, and select Pivot -> Index.\nSelect report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.\nUnder alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.\nThe Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"As anticipated, the power_plant_b is supplying the necessary reserve due to its surplus capacity, while power_plant_a is operating at full capacity. Additionally, in this model, we have not allocated a cost for reserve procurement. One way to double-check it is by selecting report__model under Relationship tree and look at the costs the Pivot table, see image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"So, is it possible to assign costs to this reserve procurement in SpineOpt? Yes, it is indeed possible.","category":"page"},{"location":"tutorial/reserves/#Specifying-a-reserve-procurement-cost-value","page":"Reserve requirements","title":"Specifying a reserve procurement cost value","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 5 as seen in the image below. This will set the cost of providing reserve for power_plant_a.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.\nIn the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 35 as seen in the image below. This will set the cost of providing reserve for power_plant_b.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Don't forget to commit the new changes to the database!","category":"page"},{"location":"tutorial/reserves/#Executing-the-worflow-and-examining-the-results-again","page":"Reserve requirements","title":"Executing the worflow and examining the results again","text":"","category":"section"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Go back to Spine Toolbox's main window, and hit again the Execute project button as before.\nSelect the output data store and open the Spine DB editor. You can inspect results as before, which should look like the image below.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"Since the cost of reserve procurement is way cheaper in power_plant_a than in power_plant_b, then the optimal solution is to reduce the production of electricity in power_plant_a to provide reserve with this unit rather than power_plant_b as before. By looking at the total costs, we can see that the reserve procurement costs are no longer zero.","category":"page"},{"location":"tutorial/reserves/","page":"Reserve requirements","title":"Reserve requirements","text":"(Image: image)","category":"page"},{"location":"advanced_concepts/investment_optimization/#Investment-Optimization","page":"Investment Optimization","title":"Investment Optimization","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"SpineOpt offers numerous ways to optimise investment decisions energy system models and in particular, offers a number of methologogies for capturing increased detail in investment models while containing the impact on run time. The basic principles of investments will be discussed first and this will be followed by more advanced approaches.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Key-concepts-for-investments","page":"Investment Optimization","title":"Key concepts for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Decisions These are the investment decisions that SpineOpt currently supports. At a high level, this means that the activity of the entities in question is controlled by an investment decision variable. The current implementation supports investments in :","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit\nconnection\nStorage - Note: while the above investment decisions correspond to an object class (i.e.) an investment in a unit or a connection, Storages are not an object class in themselves and are rather a property of a node. As such, a storage investment controls whether a particular node has a state variable or not. ","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Variable Types In all cases the capacity of the unit or connection or the maximum node state of a node is multiplied by the investment variable which may either be continuous, binary or integer. This is determined, for units, by setting the unit_investment_variable_type parameter accordingly. Similary, for connections and node storages the connection_investment_variable_type and storage_investment_variable_type are specified.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Identiying Investment Candidate Units, Connections and Storages The parameter candidate_units represents the number of units of this type that may be invested in. candidate_units determines the upper bound of the investment variable and setting this to a value greater than 0 identifies the unit as an investment candidate unit in the optimisation. If the unit_investment_variable_type is set to :variable_type_integer, the investment variable can be interpreted as the number of discrete units that may be invested in. However, if unit_investment_variable_type is :variable_type_continuous and the unit_capacity is set to unity, the investment decision variable can then be interpreted as the capacity of the unit rather than the number of units with candidate_units being the maximum capacity that can be invested in. Finally, we can invest in discrete blocks of capacity by setting unit_capacity to the size of the investment capacity blocks and have unit_investment_variable_type set to :variable_type_integer with candidate_units representing the maximum number of capacity blocks that may be invested in. The key points here are:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"The upper bound on the relevant flow variables are determined by the product of the investment variable and the unit_capacity or connection_capacity for connections or node_state_cap for storages.\ncandidate_units sets the upper bound on the investment variable, candidate_connections for connections and candidate_storages for storages\nunit_investment_variable_type determines whether the investment variable is integer, binary or continuous (connection_investment_variable_type for connections and storage_investment_variable_type for storages).","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Investment Costs Investment costs are specified by setting the appropriate *_investment\\_cost parameter. The investment cost for units are specified by setting the unit_investment_cost parameter. This is currently interpreted as the full cost over the investment period for the unit. See the section below on investment temporal structure for setting the investment period. If the investment period is 1 year, then the corresponding unit_investment_cost is the annualised investment cost. For connections and storages, the investment cost parameters are connection_investment_cost and storage_investment_cost, respectively.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Temporal and Stochastic Structure of Investment Decisions SpineOpt's flexible stochastic and temporal structure extend to investments where individual investment decisions can have their own temporal and stochastic structure independent of other investment decisions and other model variables. A global temporal resolution for all investment decisions can be defined by specifying the relationship model__default_investment_temporal_block. If a specific temporal resolution is required for specific investment decisions, then one can specify the following relationships:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit__investment_temporal_block for units,\nconnection__investment_temporal_block for connections, and\nnode__investment_temporal_block for storages. ","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Specifying any of the above relationships will override the corresponding model__default_investment_temporal_block.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Similarly, a global stochastic structure can be defined for all investment decisions by specifying the relationship model__default_investment_stochastic_structure. If a specific stochastic structure is required for specific investment decisions, then one can specifying the following relationships:","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"unit__investment_stochastic_structure for units,\nconnection__investment_stochastic_structure for connections, and\nnode__investment_stochastic_structure for storages.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Specifying any of the above relationships will override the corresponding model__default_investment_stochastic_structure.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Creating-an-Investment-Candidate-Unit-Example","page":"Investment Optimization","title":"Creating an Investment Candidate Unit Example","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"If we have model that is not currently set up for investments and we wish to create an investment candidate unit, we can take the following steps.","category":"page"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Create the unit object with all the relationships and parameters necessary to describe its function.\nEnsure that the number_of_units parameter is set to zero so that the unit is unavailable unless invested in.\nSet the candidate_units parameter for the unit to 1 to specify that a maximum of 1 new unit of this type may be invested in by the model.\nSet the unit_investment_variable_type to unit_investment_variable_type_integer to specify that this is a discrete unit investment decision.\nSpecify the unit_investment_lifetime of the unit to, say, 1 year to specify that this is the minimum amount of time this new unit must be in existence after being invested in.\nSpecify the investment period for this unit's investment decision in one of two ways:\nDefine a default investment period for all investment decisions in the model as follows:\ncreate a temporal_block with the appropriate resolution (say 1 year)\nlink this to your model object by creating the appropriate model__temporal_block relationship\nset it as the default investment temporal block by setting model__default_investment_temporal_block\nOr, define an investment period unique to this investment decision as follows:\ncreating a temporal_block with the appropriate resolution (say 1 year)\nlink this to your model object by creating the appropriate model__temporal_block relationship\nspecify this as the investment period for your unit's investment decision by setting the appropriate unit__investment_temporal_block relationship\nSimilarly to the above, define the stochastic structure for the unit's investment decision by specifying either model__default_investment_stochastic_structure or unit__investment_stochastic_structure\nSpecify your unit's investment cost by setting the unit_investment_cost parameter. Since we have defined the investment period above as 1 year, this is therefore the unit's annualised investment cost.","category":"page"},{"location":"advanced_concepts/investment_optimization/#Model-Reference","page":"Investment Optimization","title":"Model Reference","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/#Variables-for-investments","page":"Investment Optimization","title":"Variables for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Variable Name Indices Description\nunits_invested_available unit, s, t The number of invested in units that are available at a given (s, t)\nunits_invested unit, s, t The point-in-time investment decision corresponding to the number of units invested in at (s,t)\nunits_mothballed unit, s, t \"Instantaneous\" decision variable to mothball a unit\nconnections_invested_available connection, s, t The number of invested-in connectionss that are available at a given (s, t)\nconnections_invested connection, s, t The point-in-time investment decision corresponding to the number of connectionss invested in at (s,t)\nconnections_decommissioned connection, s, t \"Instantaneous\" decision variable to decommission a connection\nstorages_invested_available node, s, t The number of invested-in storages that are available at a given (s, t)\nstorages_invested node, s, t The point-in-time investment decision corresponding to the number of storages invested in at (s,t)\nstorages_decommissioned node, s, t \"instantaneous\" decision variable to decommission a storage","category":"page"},{"location":"advanced_concepts/investment_optimization/#Relationships-for-investments","page":"Investment Optimization","title":"Relationships for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Relationship Name Related Object Class List Description\nmodel__default_investment_temporal_block model, temporal_block Default temporal resolution for investment decisions effective if unit__investmenttemporalblock is not specified\nmodel__default_investment_stochastic_structure model, stochastic_structure Default stochastic structure for investment decisions effective if unit__investmentstochasticstructure is not specified\nunit__investment_temporal_block unit, temporal_block Set temporal resolution of investment decisions - overrides model__defaultinvestmenttemporal_block\nunit__investment_stochastic_structure unit, stochastic_structure Set stochastic structure for investment decisions - overrides model__defaultinvestmentstochastic_structure","category":"page"},{"location":"advanced_concepts/investment_optimization/#Parameters-for-investments","page":"Investment Optimization","title":"Parameters for investments","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Parameter Name Object Class List Description\ncandidate_units unit The number of additional units of this type that can be invested in\nunit_investment_cost unit The total overnight investment cost per candidate unit over the model horizon\nunit_investment_lifetime unit The investment lifetime of the unit - once invested-in, a unit must exist for at least this amount of time\nunit_investment_variable_type unit Whether the units_invested_available variable is continuous, integer or binary\nfix_units_invested unit Fix the value of units_invested\nfix_units_invested_available unit Fix the value of connections_invested_available\ncandidate_connections connection The number of additional connections of this type that can be invested in\nconnection_investment_cost connection The total overnight investment cost per candidate connection over the model horizon\nconnection_investment_lifetime connection The investment lifetime of the connection - once invested-in, a connection must exist for at least this amount of time\nconnection_investment_variable_type connection Whether the connections_invested_available variable is continuous, integer or binary\nfix_connections_invested connection Fix the value of connections_invested\nfix_connections_invested_available connection Fix the value of connection_invested_available\ncandidate_storages node The number of additional storages of this type that can be invested in at node\nstorage_investment_cost node The total overnight investment cost per candidate storage over the model horizon\nstorage_investment_lifetime node The investment lifetime of the storage - once invested-in, a storage must exist for at least this amount of time\nstorage_investment_variable_type node Whether the storages_invested_available variable is continuous, integer or binary\nfix_storages_invested node Fix the value of storages_invested\nfix_storages_invested_available node Fix the value of storages_invested_available","category":"page"},{"location":"advanced_concepts/investment_optimization/#Related-Model-Files","page":"Investment Optimization","title":"Related Model Files","text":"","category":"section"},{"location":"advanced_concepts/investment_optimization/","page":"Investment Optimization","title":"Investment Optimization","text":"Filename Relative Path Description\nconstraintunitsinvested_available.jl \\constraints constrains units_invested_available to be less than candidate_units\nconstraintunitsinvested_transition.jl \\constraints defines the relationship between units_invested_available, units_invested and units_mothballed. Analagous to units_on, units_started and units_shutdown\nconstraintunitlifetime.jl \\constraints once a unit is invested-in, it must remain in existence for at least unit_investment_lifetime - analagous to min_up_time.\nconstraintunitsavailable.jl \\constraints Enforces units_available is the sum of number_of_units and units_invested_available\nconstraintconnectionsinvested_available.jl \\constraints constrains connections_invested_available to be less than candidate_connections\nconstraintconnectionsinvested_transition.jl \\constraints defines the relationship between connections_invested_available, connections_invested and connections_decommissioned. Analagous to units_on, units_started and units_shutdown\nconstraintconnectionlifetime.jl \\constraints once a connection is invested-in, it must remain in existence for at least connection_investment_lifetime - analagous to min_up_time.\nconstraintstoragesinvested_available.jl \\constraints constrains storages_invested_available to be less than candidate_storages\nconstraintstoragesinvested_transition.jl \\constraints defines the relationship between storages_invested_available, storages_invested and storages_decommissioned. Analagous to units_on, units_started and units_shutdown\nconstraintstoragelifetime.jl \\constraints once a storage is invested-in, it must remain in existence for at least storage_investment_lifetime - analagous to min_up_time.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"Given a connection and a node, the power transfer distribution factor (PTDF) is the fraction of the flow injected into the node that will flow on the connection. commodity_ptdf_threshold is the minimum absolute value of the PTDF that is considered meaningful. Any value below this threshold (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"The PTDFs are used to model DC power flow on certain connections. To model DC power flow on a connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/commodity_ptdf_threshold/","page":"-","title":"-","text":"In addition, define a commodity with commodity_physics set to either commodity_physics_ptdf, or commodity_physics_lodf. and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/node__node/","page":"-","title":"-","text":"Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.","category":"page"},{"location":"concept_reference/model_type_list/","page":"-","title":"-","text":"model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"The definition of the ramp_up_limit parameter limits the maximum increase in the unit_flow over a period of time of one duration_unit whenever the unit is online.","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified, the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/ramp_up_limit/","page":"-","title":"-","text":"For a more complete description of how ramping restrictions can be implemented, see Ramping.","category":"page"},{"location":"concept_reference/fix_units_invested_available/","page":"-","title":"-","text":"Used primarily to fix the value of the units_invested_available variable which represents the unit investment decision variable and how many candidate units are invested-in and available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/fix_units_invested_available/","page":"-","title":"-","text":"See also Investment Optimization, candidate_units and unit_investment_variable_type","category":"page"},{"location":"concept_reference/node__unit_constraint/","page":"-","title":"-","text":"node__user_constraint is a two-dimensional relationship between a node and a user_constraint. The relationship specifies that a variable associated only with the node (currently only the node_state) is involved in the constraint. For example, the node_state_coefficient defined on node__user_constraint specifies the coefficient of the node's node_state variable in the specified user_constraint.","category":"page"},{"location":"concept_reference/node__unit_constraint/","page":"-","title":"-","text":"See also user_constraint","category":"page"},{"location":"concept_reference/investment_group/","page":"-","title":"-","text":"The investment_group class represents a group of investments that need to be done together. For example, a storage investment on a node might only make sense if done together with a unit or a connection investment.","category":"page"},{"location":"concept_reference/investment_group/","page":"-","title":"-","text":"To use this functionality, you must first create an investment_group and then specify any number of unit__investment_group, node__investment_group, and/or connection__investment_group relationships between your investment_group and the unit, node, and/or connection investments that you want to be done together. This will ensure that the investment variables of all the entities in the investment_group have the same value.","category":"page"},{"location":"concept_reference/state_coeff/","page":"-","title":"-","text":"The state_coeff parameter acts as a coefficient for the node_state variable in the node injection constraint. Essentially, it tells how the node_state variable should be treated in relation to the commodity flows and demand, and can be used for e.g. scaling or unit conversions. For most use-cases a state_coeff parameter value of 1.0 should suffice, e.g. having a MWh storage connected to MW flows in a model with hour as the basic unit of time.","category":"page"},{"location":"concept_reference/state_coeff/","page":"-","title":"-","text":"Note that in order for the state_coeff parameter to have an impact, the node must first have a node_state variable to begin with, defined using the has_state parameter. By default, the state_coeff is set to zero as a precaution, so that the user always has to set its value explicitly for it to have an impact on the model.","category":"page"},{"location":"concept_reference/commodity/","page":"-","title":"-","text":"Commodities correspond to the type of energy traded. When associated with a node through the node__commodity relationship, a specific form of energy, i.e. commodity, can be associated with a specific location. Furthermore, by linking commodities with units, it is possible to track the flows of a certain commodity and impose limitations on the use of a certain commodity (See also max_cum_in_unit_flow_bound). For the representation of specific commodity physics, related to e.g. the representation of the electric network, designated parameters can be defined to enforce commodity specific behaviour. (See also commodity_physics)","category":"page"},{"location":"concept_reference/demand_coefficient/","page":"-","title":"-","text":"The demand_coefficient is an optional parameter that can be used to include the demand of the a node in a user_constraint via the node__user_constraint relationship. Essentially, demand_coefficient appears as a coefficient for the demand parameter of the connected node in the user constraint.","category":"page"},{"location":"concept_reference/min_voltage_angle/","page":"-","title":"-","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), a lower bound on the pressure can be introduced through the min_voltage_angle parameter, which triggers the generation of the minimum node voltage angle constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Constraints","page":"Constraints","title":"Constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Balance-constraint","page":"Constraints","title":"Balance constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_nodal_balance","page":"Constraints","title":"Nodal balance","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In SpineOpt, node is the place where an energy balance is enforced. As universal aggregators, they are the glue that brings all components of the energy system together. An energy balance is created for each node for all node_stochastic_time_indices, unless the balance_type parameter of the node takes the value balance_type_none or if the node in question is a member of a node group, for which the balance_type is balance_type_group. The parameter nodal_balance_sense defaults to equality, but can be changed to allow overproduction (nodal_balance_sense >=) or underproduction (nodal_balance_sense <=). The energy balance is enforced by the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_injection_(nst)\n+ sum_\n conn\n\nv^connection_flow_(connnto_nodest)\n- sum_\n conn\n\nv^connection_flow_(connnfrom_nodest) \n begincases\nge textif p^nodal_balance_sense = = \n= textif p^nodal_balance_sense = == \nle textif p^nodal_balance_sense = = \nendcases \n 0 \n forall n in node p^balance_type_(n) ne balance_type_none land nexists ng ni n p^balance_type_(ng) = balance_type_group \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also balance_type and nodal_balance_sense.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_injection","page":"Constraints","title":"Node injection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The node injection itself represents all local production and consumption, computed as the sum of all connected unit flows and the nodal demand. If a node corresponds to a storage node, the parameter has_state should be set to true for this node. The node injection is created for each node in the network (unless the node is only used for parameter aggregation purposes, see Introduction to groups of objects).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_injection_(nst) \n = \n left(p^state_coeff_(n s t-1) cdot v^node_state_(n s t-1) - p^state_coeff_(n s t) cdot v^node_state_(n s t)right)\n Delta t \n - p^frac_state_loss_(nst) cdot v^node_state_(n s t) \n + sum_n p^diff_coeff_(nnst) cdot v^node_state_(n s t)\n- sum_n p^diff_coeff_(nnst) cdot v^node_state_(n s t) \n + sum_\n u\n\nv^unit_flow_(unto_nodest)\n- sum_\n u\n\nv^unit_flow_(unfrom_nodest)\n - left(p^demand_(nst) + sum_ng ni n p^fractional_demand_(nst) cdot p^demand_(ngst)right) \n + v^node_slack_pos_(nst) - v^node_slack_neg_(nst) \n forall n in node p^has_state_(n)\n forall (s t)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also state_coeff, frac_state_loss, diff_coeff, node__node, unit__from_node, unit__to_node, demand, fractional_demand, has_state.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_state_capacity","page":"Constraints","title":"Node state capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To limit the storage content, the v_node_state variable needs be constrained by the following equation:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^node_state_(n s t) leq p^node_state_cap_(n s t) quad forall n in node p^has_state_(n) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The discharging and charging behavior of storage nodes can be described through unit(s), representing the link between the storage node and the supply node. Note that the dis-/charging efficiencies and capacities are properties of these units. See the capacity constraint and the unit flow ratio constraints.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also node_state_cap, has_state.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_cyclic_node_state","page":"Constraints","title":"Cyclic condition on node state variable","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To ensure that the node state at the end of the optimization is at least the same value as the initial value at the beginning of the optimization (or higher), the cyclic node state constraint can be used by setting the cyclic_condition of a node__temporal_block to true. This triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^node_state_(n s start(tb)) geq v^node_state_(n s end(tb))\nqquad forall (ntb) in indices(p^cyclic_condition) p^cyclic_condition_(ntb)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also cyclic_condition.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Unit-operation","page":"Constraints","title":"Unit operation","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In the following, the operational constraints on the variables associated with units will be elaborated on. The static constraints, in contrast to the dynamic constraints, are addressing constraints without sequential time-coupling. It should however be noted that static constraints can still perform temporal aggregation.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#static-constraints-unit","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The fundamental static constraints for units within SpineOpt relate to the relationships between commodity flows from and to units and to limits on the unit flow capacity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_unit_flow","page":"Constraints","title":"Conversion constraint / limiting flow shares inprocess / relationship in process","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"A unit can have different commodity flows associated with it. The most simple relationship between these flows is a linear relationship between input and/or output nodes/node groups. SpineOpt holds constraints for each combination of flows and also for the type of relationship, i.e. whether it is a maximum, minimum or fixed ratio between commodity flows. Note that node groups can be used in order to aggregate flows, i.e. to give a ratio between a combination of units flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#ratio_unit_flow","page":"Constraints","title":"Ratios between flows of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"By specifying the parameters fix_ratio_out_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_in_in_unit_flow, and/or fix_ratio_out_out_unit_flow, a fix ratio can be set between, respectively, outgoing and incoming flows from and to a unit, incoming and outgoing flows to and from a unit, two incoming flows to a unit, and/or two outgoing flows from a unit.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similary, a minimum ratio between flows can be set by specifying min_ratio_out_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_in_in_unit_flow, and/or min_ratio_out_out_unit_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Finally, a maximum ratio can be set by specifying max_ratio_out_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_in_in_unit_flow, and/or max_ratio_out_out_unit_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For example, whenever there is only a single input node and a single output node, fix_ratio_out_in_unit_flow relates to the notion of efficiency. Also, fix_ratio_in_out_unit_flow can for instance be used to relate emissions to input primary fuel flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The constraint below is written for fix_ratio_out_in_unit_flow, but equivalent formulations exist for the other 11 cases described above.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_out v^unit_flow_(unfrom_nodest) \n = \n p^fix_ratio_out_in_unit_flow_(u ng_out ng_inst)\ncdot sum_n in ng_in v^unit_flow_(unto_nodest) \n + p^fix_units_on_coefficient_out_in_(ung_outng_inst) cdot v^units_on_(ust) \n forall (u ng_out ng_in) in indices(p^fix_ratio_out_in_unit_flow) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nIf any of the above mentioned ratio parameters is specified for a node group, then the ratio is enforced over the sum of flows from or to that group. In this case, there remains a degree of freedom regarding the composition of flows within the group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fix_ratio_out_in_unit_flow, fix_units_on_coefficient_out_in.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_flow_capacity","page":"Constraints","title":"Bounds on the unit capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In a multi-commodity setting, there can be different commodities entering/leaving a certain technology/unit. These can be energy-related commodities (e.g., electricity, natural gas, etc.), emissions, or other commodities (e.g., water, steel). The unit_capacity must be specified for at least one unit__to_node or unit__from_node relationship, in order to trigger a constraint on the maximum commodity flows to this location in each time step. When desirable, the capacity can be specified for a group of nodes (e.g. combined capacity for multiple products).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\n v^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right\n + sum_\n n in ng\n\n v^unit_flow_(undst) cdot left\n p^is_reserve_node_(n) land p^upward_reserve_(n) land neg p^is_non_spinning_(n) \n right\n le \n p^unit_capacity_(ungdst) cdot p^unit_availability_factor_(ust) cdot p^unit_conv_cap_to_flow_(ungdst) \n cdot ( \n qquad v^units_on_(ust) \n qquad - left(1 - p^shut_down_limit_(ungdst)right)\ncdot left( v^units_shut_down_(ust+1)\n+ sum_\n n in ng\n v^nonspin_units_shut_down_(unst) right) \n qquad - left(1 - p^start_up_limit_(ungdst)right) cdot v^units_started_up_(ust) \n ) \n forall (ungd) in indices(p^unit_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe conversion factor unit_conv_cap_to_flow has a default value of 1, but can be adjusted in case the unit of measurement for the capacity is different to the unit flows unit of measurement.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for time-slices whose duration is greater than the minimum up time of the unit. This ensures that the unit is not online for exactly one time-slice, which might result in an infeasibility if this formulation was used. Instead, for time-slices whose duration is lower or equal than the minimum up time of the unit there is a similar formulation, but the details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for flows going from a unit to a node (i.e., output flows). For flows going from a node to a unit (i.e., input flows) the direction of the reserves is switched (downwards becomes upwards, non-spinning units shut-down becomes non-spinning units started-up). The details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, upward_reserve, is_non_spinning, unit_capacity, unit_availability_factor, unit_conv_cap_to_flow, start_up_limit, shut_down_limit.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_minimum_operating_point","page":"Constraints","title":"Constraint on minimum operating point","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The minimum operating point of a unit is based on the unit_flows of input or output nodes/node groups.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst) cdot leftneg p^is_reserve_node_(n)right\n- sum_\n n in ng\n\nv^unit_flow_(undst) cdot leftp^is_reserve_node_(n) land p^downward_reserve_(n)right \n ge p^minimum_operating_point_(ungdst) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) \n cdot left( v^units_on_(ust)\n- sum_\n n in ng\n v^nonspin_units_shut_down_(unst) right) \n forall (ungd) in indices(p^minimum_operating_point) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe above formulation is valid for flows going from a unit to a node (i.e., output flows). For flows going from a node to a unit (i.e., input flows) the direction of the reserves is switched (downwards becomes upwards, non-spinning units shut-down becomes non-spinning units started-up). The details are omitted for brevity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, downward_reserve, is_non_spinning, minimum_operating_point, unit_capacity, unit_conv_cap_to_flow","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Dynamic-constraints","page":"Constraints","title":"Dynamic constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Commitment-constraints","page":"Constraints","title":"Commitment constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For modeling certain technologies/units, it is important to not only have unit_flow variables of different commodities, but also model the online (\"commitment\") status of the unit/technology at every time step. Therefore, an additional variable units_on is introduced. This variable represents the number of online units of that technology (for a normal unit commitment model, this variable might be a binary, for investment planning purposes, this might also be an integer or even a continuous variable). To define the type of a commitment variable, see online_variable_type. Commitment variables will be introduced by the following constraints (with corresponding parameters):","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"constraint on units_on\nconstraint on units_available\nconstraint on the unit state transition\nconstraint on minimum down time\nconstraint on minimum up time\nconstraint on ramp rates\nconstraint on reserve provision","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_available","page":"Constraints","title":"Bound on available units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The aggregated available units are constrained by the parameter number_of_units and the variable number of invested units units_invested_available:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_available_(ust) leq p^number_of_units_(ust) + v^units_invested_available_(ust) \n forall u in unit \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also number_of_units.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_on","page":"Constraints","title":"Bound on online units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of online units needs to be restricted to the aggregated available units:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"v^units_on_(ust) leq v^units_available_(ust) quad forall u in unit forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The investment formulation is described in chapter Investments.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_state_transition","page":"Constraints","title":"Unit state transition","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The units on status is constrained by shutting down and starting up actions. This transition is defined as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_on_(ust) - v^units_started_up_(ust) + v^units_shut_down_(ust) = v^units_on_(ust-1) \n forall u in unit \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_down_time","page":"Constraints","title":"Minimum down time","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to the minimum up time constraint, a minimum time that a unit needs to remain offline after a shut down can be imposed by defining the min_down_time parameter. This will trigger the generation of the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n p^number_of_units_(ust) + v^units_invested_available_(ust) - v^units_on_(ust) \n - sum_n v^nonspin_units_started_up_(unst) \n geq\nsum_t=t-p^min_down_time_(ust) + 1^t\nv^units_shut_down_(ust) \n forall u in indices(p^min_down_time)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also number_of_units, min_down_time.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_up_time","page":"Constraints","title":"Minimum up time","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to the minimum down time constraint, a minimum time that a unit needs to remain online after a start up can be imposed by defining the min_up_time parameter. This will trigger the generation of the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_on_(ust) - sum_n v^nonspin_units_shut_down_(unst) \n geq\nsum_t=t-p^min_up_time_(ust) +1 ^t\nv^units_started_up_(ust) \n forall u in indices(p^min_up_time)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_up_time","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Ramping-constraints","page":"Constraints","title":"Ramping constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To include ramping and reserve constraints, it is a pre requisite that minimum operating points and capacity constraints are enforced as described.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For dispatchable units, additional ramping constraints can be introduced. For setting up ramping characteristics of units see Ramping.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ramp_up","page":"Constraints","title":"Ramp up limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the increase of unit_flow over a time period of one duration_unit according to the start_up_limit and ramp_up_limit parameter values.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right \n - sum_\n n in ng\n\nv^unit_flow_(undst-1) cdot left neg p^is_reserve_node_(n) right \n + sum_\n n in ng\n\nv^unit_flow_(undst) cdot left p^is_reserve_node_(n) land p^upward_reserve_(n) right \n le ( \n qquad left(p^start_up_limit_(ungdst) - p^minimum_operating_point_(ungdst)\n- p^ramp_up_limit_(ungdst)right) cdot v^units_started_up_(ust) \n qquad + left(p^minimum_operating_point_(ungdst) + p^ramp_up_limit_(ungdst)right)\ncdot v^units_on_(ust) \n qquad - p^minimum_operating_point_(ungdst) cdot v^units_on_(ust-1) \n ) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) cdot Delta t \n forall (ungd) in indices(p^ramp_up_limit) cup indices(p^start_up_limit) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, upward_reserve, unit_capacity, unit_conv_cap_to_flow, ramp_up_limit, start_up_limit, minimum_operating_point.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ramp_down","page":"Constraints","title":"Ramp down limit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the decrease of unit_flow over a time period of one duration_unit according to the shut_down_limit and ramp_down_limit parameter values.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\n n in ng\n\nv^unit_flow_(undst-1) cdot left neg p^is_reserve_node_(n) right \n - sum_\n n in ng\n\nv^unit_flow_(undst) cdot left neg p^is_reserve_node_(n) right \n + sum_\n n in ng\n\nv^unit_flow_(undst) cdot left p^is_reserve_node_(n) land p^downward_reserve_(n) right \n le ( \n qquad left(p^shut_down_limit_(ungdst) - p^minimum_operating_point_(ungdst) - p^ramp_down_limit_(ungdst)right) cdot v^units_shut_down_(ust) \n qquad + left(p^minimum_operating_point_(ungdst) + p^ramp_down_limit_(ungdst)right) cdot v^units_on_(ust-1) \n qquad - p^minimum_operating_point_(ungdst) cdot v^units_on_(ust) \n ) cdot p^unit_capacity_(ungdst) cdot p^unit_conv_cap_to_flow_(ungdst) cdot Delta t \n forall (ungd) in indices(p^ramp_down_limit) cup indices(p^shut_down_limit) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also is_reserve_node, downward_reserve, unit_capacity, unit_conv_cap_to_flow, ramp_down_limit, shut_down_limit, minimum_operating_point.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Reserve-constraints","page":"Constraints","title":"Reserve constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_res_minimum_node_state","page":"Constraints","title":"Constraint on minimum node state for reserve provision","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-11-20: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Operating-segments","page":"Constraints","title":"Operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_operating_point_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Limit the maximum number of each activated segment unit_flow_op_active cannot be higher than the number of online units. This constraint is activated only when parameter ordered_unit_flow_op is set true.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_active_(undopst) leq v^units_on_(ust) \n forall (und) in indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 1 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_operating_point_rank","page":"Constraints","title":"Rank operating segments as per the index of operating points","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Rank operating segments by enforcing that the variable unit_flow_op_active of operating point i can only be active if previous operating point i-1 is also active. The first segment does not need this constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_active_(undopst) leq v^unit_flow_op_active_(undop-1st) \n forall (und) in indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 2 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_bounds","page":"Constraints","title":"Operating segments of units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"If the segments of a unit_flow, i.e. unit_flow_op is not ordered according to the rank of the unit_flow's operating_points (parameter ordered_unit_flow_op is false), the operating segment variable unit_flow_op is only bounded by the difference between successive operating_points adjusted for available capacity. If the order is enforced on the segments (parameter ordered_unit_flow_op is true), unit_flow_op can only be active if the segment is active (variable unit_flow_op_active is true) besides being bounded by the segment capacity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op_(u n d op s t) \n leq p^unit_capacity_(u n d s t) cdot p^unit_conv_cap_to_flow_(u n d s t) cdot p^unit_availability_factor_(u s t) \n cdot left( p^operating_points_(u n d op s t)\n- begincases \n p^operating_points_(u n op-1 s t) textif op 1\n 0 textotherwise\nendcases right) \n cdot begincases\n v^unit_flow_op_active_(undopst) textif p^ordered_unit_flow_op_(ust) \n v^units_on_(ust) textotherwise\nendcases \n forall (und) in indices(p^unit_capacity) cup indices(p^operating_points) \n forall op in 1 ldots leftp^operating_points_(und)right \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_capacity, unit_conv_cap_to_flow, unit_availability_factor, operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_rank","page":"Constraints","title":"Bounding operating segments to use up its own capacity for activating the next segment","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Enforce the operating point flow variable unit_flow_op at operating point i to use its full capacity if the subsequent operating point i+1 is active if parameter ordered_unit_flow_op is set true. The last segment does not need this constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_op(u n d op s t) \n geq p^unit_capacity_(u n d s t) cdot p^unit_conv_cap_to_flow_(u n d s t) \n cdot left(p^operating_points_(u n op s t) - begincases \n p^operating_points_(u n op-1 s t) textif op 1 \n 0 textotherwise \nendcases right) \n cdot v^unit_flow_op_active_(u n d op+1 s t) \n forall (und) in indices(p^unit_capacity) cup indices(p^operating_points) p^ordered_unit_flow_op_(und) \n forall op in 1 ldots leftp^operating_points_(und)right - 1 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_capacity, unit_conv_cap_to_flow, operating_points, ordered_unit_flow_op.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#unit_flow_op_sum","page":"Constraints","title":"Bounding unit flows by summing over operating segments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"unit_flow is constrained to be the sum of all operating segment variables, unit_flow_op","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_(u n d s t) = sum_op=1^leftp^operating_points_(und)right v^unit_flow_op_(u n d op s t) \n forall (und) in indices(p^operating_points) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also operating_points.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_pw_heat_rate","page":"Constraints","title":"Unit piecewise incremental heat rate","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Implements a standard piecewise linear heat-rate function where unit_flow from a (input fuel consumption) node is equal to the sum over operating point segments of unit_flow_op to a (output electricity node) node times the corresponding incremental_heat_rate.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^unit_flow_(u n_in d s t) \n = sum_op=1^leftp^operating_points_(und)right p^unit_incremental_heat_rate_(u n_in n_out op s t)\ncdot v^unit_flow_op_(u n_out d op s t) \n + p^unit_idle_heat_rate_(u n_in n_out s t) cdot v^units_on_(u s t) \n + p^unit_start_flow_(u n_in n_out s t) cdot v^units_started_up_(u s t) \n forall (un_inn_out) in indices(p^unit_incremental_heat_rate) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also unit_incremental_heat_rate, unit_idle_heat_rate, unit_start_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Bounds-on-commodity-flows","page":"Constraints","title":"Bounds on commodity flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_total_cumulated_unit_flow","page":"Constraints","title":"Bound on cumulated unit flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To impose a limit on the cumulative amount of certain commodity flows, a cumulative bound can be set by defining one of the following parameters:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"max_total_cumulated_unit_flow_from_node\nmin_total_cumulated_unit_flow_from_node\nmax_total_cumulated_unit_flow_to_node\nmin_total_cumulated_unit_flow_to_node","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"A maximum cumulated flow restriction can for example be used to limit emissions or consumption of a certain commodity.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_u in ug n in ng v^unit_flow_(undst) leq p^max_total_cumulated_unit_flow_from_node_(ugngd) \n forall (ugngd) in indices(p^max_total_cumulated_unit_flow_from_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) geq p^min_total_cumulated_unit_flow_from_node_(ugngd) \n forall (ugngd) in indices(p^min_total_cumulated_unit_flow_from_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) leq p^max_total_cumulated_unit_flow_to_node_(ugngd) \n forall (ugngd) in indices(p^max_total_cumulated_unit_flow_to_node) forall s \n sum_u in ug n in ng v^unit_flow_(undst) geq p^min_total_cumulated_unit_flow_to_node_(ugngd) \n forall (ugngd) in indices(p^min_total_cumulated_unit_flow_to_node) forall s \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Network-constraints","page":"Constraints","title":"Network constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#static-constraints-connection","page":"Constraints","title":"Static constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_capacity","page":"Constraints","title":"Capacity constraint on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In a multi-commodity setting, there can be different commodities entering/leaving a certain connection. These can be energy-related commodities (e.g., electricity, natural gas, etc.), emissions, or other commodities (e.g., water, steel). The connection_capacity should be specified for at least one connection__to_node or connection__from_node relationship, in order to trigger a constraint on the maximum commodity flows to this location in each time step. When desirable, the capacity can be specified for a group of nodes (e.g. combined capacity for multiple products).","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\nn in ng\n v^connection_flow_(connndst)\n- sum_\nn in ng\n v^connection_flow_(connnreverse(d)st) \n = p^connection_capacity_(connngdst) cdot p^connection_availability_factor_(connst) cdot p^connection_conv_cap_to_flow_(connngdst) \n cdot begincases \n v^connections_invested_available_(connst) textif p^candidate_connections_(connst) geq 1 \n 1 textotherwise \nendcases \n forall (connngd) in indices(p^connection_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_capacity, connection_availability_factor, connection_conv_cap_to_flow, candidate_connections","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nFor situations where the same connection handles flows to multiple nodes with different temporal resolutions, the constraint is only generated for the lowest resolution, and only the average of the higher resolution flow is constrained. In other words, what gets constrained is the \"average power\" (e.g. MWh/h) rather than the \"instantaneous power\" (e.g. MW). If instantaneous power needs to be constrained as well, then connection_capacity needs to be specified separately for each node served by the connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe conversion factor connection_conv_cap_to_flow has a default value of 1, but can be adjusted in case the unit of measurement for the capacity is different to the connection flows unit of measurement.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_out_in_connection_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"By defining the parameters fix_ratio_out_in_connection_flow, max_ratio_out_in_connection_flow or min_ratio_out_in_connection_flow, a ratio can be set between outgoing and incoming flows from and to a connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The constraint below is written for fix_ratio_out_in_connection_flow, but equivalent formulations exist for the other two cases.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_out v^connection_flow_(connnfrom_nodest) \n = \n p^fix_ratio_out_in_connection_flow_(conn ng_out ng_inst)\ncdot sum_n in ng_in v^connection_flow_(connnto_nodest) \n forall (conn ng_out ng_in) in indices(p^fix_ratio_out_in_connection_flow) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nIf any of the above mentioned ratio parameters is specified for a node group, then the ratio is enforced over the sum of flows from or to that group. In this case, there remains a degree of freedom regarding the composition of flows within the group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fix_ratio_out_in_connection_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Specific-network-representation","page":"Constraints","title":"Specific network representation","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In the following, the different specific network representations are introduced. While the Static constraints find application in any of the different networks, the following equations are specific to the discussed use cases. Currently, SpineOpt incorporated equations for pressure driven gas networks, nodal lossless DC power flows and PTDF based lossless DC power flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#pressure-driven-gas-transfer-math","page":"Constraints","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For gas pipelines it can be relevant a pressure driven gas transfer can be modelled, i.e. to account for linepack flexibility. Generally speaking, the main challenges related to pressure driven gas transfers are the non-convexities associated with the Weymouth equation. In SpineOpt, a convexified MILP representation has been implemented, which as been presented in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. The approximation approach is based on the Taylor series expansion around fixed pressure points.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In addition to the already known variables, such as connection_flow and node_state, the start and end points of a gas pipeline connection are associated with the variable node_pressure. The variable is triggered by the has_pressure parameter. For more details on how to set up a gas pipeline, see also the advanced concept section on pressure driven gas transfer.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_max_node_pressure","page":"Constraints","title":"Maximum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose an upper limit on the maximum pressure at a node the parameter max_node_pressure can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sum_n in ng v^node_pressure_(nst) leq p^max_node_pressure_(ngst)\nquad forall (ng) in indices(p^max_node_pressure) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter max_node_pressure can also be defined on a node group, in order to impose an upper limit on the aggregated node_pressure within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_node_pressure.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_node_pressure","page":"Constraints","title":"Minimum node pressure","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose a lower limit on the pressure at a node the parameter min_node_pressure can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sum_n in ng v^node_pressure_(nst) geq p^min_node_pressure_(ngst)\nquad forall (ng) in indices(p^min_node_pressure) forall (st)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter min_node_pressure can also be defined on a node group, in order to impose a lower limit on the aggregated node_pressure within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_node_pressure.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_compression_factor","page":"Constraints","title":"Constraint on the pressure ratio between two nodes","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"If a compression station is located in between two nodes, the connection is considered to be active and a compression ratio between the two nodes can be imposed. The parameter compression_factor needs to be defined on a connection__node__node relationship, where the first node corresponds the origin node, before the compression, while the second node corresponds to the destination node, after compression. The existence of this parameter will trigger the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng2 v^node_pressure_(nst) leq p^compression_factor_(connng1ng2st) cdot sum_n in ng1 v^node_pressure_(nst) \n forall (connng1ng2) in indices(p^compression_factor) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also compression_factor.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_fixed_node_pressure_point","page":"Constraints","title":"Outer approximation through fixed pressure points","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The Weymouth equation relates the average flows through a connection to the difference between the adjacent squared node pressures.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\n left(\n v^connection_flow_(conn n_origfrom_nodest)\n + v^connection_flow_(conn n_destto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_destfrom_nodest)\n + v^connection_flow_(conn n_origto_nodest)\n right)\nright)\n\n cdot left\n left(\n v^connection_flow_(conn n_origfrom_nodest)\n + v^connection_flow_(conn n_destto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_destfrom_nodest)\n + v^connection_flow_(conn n_origto_nodest)\n right)\nright\n\n = 4 cdot K_(conn) cdot left(\n left(v^node_pressure_(n_origst)right)^2 - left(v^node_pressure_(n_destst)right)^2\nright) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where K corresponds to the natural gas flow constant.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The above can be rewritten as","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\n- left(v^connection_flow_(conn n_destfrom_nodest) + v^connection_flow_(conn n_origto_nodest)right)\nright)\n = 2 cdot sqrt\n K_(conn)\n cdot left(\n left(v^node_pressure_(n_origst)right)^2 - left(v^node_pressure_(n_destst)right)^2\n right)\n \n textif left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\nright) 0\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"and","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(\n left(\n v^connection_flow_(conn n_destfrom_nodest) + v^connection_flow_(conn n_origto_nodest)\n right)\n - left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\n right)\nright) \n = 2 cdot sqrt\n K_(conn) cdot left(\n left(v^node_pressure_(n_destst)right)^2 - left(v^node_pressure_(n_origst)right)^2\n right)\n \n textif left(\n v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)\nright) 0\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The cone described by the Weymouth equation can be outer approximated by a number of tangent planes, using a set of fixed pressure points, as illustrated in Schwele - Integration of Electricity, Natural Gas and Heat Systems With Market-based Coordination. The big M method is used to replace the sign function.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The linearized version of the Weymouth equation implemented in SpineOpt is given as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n \nleft\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\nmiddle2 \nright\n\n leq p^fixed_pressure_constant_1_(connn_orign_destjst) cdot v^node_pressure_(n_origst) \n - p^fixed_pressure_constant_0_(connn_orign_destjst) cdot v^node_pressure_(n_destst) \n + p^big_m cdot left(1 - v^binary_gas_connection_flow_(conn n_dest to_node s t)right) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall j in left1 ldots left p^fixed_pressure_constant_1_(conn n_orig n_dest) right right\np^fixed_pressure_constant_1_(conn n_orig n_dest j) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 should be defined. For each considered fixed pressure point, they can be calculated as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n p^fixed_pressure_constant_1_(connn_orign_destj) =\n left K_(conn) cdot p^fixed_pressure_(n_origj) middle sqrt\n left(p^fixed_pressure_(n_origj)right)^2 - left(p^fixed_pressure_(n_destj)right)^2\n right \n p^fixed_pressure_constant_0_(connn_orign_destj) =\n left K_(conn) cdot p^fixed_pressure_(n_destj) middle sqrt\n left(p^fixed_pressure_(n_origj)right)^2 - left(p^fixed_pressure_(n_destj)right)^2\n right \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where p^fixed_pressure_(nj) is the fix pressure for node n and point j.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The big_m parameter combined with the variable binary_gas_connection_flow together with the equations on unitary gas flow and on the maximum gas flow ensure that the bound on the average flow through the fixed pressure points becomes active, if the flow is in a positive direction for the observed set of connection, node1 and node2.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also fixed_pressure_constant_1, fixed_pressure_constant_0, big_m.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_unitary_gas_flow","page":"Constraints","title":"Enforcing unidirectional flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The flow through a connection can only be in one direction at at time. Whether a flow is active in a certain direction is indicated by the binary_gas_connection_flow variable, which takes a value of 1 if the direction of flow is positive. To ensure that the binary_gas_connection_flow in the opposite direction then takes the value 0, the following constraint is enforced:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^binary_gas_connection_flow_(conn n_orig to_node s t) \n = 1 - v^binary_gas_connection_flow_(conn n_dest to_node s t) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_gas_capacity","page":"Constraints","title":"Gas connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To enforce that the averge flow of a connection is only in one direction, the flow in the opposite direction is forced to be 0 by the following equation. For the connection flow in the direction of flow the parameter big_m should be chosen large enough not to become binding.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n \nleft\nleft(v^connection_flow_(conn n_origfrom_nodest) + v^connection_flow_(conn n_destto_nodest)right)\nmiddle2 \nright\n\n = p^big_m cdot v^binary_gas_connection_flow_(conn n_dest to_node s t) \n forall (conn n_orig n_dest) in indices(p^fixed_pressure_constant_1) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also p^{fixed_pressure_constant_1}, big_m.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storage_line_pack","page":"Constraints","title":"Linepack storage flexibility","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to account for linepack flexibility, i.e. storage capability of a connection, the linepack storage is linked to the average pressure of the adjacent nodes by the following equation, triggered by the parameter connection_linepack_constant:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^node_state_(n_storst) = left(\n p^connection_linepack_constant_(connn_storng) middle 2\nright) cdot sum_n in ng v^node_pressure_(nst) \n forall (conn n_stor ng) in indices(p^connection_linepack_constant) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"note: Note\nThe parameter connection_linepack_constant should be defined on a connection__node__noderelationship, where the first node corresponds to the linepack storage node, whereas the second node corresponds to the node group of both start and end nodes of the pipeline.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_linepack_constant","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#nodal-lossless-DC","page":"Constraints","title":"Node-based lossless DC power flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For the implementation of the nodebased loss DC powerflow model, a new variable node_voltage_angle is introduced. See also has_voltage_angle. For further explanation on setting up a database for nodal lossless DC power flow, see the advanced concept chapter on Lossless nodal DC power flows.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_max_node_voltage_angle","page":"Constraints","title":"Maximum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose an upper limit on the maximum voltage angle at a node the parameter max_voltage_angle can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng v^node_voltage_angle_(nst) geq p^max_voltage_angle_(ngst) \n forall ng in indices(p^max_voltage_angle) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter max_voltage_angle can also be defined on a node group, in order to impose an upper limit on the aggregated node_voltage_angle within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also max_voltage_angle.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_min_node_voltage_angle","page":"Constraints","title":"Minimum node voltage angle","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"In order to impose a lower limit on the voltage angle at a node the parameter min_voltage_angle can be specified which triggers the following constraint:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng v^node_voltage_angle_(nst) leq p^min_voltage_angle_(ngst) \n forall ng in indices(p^min_voltage_angle) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"As indicated in the equation, the parameter min_voltage_angle can also be defined on a node group, in order to impose a lower limit on the aggregated node_voltage_angle within one node group.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also min_voltage_angle.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_node_voltage_angle","page":"Constraints","title":"Voltage angle to connection flows","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"To link the flow over a connection to the voltage angles of the adjacent nodes, the following constraint is imposed. Note that this constraint is only generated if the parameter connection_reactance is defined for a connection object and if a fix_ratio_out_in_connection_flow is defined for a connection__node__node relationship involving that connection.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_n in ng_from v^connection_flow_(connnfrom_nodest)\n- sum_n in ng_to v^connection_flow_(connnfrom_nodest)\n = \n left(p^connection_reactance_base_(connst) middle p^connection_reactance_(connst)right) \n cdot left(sum_n in ng_from v^node_voltage_angle_(nst) - sum_n in ng_to v^node_voltage_angle_(nst) right)\n forall (conn ng_to ng_from) in indices(p^fix_ratio_out_in_connection_flow)\n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"See also connection_reactance, connection_reactance_base, fix_ratio_out_in_connection_flow.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#PTDF-lossless-DC","page":"Constraints","title":"PTDF based DC lossless powerflow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_intact_flow_ptdf","page":"Constraints","title":"Connection intact flow PTDF","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The power transfer distribution factors are a property of the network reactances. p^ptdf_(c n) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of p^ptdf_(c n) multiplied by the net injection at that node. connection_intact_flow represents the flow on each line of the network with all candidate connections with PTDF-based flow present in the network.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_intact_flow_(c n_to to_node s t)\n- v^connection_intact_flow_(c n_to from_node s t) \n = sum_n_inj p^ptdf_(c n_inj t) cdot v^node_injection_(n_inj s t)\ncdot leftp^node_opf_type_(n_inj) neq node_opf_type_reference right\n\n forall c in connection p^is_monitored_(c) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p vcentcolon = begincases\n1 textif p text is true\n0 textotherwise\nendcases","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_lodf","page":"Constraints","title":"N-1 post contingency connection flow limits","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The N-1 security constraint for the post-contingency flow on monitored connection, c_mon, upon the outage of a contingency connection, c_cont, is formed using line outage distribution factors (LODF). p^lodf_(c_con c_mon) represents the fraction of the pre-contingency flow on connection c_cont that will flow on c_mon if the former is disconnected. If connection c_cont is disconnected, the post-contingency flow on the monitored connection connection c_mon is the pre-contingency connection_flow on c_mon plus the LODF times the pre-contingency connection_flow on c_cont. This post-contingency flow should be less than the connection_emergency_capacity of c_mon.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c_mon n_mon_to to_node s t)\n- v^connection_flow_(c_mon n_mon_to from_node s t) \n + p^lodf_(c_cont c_mon) cdot left( \nv^connection_flow_(c_cont n_cont_to to_node s t)\n- v^connection_flow_(c_cont n_cont_to from_node s t)\nright) \n leq min left(\n p^connection_emergency_capacity_(c_mon n_cont_to to_node s t)\n p^connection_emergency_capacity_(c_mon n_cont_to from_nodes t)\nright) \n forall (c_mon c_cont) in connection times connection \np^is_monitored_(c_mon) land p^is_contingency_(c_cont) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments","page":"Constraints","title":"Investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-units","page":"Constraints","title":"Investments in units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_unit_lifetime","page":"Constraints","title":"Economic lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-03: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-unit","page":"Constraints","title":"Technical lifetime of a unit","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_invested_available","page":"Constraints","title":"Available Investment Units","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in units at any point in time is less than the number of investment candidate units.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_invested_available_(ust) p^candidate_units_(u) \n forall u in unit p^candidate_units_(u) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_units_invested_transition","page":"Constraints","title":"Investment transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"units_invested represents the point-in-time decision to invest in a unit or not, while units_invested_available represents the invested-in units that are available at a specific time. This constraint enforces the relationship between units_invested, units_invested_available and units_mothballed in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^units_invested_available_(ust) - v^units_invested_(ust)\n+ v^units_monthballed_(ust)\n= v^units_invested_available_(ust-1) \n forall u in unit p^candidate_units_(u) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-connections","page":"Constraints","title":"Investments in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connections_invested_available","page":"Constraints","title":"Available invested-in connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in connections at any point in time is less than the number of investment candidate connections.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connections_invested_available_(cst) p^candidate_connections_(c) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connections_invested_transition","page":"Constraints","title":"Transfer of previous investments","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"connections_invested represents the point-in-time decision to invest in a connection or not while connections_invested_available represents the invested-in connections that are available at a specific time. This constraint enforces the relationship between connections_invested, connections_invested_available and connections_decommissioned in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connections_invested_available_(cst) - v^connections_invested_(cst)\n+ v^connections_decommissioned_(cst) \n = v^connections_invested_available_(cst-1) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_flow_intact_flow","page":"Constraints","title":"Intact network ptdf-based flows on connections","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Enforces the relationship between connection_intact_flow (flow with all investments assumed in force) and connection_flow. This constraint ensures that the connection_flow is connection_intact_flow plus additional flow contributions from investment connections that are not invested in.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n left(v^connection_flow_(c n_to from_node s t)\n- v^connection_flow_(c n_to to_node s t) right)\n- left(v^connection_intact_flow_(c n_to from_node s t)\n- v^connection_intact_flow_(c n_to to_node s t) right) \n =\n sum_c_cand p^lodf_(c_cand c) cdot leftp^candidate_connections_(c_cand) neq 0 right cdot Big( \n qquad left(\n v^connection_flow_(c_cand n_to_cand from_node s t)\n - v^connection_flow_(c_cand n_to_cand to_node s t) \nright)\n\n qquad \n- left(\n v^connection_intact_flow_(c_cand n_to_cand from_node s t)\n - v^connection_intact_flow_(c_cand n_to_cand to_node s t)\nright)\n\n Big) \n forall c in connection p^is_monitored_(c) land p^candidate_connections_(c) = 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_intact_flow_capacity","page":"Constraints","title":"Intact connection flow capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Similarly to this, limits connection_intact_flow according to connection_capacity","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_\nn in ng\n v^connection_intact_flow_(connndst)\n- sum_\nn in ng\n v^connection_intact_flow_(connnreverse(d)st) \n = p^connection_capacity_(connngdst) cdot p^connection_availability_factor_(connst)\ncdot p^connection_conv_cap_to_flow_(connngdst) \n forall (connngd) in indices(p^connection_capacity) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_ratio_out_in_connection_intact_flow","page":"Constraints","title":"Fixed ratio between outgoing and incoming intact flows of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For PTDF-based lossless DC power flow, ensures that the output flow to the to_node equals the input flow from the from_node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned \n v^connection_intact_flow_(c n_out d_to s t)\n=\nv^connection_intact_flow_(c n_in d_from s t) \n forall c in connection p^is_monitored_(c) \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_candidate_connection_flow_lb","page":"Constraints","title":"Lower bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For candidate connections with PTDF-based poweflow, together with this, this constraint ensures that connection_flow is zero if the candidate connection is not invested-in and equals connection_intact_flow otherwise.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c n d s t) \n leq \n v^connection_intact_flow_(c n d s t)\n- p^connection_capacity_(c n d s t) cdot left(\n p^candidate_connections_(c s t) - v^connections_invested_available_(c s t) right) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_candidate_connection_flow_ub","page":"Constraints","title":"Upper bound on candidate connection flow","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For candidate connections with PTDF-based poweflow, together with this, this constraint ensures that connection_flow is zero if the candidate connection is not invested-in and equals connection_intact_flow otherwise.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^connection_flow_(c n d s t) \nleq\nv^connection_intact_flow_(c n d s t) \n forall c in connection p^candidate_connections_(c) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_connection_lifetime","page":"Constraints","title":"Economic lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-connection","page":"Constraints","title":"Technical lifetime of a connection","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Investments-in-storages","page":"Constraints","title":"Investments in storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Note: can we actually invest in nodes that are not storages? (e.g. new location)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storages_invested_available","page":"Constraints","title":"Available invested storages","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The number of available invested-in storages at node n at any point in time is less than the number of investment candidate storages at that node.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^storages_invested_available_(nst)\nleq p^candidate_storages_(nst) \n forall n in node p^candidate_storages_(n) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storages_invested_transition","page":"Constraints","title":"Storage capacity transfer ","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"storages_invested represents the point-in-time decision to invest in storage at a node n or not, while storages_invested_available represents the invested-in storages that are available at a node at a specific time. This constraint enforces the relationship between storages_invested, storages_invested_available and storages_decommissioned in adjacent timeslices.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^storages_invested_available_(nst) - v^storages_invested_(nst)\n+ v^storages_decommissioned_(nst)\n= v^storages_invested_available_(nst-1) \n forall n in node p^candidate_storages_(n) neq 0 \n forall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_storage_lifetime","page":"Constraints","title":"Economic lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2023-05-12: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Technical-lifetime-of-a-storage","page":"Constraints","title":"Technical lifetime of a storage","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Capacity-transfer","page":"Constraints","title":"Capacity transfer","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#Early-retirement-of-capacity","page":"Constraints","title":"Early retirement of capacity","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"(Comment 2021-04-29: Currently under development)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#User-constraints","page":"Constraints","title":"User constraints","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_user_constraint","page":"Constraints","title":"User constraint","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This is a generic data-driven custom constraint which allows for defining constraints involving multiple units, nodes, or connections. The constraint_sense parameter changes the sense of the user_constraint, while the right_hand_side parameter allows for defining the constant term of the constraint.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Coefficients for the different variables appearing in the user_constraint are defined using relationships, like e.g. unit__from_node__user_constraint and connection__to_node__user_constraint for unit_flow and connection_flow variables, or unit__user_constraint and node__user_constraint for units_on, units_started_up, and node_state variables.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"For more information, see the dedicated article on User Constraints","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n sum_u n left\n beginaligned \n sum_op=1^left p^operating_points_(u) right p^unit_flow_coefficient_(unopucst)\n cdot v^unit_flow_op_(undopst) textif left p^operating_points_(u) right 1 \n p^unit_flow_coefficient_(unucst) cdot v^unit_flow_(undst) textotherwise \n endaligned\n right\n\n+sum_u p^units_started_up_coefficient_(uucst) cdot v^units_started_up_(ust) \n+sum_u p^units_on_coefficient_(uucst) cdot v^units_on_(ust) \n+sum_c p^connection_flow_coefficient_(cnucst) cdot v^connection_flow_(cndst) \n+sum_n p^node_state_coefficient_(nucst) cdot v^node_state_(nst) \n+sum_n p^demand_coefficient_(nucst) cdot p^demand_(nst) \n begincases \n = textif p^constraint_sense_(uc) text= ==\n geq textif p^constraint_sense_(uc) text= =\n leq textif p^constraint_sense_(uc) text= ==\n endcases\n+p^right_hand_side_(ucts)\nforall uc in user_constraint \nforall (st)\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#benders_decomposition","page":"Constraints","title":"Benders decomposition","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This section describes the high-level formulation of the benders-decomposed problem.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Taking the simple example of minimising capacity and operating cost for a fleet of units with a linear cost coefficient p^operational_cost:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sum_ust left( p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ sum_nd p^operational_cost_(undst) cdot v^unit_flow_(u n d s t) right) \nst \n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + v^units_invested_available_(u s t)\nright) quad forall u in unit n in node s t\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"So this is a single problem that can't be decoupled over t because the investment variables units_invested_available couple the timesteps together. If units_invested_available were a constant in the problem, then all t's could be solved individually. This is the basic idea in Benders decomposition. We decompose the problem into a master problem and sub problems with the master problem optimising the coupling investment variables which are treated as constants in the sub problems.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The master problem is built by replacing the operational costs (which will be minimised in the sub problem) by a new decision variable, v^sp_objective:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust) + v^sp_objective \nst \n v^sp_objective geq 0\nendaligned\n","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The solution to this problem yields values for the investment variables which are fixed as p^units_invested_available in the sub problem and will be zero in the first iteration.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The sub problem for benders iteration b then becomes :","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin\n\n sp_obj_b = sum_undst p^operational_cost_(undst) cdot v^unit_flow_(u n d s t)\nst\n\n v^unit_flow_(undst) le p^unit_capacity_(u n d s t) cdot left(\n v^units_available_(ust) + p^units_invested_available_(b u s t)\nright) \n qquad forall u in unit n in node st qquad mu_(bust)\n\n sum_ud v^unit_flow_(undst) = p^demand_(n s t) quad forall n in node st\nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This sub problem can be solved individually for each t. This is pretty trivial in this small example but if we consider a single t to be a single rolling horizon instead, decoupling the investment variables means that each rolling horizon can be solved individually rather than having to solve the entire model horizon as a single problem.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"mu_(bust) is the marginal value of the capacity constraint for benders iteration b and can be interpreted as the decrease in the objective function for an additional MW of flow from unit u (in scenario s at time t). Thus, an upper bound on the sub problem objective function is obtained as follows:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"sp_obj_b + sum_undst mu_(bust) cdot p^unit_capacity_(undst) \ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right)","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The above is added to the master problem for the next iteration as a new constraint, called a Benders cut, thus becoming:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\nmin \n sum_ust p^unit_investment_cost_(ust) cdot v^units_invested_(ust)\n+ v^sp_objective \n\nst \n\n v^sp_objective geq sp_obj_b \n quad + sum_undst mu_(bust) cdot p^unit_capacity_(undst)\ncdot left(v^units_invested_available_(ust) - p^units_invested_available_(bust)right) quad forall b \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"Note the benders cuts are added as inequalities because they represent an upper bound on the value we are going to get for the sub problem objective function by adjusting the master problem variables in that benders iteration. If we consider the example of renewable generation - because it's marginal cost is zero, on the first benders iteration, it could look like there would be a lot of value in increasing the capacity because of the marginal values from the sub problems. However, when the capacity variables are increased accordingly and curtailment occurs in the sub-problems, the marginal values will be zero when curtailment occurs and so, other resources may become optimal in subsequent iterations.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"This is a simple example but it illustrates the general strategy. The algorithm pseudo code looks something like this:","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":" initialise master problem\n initialise sub problem\n solve first master problem\n create master problem variable time series\n solve rolling spine opt model\n save zipped marginal values\n while master problem not converged\n update master problem\n solve master problem\n update master problem variable timeseries for benders iteration b\n rewind sub problem\n update sub problem\n solve rolling spine opt model\n save zipped marginal values\n test for convergence\n end","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/#constraint_mp_any_invested_cuts","page":"Constraints","title":"Benders cuts","text":"","category":"section"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"The benders cuts for the problem including all investments in candidate connections, storages and units is given below.","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"beginaligned\n v^sp_objective \n geq \n p^sp_obj_(b) + \n sum_ust p^units_invested_available_mv_(bust)\ncdot left( v^units_invested_available_(ust) - p^units_invested_available_(ust) right) \n + sum_cst p^connections_invested_available_mv_(bcst)\ncdot left( v^connections_invested_available_(cst) - p^connections_invested_available_(cst) right) \n + sum_nst p^storages_invested_available_mv_(bnst)\ncdot left( v^storages_invested_available_(nst) - p^storages_invested_available_(nst) right) \nendaligned","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"where","category":"page"},{"location":"mathematical_formulation/constraints_automatically_generated/","page":"Constraints","title":"Constraints","text":"p^sp_obj_(b) is the sub problem objective function value in benders iteration b,\np^units_invested_available_mv is the reduced cost of the units_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a unit of this type, \np^connections_invested_available_mv is the reduced cost of the connections_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a connection of this type, \np^storages_invested_available_mv is the reduced cost of the storages_invested_available fixed sub-problem variable, representing the reduction in operating costs possible from an investment in a storage node of this type, \np^units_invested_available is the value of the fixed sub problem variable units_invested_available in benders iteration b, \np^connections_invested_available is the value of the fixed sub problem variable connections_invested_available in benders iteration b and \np^storages_invested_available is the value of the fixed sub problem variable storages_invested_available in benders iteration b","category":"page"},{"location":"concept_reference/fix_storages_invested_available/","page":"-","title":"-","text":"Used primarily to fix the value of the storages_invested_available variable which represents the storages investment decision variable and how many candidate storages are available at the corresponding node, time step and stochastic scenario. Used also in the decomposition framework to communicate the value of the master problem solution variables to the operational sub-problem.","category":"page"},{"location":"concept_reference/fix_storages_invested_available/","page":"-","title":"-","text":"See also candidate_storages and Investment Optimization","category":"page"},{"location":"concept_reference/connection_availability_factor/","page":"-","title":"-","text":"To indicate that a connection is only available to a certain extent or at certain times of the optimization, the connection_availability_factor can be used. A typical use case could be an availability timeseries for connection with expected outage times. By default the availability factor is set to 1. The availability is, among others, used in the constraint_connection_flow_capacity.","category":"page"},{"location":"concept_reference/connection__from_node/","page":"-","title":"-","text":"connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/duration_unit_list/","page":"-","title":"-","text":"The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.","category":"page"},{"location":"concept_reference/commodity_physics_list/","page":"-","title":"-","text":"commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details","category":"page"},{"location":"concept_reference/connection_investment_variable_type/","page":"-","title":"-","text":"The connection_investment_variable_type parameter represents the type of the connections_invested_available decision variable.","category":"page"},{"location":"concept_reference/connection_investment_variable_type/","page":"-","title":"-","text":"The default value, variable_type_integer, means that only integer factors of the connection_capacity can be invested in. The value variable_type_continuous means that any fractional factor can also be invested in. The value variable_type_binary means that only a factor of 1 or zero are possible.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_in/","page":"-","title":"-","text":"The fix_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the fix_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, and fix_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_in_in and max_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"Indicates the end of this temporal block. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"single solve When a Date time value is chosen, this is directly the end of the optimization for this temporal block. In a single solve optimization, a combination of block_start and block_end can easily be used to run optimizations that cover only part of the model horizon. Multiple temporal_block objects can then be used to create optimizations for disconnected time periods, which is commonly used in the method of representative days. The default value coincides with the model_end.","category":"page"},{"location":"concept_reference/block_end/","page":"-","title":"-","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The block_end parameter will in this case determine the size of the optimization window, with respect to the start of each optimization window. If multiple temporal blocks with different block_end parameters exist, the maximum value will determine the size of the optimization window. Note, this is different from the roll_forward parameter, which determines how much the window moves for after each optimization. For more info, see One single temporal_block. The default value is equal to the roll_forward parameter.","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"Together with the model_start parameter, it is used to define the temporal horizon of the model. In case of a single solve optimization, the parameter marks the end of the last timestep that is possibly part of the optimization. Note that it poses an upper bound, and that the optimization does not necessarily include this timestamp when the block_end parameters are more stringent.","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"In case of a rolling horizon optimization, it will tell to the model to stop rolling forward once an optimization has been performed for which the result of the indicated timestamp has been kept in the final results. For example, assume that a model_end value of 2030-01-01T05:00:00 has been chosen, a block_end of 3h, and a roll_forward of 2h. The roll_forward parameter indicates here that the results of the first two hours of each optimization window are kept as final, therefore the last optimization window will span the timeframe [2030-01-01T04:00:00 - 2030-01-01T06:00:00].","category":"page"},{"location":"concept_reference/model_end/","page":"-","title":"-","text":"A DateTime value should be chosen for this parameter. ","category":"page"},{"location":"concept_reference/model__report/","page":"-","title":"-","text":"The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"The definition of the min_down_time parameter will trigger the creation of the Constraint on minimum down time. It sets a lower bound on the period that a unit has to stay offline after a shutdown.","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/min_down_time/","page":"-","title":"-","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_in/","page":"-","title":"-","text":"The max_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the max_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow being constrained: max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/fix_node_voltage_angle/","page":"-","title":"-","text":"For a lossless nodal DC power flow network, each node is associated with a node_voltage_angle variable. In order to fix the voltage angle at a certain node or to give initial conditions the fix_node_voltage_angle parameter can be used.","category":"page"},{"location":"how_to/print_the_model/#How-to-print-the-model","page":"Print the model","title":"How to print the model","text":"","category":"section"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"As the SpineOpt model formulation is quite complex and can change depending on a few parameters (some parts of the formulation can be activated or deactivated), it can be useful to print the model that SpineOpt sends to JuMP. There are a few ways to do this.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"The model that SpineOpt sends to JuMP can be saved to a file. It is not the nicest file to read but at the very least you can find the used variables and parameter values.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"To write that file you need to set the write_mps_file parameter of the model object to write_mps_always.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"SpineOpt will write the file to the working directory. If you are using Spine Toolbox that working directory will be the Spine Toolbox work folder which is typically in your user directory e.g. C:\\Users\\username\\.spinetoolbox\\work\\run_spineopt_gibberish_toolbox\\model_diagnostics.mps","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"An alternative approach is to directly use the write_model_file(m, filename) command in which m is a reference to your model and filename is the filename you want the model file written to.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"m can be obtained from the call to run_spineopt(). In Spine Toolbox, more particularly the run_SpineOpt tool, you will have m=run_spineopt(). That means that you can call write_model_file(m,filename) in the console once SpineOpt has finished executing and the console remains open.","category":"page"},{"location":"how_to/print_the_model/","page":"Print the model","title":"Print the model","text":"In either case, here are some tips if you are using this file for debugging. The file can be very large so often it is helpful to create a minimum example of your model with only one or two timesteps. Also, in the call to run_spineopt() you can add the keyword argument optimize=false so it will just build the model and not attempt to solve it.","category":"page"},{"location":"concept_reference/overwrite_results_on_rolling/","page":"-","title":"-","text":"The overwrite_results_on_rolling parameter allows one to define whether or not results from further optimisation windows should overwrite those from previous ones. This, of course, is relevant only if optimisation windows overlap, which in turn happens whenever a temporal_block goes beyond the end of the window.","category":"page"},{"location":"concept_reference/overwrite_results_on_rolling/","page":"-","title":"-","text":"If true (the default) then results are written as a time-series. If false, then results are written as a map from analysis time (i.e., the window start) to time-series.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_out/","page":"-","title":"-","text":"The fix_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the fix_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for fixing the conversion ratio depending on the amount of online capacity.","category":"page"},{"location":"concept_reference/fix_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, and fix_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or maximum conversion rates, e.g. min_units_on_coefficient_out_out and max_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/node_state_min/","page":"-","title":"-","text":"The node_state_min parameter sets the lower bound for the node_state variable, if one has been enabled by the has_state parameter. For reserve nodes with minimum_reserve_activation_time, the node_state_min is considered also via a special constraint.","category":"page"},{"location":"concept_reference/node_slack_penalty/","page":"-","title":"-","text":"node_slack_penalty triggers the creation of node slack variables, node_slack_pos and node_slack_neg. This allows the model to violate the node_balance constraint with these violations penalised in the objective function with a coefficient equal to node_slack_penalty. If node_slack_penalty = 0 the slack variables are created and violations are unpenalised. If set to none or undefined, the variables are not created and violation of the node_balance constraint is not possible.","category":"page"},{"location":"concept_reference/downward_reserve/","page":"-","title":"-","text":"If a node has a true is_reserve_node parameter, it will be treated as a reserve node in the model. To define whether the node corresponds to an upward or downward reserve commodity, the upward_reserve or the downward_reserve parameter needs to be set to true, respectively.","category":"page"},{"location":"concept_reference/node_opf_type/","page":"-","title":"-","text":"Used to identify the reference node (or slack bus) when ptdf based dc load flow is enabled (commodity_physics set to commodity_physics_ptdf or commodity_physics_lodf. To identify the reference node, set node_opf_type = :node_opf_type_reference","category":"page"},{"location":"concept_reference/node_opf_type/","page":"-","title":"-","text":"See also powerflow.","category":"page"},{"location":"concept_reference/balance_type/","page":"-","title":"-","text":"The balance_type parameter determines whether or not a node needs to be balanced, in the classical sense that the sum of flows entering the node is equal to the sum of flows leaving it.","category":"page"},{"location":"concept_reference/balance_type/","page":"-","title":"-","text":"The values balance_type_node (the default) and balance_type_group mean that the node is always balanced. The only exception is if the node belongs in a group that has itself balance_type equal to balance_type_group. The value balance_type_none means that the node doesn't need to be balanced.","category":"page"},{"location":"advanced_concepts/decomposition/#Decomposition","page":"Decomposition","title":"Decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Decomposition approaches take advantage of certain problem structures to separate them into multiple related problems which are each more easily solved. Decomposition also allows us to do the inverse, which is to combine independent problems into a single problem, where each can be solved separately but with communication between them (e.g. investments and operations problems)","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Decomposition thus allows us to do a number of things","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Solve larger problems which are otherwise intractable\nInclude more detail in problems which otherwise need to be simplified\nCombine related problems (e.g. investments/operations) in a more scientific way (rather than ad-hoc).\nEmploy parallel computing methods to solve multiple problems simultaneously.","category":"page"},{"location":"advanced_concepts/decomposition/#High-level-Decomposition-Algorithm","page":"Decomposition","title":"High-level Decomposition Algorithm","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"The high-level algorithm is described below. For a more detailed description please see Benders decomposition","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Model initialisation (preprocessdatastructure, generate temporal structures etc.)\nFor each benders_iteration\nSolve master problem\nProcess master-problem solution:\nset units_invested_bi(unit=u) equal to the investment variables solution from the master problem\nSolve operations problem loop\nProcess operations sub-problem\nset units_on_mv(unit=u) equal to the marginal value of the units_on bound constraint\nTest for convergence\nUpdate master problem\nAdd Benders cuts constraints\nRewind operations problem\nNext benders iteration","category":"page"},{"location":"advanced_concepts/decomposition/#Duals-and-reduced-costs-calculation-for-decomposition","page":"Decomposition","title":"Duals and reduced costs calculation for decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"The marginal values above are computed as the reduced costs of relevant optimisation variables. However, the dual solution to a MIP problem is not well defined. The standard approach to obtaining marginal values from a MIP model is to relax the integer variables, fix them to their last solution value and re-solve the problem as an LP. This is the standard approach in energy system modelling to obtain energy prices. However, although this is the standard approach, it does need to be used with caution. The main hazard associated with inferring duals in this way is that the impact on costs of an investment may be overstated. However, since these duals are used in Benders decomposition to obtain a lower bound on costs (i.e. the maximum potential value from an investment), this is ok and can be \"corrected\" in the next iteration. And finally, the benders gap will tell us how close our decomposed problem is to the optimal global solution.","category":"page"},{"location":"advanced_concepts/decomposition/#Reporting-dual-values-and-reduced-costs","page":"Decomposition","title":"Reporting dual values and reduced costs","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's relaxed problem marginal value will be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"To report the reduced cost for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of units_on in the final fixed LP to be written to the output db.","category":"page"},{"location":"advanced_concepts/decomposition/#Using-Decomposition","page":"Decomposition","title":"Using Decomposition","text":"","category":"section"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Assuming one has set up a conventional investments problem as described in Investment Optimization the following additional steps are required to utilise the decomposition framework:","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Set the model_type parameter for your model to spineopt_benders.\nSpecify max_gap parameter for your model - This determines the master problem convergence criterion for the relative benders gap. A value of 0.05 will represent a relative benders gap of 5%.\nSpecify the max_iterations parameter for your model - This determines the master problem convergence criterion for the number of iterations. A value of 10 could be appropriate but this is highly dependent on the size and nature of the problem.","category":"page"},{"location":"advanced_concepts/decomposition/","page":"Decomposition","title":"Decomposition","text":"Once the above is set, all investment decisions in the model are automatically decomposed and optimised in a Benders master problem. This behaviour may change in the future to allow some investment decisions to be optimised in the operations problem and some optimised in the master problem as desired.","category":"page"},{"location":"advanced_concepts/reserves/#Reserves","page":"Reserves","title":"Reserves","text":"","category":"section"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"To include a requirement of reserve provision in a model, SpineOpt offers the possibility of creating reserve nodes. Of course reserve provision is different from regular operation, because the reserved capacity does not actually get activated. In this section we will take a look at the things that are particular for a reserve node.","category":"page"},{"location":"advanced_concepts/reserves/#Defining-a-reserve-node","page":"Reserves","title":"Defining a reserve node","text":"","category":"section"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"To define a reserve node, the following parameters have to be defined for the relevant node:","category":"page"},{"location":"advanced_concepts/reserves/","page":"Reserves","title":"Reserves","text":"is_reserve_node : this boolean parameter indicates that this node is a reserve node.\nupward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns upward reserves.\ndownward_reserve : this boolean parameter indicates that the demand for reserve provision of this node concerns downward reserves.\nreserve_procurement_cost: (optional) this parameter indicates the procurement cost of a unit for a certain reserve product and can be define on a unit__to_node or unit__from_node relationship.","category":"page"},{"location":"concept_reference/connections_invested_mga/","page":"-","title":"-","text":"The connections_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of connections_invested_mga is set to true, investment decisions in this connection, or group of connections, will be included in the MGA algorithm.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Hydro-Power-Planning","page":"Two hydro plants","title":"Hydro Power Planning","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Welcome to this Spine Toolbox tutorial for building hydro power planning models. The tutorial guides you through the implementation of different ways of modelling hydrodologically-coupled hydropower systems.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Introduction","page":"Two hydro plants","title":"Introduction","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"This tutorial aims at demonstrating how we can model a hydropower system in Spine (SpineOpt.jl and Spine-Toolbox) with different assumptions and goals. It starts off by setting up a simple model of system of two hydropower plants and gradually introduces additional features. The goal of the model is to capture the combined operation of two hydropower plants (Språnget and Fallet) that operate on the same river as shown in the picture bellow. Each power plant has its own reservoir and generates electricity by discharging water. The plants might need to spill water, i.e., release water from their reservoirs without generating electricity, for various reasons. The water discharged or spilled by the upstream power plant follows the river route and becomes available to the downstream power plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: A system of two hydropower plants.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"A system of two hydropower plants","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing-the-spineopt-database-template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nJust remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Two_hydro’) in the corresponding step, so to not mix up the Spine Toolbox projects!","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"That is all you need at the moment, you can now start inserting the data.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Setting-up-a-Basic-Hydropower-Model","page":"Two hydro plants","title":"Setting up a Basic Hydropower Model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"For creating a SpineOpt model you need to create Objects, Relationships (associating the objects), and in some cases, parameters values accompanying them. To do this, open the input database using the Spine DB Editor (double click on the input database in the Design View pane of Spine Toolbox).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nTo save your work in the Spine DB Editor you need to commit your changes (please check the Simple System tutorial for how to do that). As a good practice, you should commit often as you enter the data in the model to avoid data loss.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-objects","page":"Two hydro plants","title":"Defining objects","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Commodities","page":"Two hydro plants","title":"Commodities","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Since we are modelling a hydropower system we will have to define two commodities, water and electricity. In the Spine DB editor, locate the Object tree, expand the root element if required, right click on the commodity class, and select Add objects from the context menu. In the Add objects dialogue that should pop up, enter the object names for the commodities as you see in the image below and then press Ok.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining commodities.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Nodes","page":"Two hydro plants","title":"Nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Follow a similar path to add nodes, right click on the node class, and select Add objects from the context menu. In the dialogue, enter the node names as shown:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining nodes.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Nodes in SpineOpt are used to balance commodities. As you noticed, we defined two nodes for each hydropower station (water nodes) and a single electricity node. This is one possible way to model the hydropower plant operation. This will become clearer in the next steps, but in a nutshell, the upper node represents the water arriving at each plant, while the lower node represents the water that is discharged and becomes available to the next plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Connections","page":"Two hydro plants","title":"Connections","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Similarly, add connections, right click on the connection class, select Add objects from the context menu and add the following connections:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining connections.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Connections enable the nodes to interact. Since, for each plant we need to model the amount of water that is discharged and the amount that is spilled, we must define two connections accordingly. When defining relationships we shall associate the connections with the nodes.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Units","page":"Two hydro plants","title":"Units","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To convert from one type of commodity associated with one node to another, you need a unit. You guessed it! Right click on the unit class, select Add objects from the context menu and add the following units:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining units.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"We have defined one unit for each hydropower plant that converts water to electricity and an additional unit that we will use to model the income from selling the electricity production in the electricity market.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Relationships","page":"Two hydro plants","title":"Relationships","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Assinging-commodities-to-nodes","page":"Two hydro plants","title":"Assinging commodities to nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Since we have defined more than one commodities, we need to assign them to nodes. In the Spine DB editor, locate the Relationship tree, expand the root element if required, right click on the node__commodity class, and select Add relationships from the context menu. In the Add relationships dialogue, enter the following relationships as you see in the image below and then press Ok.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing node__commodity relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Associating-connections-to-nodes","page":"Two hydro plants","title":"Associating connections to nodes","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Next step is to define the topology of flows between the nodes. To do that insert the following relationships in the connection__from_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: image)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing connection__from_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"as well as the following the following connection__node_node relationships as you see in the figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing connection__node_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing connection__node_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Placing-the-units-in-the-model","page":"Two hydro plants","title":"Placing the units in the model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To define the topology of the units and be able to introduce their parameters later on, you need to define the following relationships in the unit__from_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__from_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__from_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"in the unit__node_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__node_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__node_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"and in the unit__to_node class as you see in the following figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing unit__to_node relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing unit__to_node relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-the-report-outputs","page":"Two hydro plants","title":"Defining the report outputs","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To force Spine to export the optimal values of the optimization variables to the output database you need to specify them in the form of report_output relationships. Add the following relationships to the report_output class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Introducing report outputs with report_output relationships.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Introducing report outputs with report_output relationships.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Objects-and-Relationships-parameter-values","page":"Two hydro plants","title":"Objects and Relationships parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/#Defining-model-parameter-values","page":"Two hydro plants","title":"Defining model parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The specify modelling properties of both objects and relationships you need to introduce respective parameter values. To introduce object parameter values first select the model class in the Object tree and enter the following values in the Object parameter value pane:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining model execution parameters.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining model execution parameters.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Observe the difference between the Object parameter value and the Object parameter definition sub-panes of the Object parameter value pane. The first one is for the modeller to introduce values for specific parameters, while the second one holds the definition of all available parameters with their default values (these are overwritten when the user introduces their own values). Feel free to explore the different parameters and their default values. While entering data in each row you will also observe that, in most cases, clicking on each cell activates a drop-down list of elements that the user must choose from. In the case of the value cells, however, unless you need to input a scalar value or a string, you should right-click on the cell and select edit for specifying the data type of the parameter value. As you see in the figure above, for the first duration_unit parameter you is of type string, while the model_start and model_end parameters are of type Date time. The Date time parameters can be edited by right-clicking on the corresponding value cells, selecting Edit, and then inserting the Date time values that you see in the figure above in the Datetime field using the correct format.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-node-parameter-values","page":"Two hydro plants","title":"Defining node parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Going back to hydropower modelling, we need to specify several parameters for the nodes of the systems. In the same pane as before, but this time selecting the node class from the Object tree, we need to add the following entries:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining model execution parameters.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining model execution parameters.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Before we go through the interpretation of each parameter, click on the following link for each fix_node_state parameter (Node state Språnget, Node state Fallet), select all, copy the data and then paste them directly in the respective parameter value cell. Spine should automatically detect and input the timeseries data as a parameter value. The data type for those entries should be Timeseries as shown in the figure above. Alternatively, you can select the data type as Timeseries and manually insert the data (values with their corresponding datetimes).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To model the reservoirs of each hydropower plant, we leverage the state feature that a node can have to represent storage capability. We only need to do this for one of the two nodes that we have used to model each plant and we choose the upper level node. To define storage, we set the value of the parameter has_state as True (be careful to not set it as a string but select the boolean true value by right clicking and selecting Edit in the respective cells). This activates the storage capability of the node. Then, we need to set the capacity of the reservoir by setting the node_state_cap parameter value. Finally, we fix the initial and final values of the reservoir by setting the parameter fix_node_state to the respective values (we introduce nan values for the time steps that we don't want to impose such constraints). To model the local inflow we use the demand parameter but using the negated value of the actual inflow, due to the definition of the parameter in Spine as a demand.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-the-temporal-resolution-of-the-model","page":"Two hydro plants","title":"Defining the temporal resolution of the model","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Spine automates the creation of the temporal resolution of the optimization model and even supports different temporal resolutions for different parts of the model. To define a model with an hourly resolution we select the temporal_block class in the Object tree and we set the resolution parameter value to 1h as shown in the figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the temporal resolution of the model.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the temporal resolution of the model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-connection-parameter-values","page":"Two hydro plants","title":"Defining connection parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The water that is discharged from Språnget will flow from Språnget_lower node to Fallet_upper through the Språnget_to_Fallet_disc connection, while the water that is spilled will flow from Språnget_upper directly to to Fallet_upper through the Språnget_to_Fallet_spill connection. To model this we need to select the connection__node_node class in the Relationship tree and add the following entries in the Relationship parameter value pane, as shown next:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining discharge and spillage ratio flows.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining discharge and spillage ratio flows.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Defining-unit-parameter-values","page":"Two hydro plants","title":"Defining unit parameter values","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Similarly, for each one of the unit__from_node, unit__node_node, and unit__to_node relationship classes we need to add the the maximal water that can be discharged by each hydropower plant:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the maximal water discharge of each plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the maximal water discharge of each plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To define the income from selling the produced electricity we use the vom_cost parameter and negate the values of the electricity prices. To automatically insert the timeseries data in Spine, click on the Electricity prices timeseries, select all values, copy, and paste them, after having selected the value cell of the corresponding row. You can plot and edit the timeseries data by double clicking on the same cell afterwards:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Previewing and editing the electricity prices timeseries.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Previewing and editing the electricity prices timeseries.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Carrying on with our hydropower model we must define the conversion ratios between the nodes. Assuming that water is not \"lost\" from the upper node toward the lower node and electricity is produced with the discharged water with a given efficiency we define the following parameter values for each hydropower plant, in the unit__node_node class:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Defining conversion efficiencies.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Defining conversion efficiencies.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Lastly, we can define the maximal electricity production of each plant by inserting the following unit__to_node relationship parameter values:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Setting the maximal electricity production of each plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Setting the maximal electricity production of each plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Hooray! You can now commit the database, close the Spine DB Editor and run your model! Go to the main Spine window and click on Execute (Image: image).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Examining-the-results","page":"Two hydro plants","title":"Examining the results","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Select the output data store and open the Spine DB editor. To quickly plot some results, you can expand the unit class in the Object tree and select the electricity_load unit. In the Relationship parameter value pane double click on the value cell of","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | electricity_load | electricity_node | from_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"object name. This will open a plotting window from were you can also examine closer and retrieve the data, as shown in the next figure. The unit_flow variable of the electricity_load unit represents the total electricity production in the system:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Total electricity produced in the system.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Total electricity produced in the system.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Now, take to a minute to reflect on how you could retrieve the data representing the water that is discharged by each hydropower plant as shown in the next figure:","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"(Image: Water discharge of Språnget hydropower plant.)","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Water discharge of Språnget hydropower plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"The right answer is that you need to select some hydropower plant (e.g., Språnget) and then double-click on the value cell of the object name","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | Språnget_pwr_plant | Språnget_lower | to_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"or","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"report1 | Språnget_pwr_plant | Språnget_upper | from_node | realization","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It could be useful to also reflect on why these objects give the same results, and what do the results from the third element represent. (Hint: observe the to_ or from_ directions in the object names). As an exercise, you can try to retrieve the timeseries data for spilled water as well as the water levels at the reservoir of each hydropower plant.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"You can further explore the model, or make changes in the input database to observe how these affect the results, e.g., you can use different electricity prices, values for the reservoir capacity (and initialization points), as well as change the temporal resolution of the model. All you need to do is commit the changes and run your model. Every time that you run the model, your results are appended in the output database with an execution timestamp. You can however filter your results per execution, by selecting the Alternative that you want from the Alternative/Scenario tree pane. You can use the exporter too to export specific variables in an Excel sheet. Alternatively, you can export all the data of the output database by going to the main menu (Press Alt + F to display it), selecting File -> Export, then select the items that you want, click ok and export the data in Excel, or json format.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"In the following, we extend this simple hydropower system to include more elaborate modelling choices.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"note: Note\nIn each of the next sections, we perform incremental changes to the initial simple hydropower model. If you want to keep the database that you created, you can duplicate the database file (right-click on the input database and select Duplicate and duplicate files) and perform the changes in the new database. You need to configure the workflow accordingly in order to run the database you want (please check the Simple System tutorial for how to do that).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Maximisation-of-Stored-Water","page":"Two hydro plants","title":"Maximisation of Stored Water","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Instead of fixing the water content of the reservoirs at the end of the planning period, we can consider that the remaining water in the reservoirs has a value and then maximize the value along with the revenues for producing electricity within the planning horizon. This objective term is often called the Value of stored water and we can approximate it by assuming that this water will be used to generate electricity in the future that would be sold at a forecasted price. The water stored in the upstream hydropower plant will become also available to the downstream plant and this should be taken into account.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"To model the value of stored water we need to make some additions and modifications to the initial model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"First, add a new node (see adding nodes) and give it a name (e.g., stored_water). This node will accumulate the water stored in the reservoirs at the end of the planning horizon. Associate the node with the water commodity (see node__commodity).\nAdd three more units (see adding units); two will transfer the water at the end of the planning horizon in the new node that we just added (e.g., Språnget_stored_water, Fallet_stored_water), and one will be used as a sink introducing the value of stored water in the objective function (e.g., value_stored_water).\nTo establish the topology of the new units and nodes (see adding unit relationships):\nadd one unit__from_node relationship, between the value_stored_water unit from the stored_water node, another one between the Språnget_stored_water unit from the Språnget_upper node and one for Faller_stored_water from Fallet_upper.\nadd one unit__node__node relationship between the Språnget_stored_water unit with the stored_water and Språnget_upper nodes and another one for Fallet_stored_water unit with the stored_water and Fallet_upper nodes,\nadd a unit__to_node relationship between the Fallet_stored_water and the stored_water node and another one between the Språnget_stored_water unit and the stored_water node.\nNow we need to make some changes in object parameter values.\nExtend the planning horizon of the model by one hour, i.e., change the model_end parameter value to 2021-01-02T01:00:00 (right-click on the value cell, click edit and paste the new datetime in the popup window).\nRemove the fix_node_state parameter values for the end of the optimization horizon as you seen in the following figure: double click on the value cell of the Språnget_upper and Fallet_upper nodes, select the third data row, right-click, select Remove rows, and click OK.\nAdd an electricity price for the extra hour. Enter the parameter vom_cost on the unit__from_node relationship between the electricity_node and the electricity_load and set 0 as the price of electricity for the last hour 2021-01-02T00:00:00. The price is set to zero to ensure no electricity is sold during this hour.\n(Image: Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.) Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.\nFinally, we need to add some relationship parameter values for the new units:\nAdd a vom_cost parameter value on a value_stored_water|stored_water instance of a unit__from_node relationship, as you see in the figure bellow. For the timeseries you can copy-paste the data directly from this link. If you examine the timeseries data you'll notice that we have imposed a zero cost for all the optimisation horizon, while we use an assumed future electricity value for the additional time step at the end of the horizon. \n(Image: Adding vom_cost parameter value on the value_stored_water unit.) Adding vom_cost parameter value on the value_stored_water unit.\nAdd two fix_ratio_out_in_unit_flow parameter values as you see in the figure bellow. The efficiency of Fallet_stored_water is the same as the Fallet_pwr_plant as the water in Fallet's reservoir will be used to produce electricity by the the Fallet plant only. On the other hand, the water from Språnget's reservoir will be used both by Fallet and Språnget plant, therefore we use the sum of the two efficiencies in the parameter value of Språnget_stored_water.\n(Image: Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.) Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"You can now commit your changes in the database, execute the project and examine the results! As an exercise, try to retrieve the value of stored water as it is calculated by the model.","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Spillage-Constraints-Minimisation-of-Spilt-Water","page":"Two hydro plants","title":"Spillage Constraints - Minimisation of Spilt Water","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It might be the case that we need to impose certain limits to the amount of water that is spilt on each time step of the planning horizon, e.g., for environmental reasons, there can be a minimum and a maximum spillage level. At the same time, to avoid wasting water that could be used for producing electricity, we could explicitly impose the spillage minimisation to be added in the objective function.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Add one unit (see adding units) to impose the spillage constraints to each plant and name it (for example Språnget_spill).\nRemove the Språnget_to_Fallet_spill connection (in the Object tree expand the connection class, right-click on Språnget_to_Fallet_spill, and the click Remove).\nTo establish the topology of the unit (see adding unit relationships):\nAdd a unit__from_node relationship, between the Språnget_spill unit from the Språnget_upper node,\nadd a unit__node__node relationship between the Språnget_spill unit with the Fallet_upper and Språnget_upper nodes,\nadd a unit__to_node relationship between the Språnget_spill and the Fallet_upper node,\nAdd the relationship parameter values for the new units:\nSet the unit_capacity (to apply a maximum), the minimum_operating_point (defined as a percentage of the unit_capacity) to impose a minimum, and the vom_cost to penalise the water that is spilt:\n(Image: Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.)\nSetting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"For the Språnget_spill unit define the fix_ratio_out_in_unit_flow parameter value of the min_spillage|Fallet_upper|Språnget_upper relationship to 1 (see adding unit relationships).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Commit your changes in the database, execute the project and examine the results! As an exercise, you can perform this process for and Fallet plant (you would also need to add another water node, downstream of Fallet).","category":"page"},{"location":"tutorial/tutorialTwoHydro/#Follow-Contracted-Load-Curve","page":"Two hydro plants","title":"Follow Contracted Load Curve","text":"","category":"section"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"It is often the case that a system of hydropower plants should follow a given production profile. To model this in the given system, all we have to do is set a demand in the form of a timeseries to the electricity_node.","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Add the Contracted load timeseries, to the demand parameter value of the electricity_node (see adding node parameter values).","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"Commit your changes in the database, execute the project and examine the results!","category":"page"},{"location":"tutorial/tutorialTwoHydro/","page":"Two hydro plants","title":"Two hydro plants","text":"This concludes the tutorial, we hope that you enjoyed building hydropower systems in Spine as much as we do!","category":"page"},{"location":"concept_reference/node__commodity/","page":"-","title":"-","text":"node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:","category":"page"},{"location":"concept_reference/node__commodity/","page":"-","title":"-","text":"To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow\nOnly connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.","category":"page"},{"location":"getting_started/archetypes/#Archetypes","page":"Archetypes","title":"Archetypes","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Archetypes are essentially ready-made templates for different aspects of SpineOpt.jl. They are intended to serve both as examples for how the data structure in SpineOpt.jl works, as well as pre-made modular parts that can be imported on top of existing model input data.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"The templates/models/basic_model_template.json contains a ready-made template for simple energy system models, with uniform time resolution and deterministic stochastic structure. Essentially, it serves as a basis for testing how the modelled system is set up, without having to worry about setting up the temporal and stochastic structures.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"The rest of the different archetypes are included under templates/archetypes in the SpineOpt.jl repository. Each archetype is stored as a .json file containing the necessary objects, relationships, and parameters to form a functioning pre-made part for a SpineOpt.jl model. The archetypes aren't completely plug-and-play, as there are always some relationships required to connect the archetype to the other input data correctly. Regardless, the following sections explain the different archetypes included in the SpineOpt.jl repository, as well as what steps the user needs to take to connect said archetype to their input data correctly.","category":"page"},{"location":"getting_started/archetypes/#Loading-the-SpineOpt-Template-and-Archetypes-into-Your-Model","page":"Archetypes","title":"Loading the SpineOpt Template and Archetypes into Your Model","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"To load the latest version of the SpineOpt template, in the Spine DB Editor, from the menu (three hirzontal bars in the top right), click on import as follows:","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"(Image: importing the SpineOpt Template)","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Change the file type to JSON and click on spineopt_template.json as follows:","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"(Image: importing the SpineOpt Template)","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Click on spineopttemplate.json and press Open. If you don't see spineopttemplate.json make sure you have navigated to Spine\\SpineOpt.jl\\templates.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Loading the latest version of the SpineOpt template in this way will update your datastore with the latest version of the data structure.","category":"page"},{"location":"getting_started/archetypes/#Branching-Stochastic-Tree","page":"Archetypes","title":"Branching Stochastic Tree","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/branching_stochastic_tree.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called branching, representing a branching scenario tree. The stochastic_structure starts out as a single stochastic_scenario called realistic, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. This archetype is the final product of following the steps in the Example of branching stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"getting_started/archetypes/#Converging-Stochastic-Tree","page":"Archetypes","title":"Converging Stochastic Tree","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/converging_stochastic_tree.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called converging, representing a converging scenario tree (technically a directed acyclic graph DAG). The stochastic_structure starts out as a single stochastic_scenario called realization, which then branches out into three roughly equiprobable stochastic_scenarios called forecast1, forecast2, and forecast3 after 6 hours. Then, after 24 hours (1 day), these three forecasts converge into a single stochastic_scenario called converged_forecast. This archetype is the final product of following the steps in the Example of converging stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"getting_started/archetypes/#Deterministic-Stochastic-Structure","page":"Archetypes","title":"Deterministic Stochastic Structure","text":"","category":"section"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"templates/archetypes/deterministic_stochastic_structure.json","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"This archetype contains the definitions required for an example stochastic_structure called deterministic, representing a simple deterministic modelling case. The stochastic_structure contains only a single stochastic_scenario called realization, which continues indefinitely. This archetype is the final product of following the steps in the Example of deterministic stochastics part of the Stochastic Framework section.","category":"page"},{"location":"getting_started/archetypes/","page":"Archetypes","title":"Archetypes","text":"Importing this archetype into an input datastore only creates the stochastic_structure, which needs to be connected to the rest of your model using either the model__default_stochastic_structure relationship for a model-wide default, or the other relevant Structural relationship classes. Note that the model-wide default gets superceded by any conflicting definitions via e.g. the node__stochastic_structure.","category":"page"},{"location":"concept_reference/duration_unit/","page":"-","title":"-","text":"The duration_unit parameter specifies the base unit of time in a model. Two values are currently supported, hour and the default minute. E.g. if the duration_unit is set to hour, a Duration of one minute gets converted into 1/60 hours for the calculations.","category":"page"},{"location":"implementation_details/documentation/#Documentation","page":"Documentation","title":"Documentation","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The documentation is build with Documenter.jl, by running the make.jl script. Note that make.jl calls some stuff from docs_util.jl.","category":"page"},{"location":"implementation_details/documentation/#Concept-reference","page":"Documentation","title":"Concept reference","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"Parameters.md is one of the files that is automatically generated. Each parameter has a description in the concept_reference folder and is further processed with the spineopt template. As such there is no point in attempting to make changes directly in Parameters.md.","category":"page"},{"location":"implementation_details/documentation/#Documentation-from-docstring","page":"Documentation","title":"Documentation from docstring","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The mathematical formulation of the constraints is also automatically generated: constraints.md contains tags to automatically pull a function's docstring to the file constraints_automatically_generated.md. An example of a tag:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"@@add_constraint_nodal_balance!","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"An example for how the docstring looks:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n add_constraint_nodal_balance!(m::Model)\n\nBalance equation for nodes.\n\nIn **SpineOpt**, [node](@ref) is the place where an energy balance is enforced. As universal aggregators,\nthey are the glue that brings all components of the energy system together. An energy balance is created for each [node](@ref) for all `node_stochastic_time_indices`, unless the [balance\\_type](@ref) parameter of the node takes the value [balance\\_type\\_none](@ref balance_type_list) or if the node in question is a member of a node group, for which the [balance\\_type](@ref) is [balance\\_type\\_group](@ref balance_type_list). The parameter [nodal\\_balance\\_sense](@ref) defaults to equality, but can be changed to allow overproduction ([nodal\\_balance\\_sense](@ref) [`>=`](@ref constraint_sense_list)) or underproduction ([nodal\\_balance\\_sense](@ref) [`<=`](@ref constraint_sense_list)).\nThe energy balance is enforced by the following constraint:\n","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"math \\begin{aligned} & v{node\\injection}(n,s,t) \\\n& + \\sum{\\substack{(conn,n',d{in},s,t) \\in connection_flow_indices: \\ d{out} == :to\\node}} v{connection\\flow}(conn,n',d{in},s,t)\\\n& - \\sum{\\substack{(conn,n',d{out},s,t) \\in connection\\flow_indices: \\ d{out} == :from\\node}} v{connection\\flow}(conn,n',d{out},s,t)\\\n& + v{node_slack_pos}(n,s,t) \\\n& - v{node\\slack_neg}(n,s,t) \\\n& {>=,==,<=} \\\n& 0 \\\n& \\forall (n,s,t) \\in node_stochastic_time_indices: \\\n& p{balance\\type}(n) != balance_type_none \\\n& \\nexists ng \\in groups(n) : balance_type_group \\\n\\end{aligned}","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The reason for using the docstring is such that it is easier to update the documentation in the docstring when developing a certain constraint.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The feature is completely optional. To activate the functionality for another file (e.g. objective.md) add tags to that file and then add code similar to this to make.jl.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"mathpath = joinpath(path, \"src\", \"mathematical_formulation\")\ndocstrings = all_docstrings(SpineOpt)\n\nobjective_function_lines = readlines(joinpath(mathpath, \"objective_function.md\"))\nexpand_tags!(objective_function_lines, docstrings)\nopen(joinpath(mathpath, \"objective_function_automatically_generated.md\"), \"w\") do file\n write(file, join(objective_function_lines, \"\\n\"))\nend","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"To deactivate the functionality, just remove the code and replace the tags in your .md file.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"It is also possible to introduce this feature over time. Anytime you want to add the documentation of a constraint to the docstring you need to follow a few steps:","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"For the docstring\nadd @doc raw before the docstring (that allows to write latex in the docstring)\nFor the .md file\ncut the description and mathematical formulation and paste them in the corresponding function's docstring\nadd the tag to pull the above from the docstring","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"An example of both the docstring and the instruction file have already been shown above.","category":"page"},{"location":"implementation_details/documentation/#Drag-and-drop","page":"Documentation","title":"Drag and drop","text":"","category":"section"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"There is also a drag-and-drop feature for select chapters (e.g. the how to section). For those chapters you can simply add your markdown file to the folder of the chapter and it will be automatically added to the documentation. To allow both manually composed chapters and automatically generated chapter, the functionality is only activated for empty chapters (of the structure \"chapter name\" => []).","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"The drag-and-drop function assumes a specific structure for the documentation files.","category":"page"},{"location":"implementation_details/documentation/","page":"Documentation","title":"Documentation","text":"All chapters and corresponding markdownfiles are in the docs/src folder.\nFolder names need to be lowercase with underscores because the automated folder names are derived from the page names in make.jl. A new chapter (e.g. implementation details) needs to follow this structure.\nMarkdown file names can have uppercases and can have underscores but don't need to because the page names in make.jl are derived from the actual file names. In other words, your filename will become the page name in the documentation so make this descriptive.","category":"page"},{"location":"concept_reference/resolution/","page":"-","title":"-","text":"This parameter specifies the resolution of the temporal block, or in other words: the length of the timesteps used in the optimization run. Generally speaking, variables and constraints are generated for each timestep of an optimization. For example, the nodal balance constraint must hold for each timestep.","category":"page"},{"location":"concept_reference/resolution/","page":"-","title":"-","text":"An array of duration values can be used to have a resolution that varies with time itself. It can for example be used when uncertainty in one of the inputs rises as the optimization moves away from the model start. Think of a forecast of for instance wind power generation, which might be available in quarter hourly detail for one day in the future, and in hourly detail for the next two days. It is possible to take a quarter hourly resolution for the full horizon of three days. However, by lowering the temporal resolution after the first day, the computational burden is lowered substantially.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"The definition of the min_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets a lower bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/min_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be above the given value. A possible use case is a minimum value for electricity generated from renewable sources. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"mathematical_formulation/sets/#Sets","page":"Sets","title":"Sets","text":"","category":"section"},{"location":"mathematical_formulation/sets/#ind(*parameter*)","page":"Sets","title":"ind(*parameter*)","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Tuple of all objects, for which the parameter is defined ","category":"page"},{"location":"mathematical_formulation/sets/#t_before_t(t_aftert')","page":"Sets","title":"t_before_t(t_after=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are directly before timeslice t'. ","category":"page"},{"location":"mathematical_formulation/sets/#t_before_t(t_beforet')","page":"Sets","title":"t_before_t(t_before=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are directly after timeslice t'. ","category":"page"},{"location":"mathematical_formulation/sets/#t_in_t(t_shortt')","page":"Sets","title":"t_in_t(t_short=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that contain timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#t_in_t(t_longt')","page":"Sets","title":"t_in_t(t_long=t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that are contained in timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#t_overlaps_t(t')","page":"Sets","title":"t_overlaps_t(t')","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of timeslices that overlap with timeslice t' ","category":"page"},{"location":"mathematical_formulation/sets/#full_stochastic_paths","page":"Sets","title":"full_stochastic_paths","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of all possible scenario branches ","category":"page"},{"location":"mathematical_formulation/sets/#active_stochastic_paths(s)","page":"Sets","title":"active_stochastic_paths(s)","text":"","category":"section"},{"location":"mathematical_formulation/sets/","page":"Sets","title":"Sets","text":"Set of all active scenario branches, based on active scenarios s ","category":"page"},{"location":"mathematical_formulation/variables/#Variables","page":"Variables","title":"Variables","text":"","category":"section"},{"location":"mathematical_formulation/variables/#binary_gas_connection_flow","page":"Variables","title":"binary_gas_connection_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_binary_gas_connection_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: binary_gas_connection_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Binary variable with the indices node n over the connection conn in the direction to_node for the stochastic scenario s at timestep t describing if the direction of gas flow for a pressure drive gastransfer is in the indicated direction. ","category":"page"},{"location":"mathematical_formulation/variables/#connection_flow","page":"Variables","title":"connection_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connection_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connection_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity flow associated with node n over the connection conn in the direction d for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#connection_intact_flow","page":"Variables","title":"connection_intact_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connection_intact_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connection_intact_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"??? ","category":"page"},{"location":"mathematical_formulation/variables/#connections_decommissioned","page":"Variables","title":"connections_decommissioned","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_decommissioned ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of decomissioned connections conn for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#connections_invested","page":"Variables","title":"connections_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of connections conn invested at timestep t in for the stochastic scenario s ","category":"page"},{"location":"mathematical_formulation/variables/#connections_invested_available","page":"Variables","title":"connections_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_connections_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (connection=conn, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: connections_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested connections conn that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#mp_objective_lowerbound_indices","page":"Variables","title":"mp_objective_lowerbound_indices","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_mp_objective_lowerbound_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: mp_objective_lowerbound_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Updating lowerbound for master problem of Benders decomposition ","category":"page"},{"location":"mathematical_formulation/variables/#node_injection","page":"Variables","title":"node_injection","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_injection ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_injection_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity injections at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_pressure","page":"Variables","title":"node_pressure","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_pressure ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_pressure_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Pressue at a node n for a specific stochastic scenario s and timestep t. See also: has_pressure ","category":"page"},{"location":"mathematical_formulation/variables/#node_slack_neg","page":"Variables","title":"node_slack_neg","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_slack_neg ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_slack_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Positive slack variable at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_slack_pos","page":"Variables","title":"node_slack_pos","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_slack_pos ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_slack_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Negative slack variable at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_state","page":"Variables","title":"node_state","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_state ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_state_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Storage state at node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#node_voltage_angle","page":"Variables","title":"node_voltage_angle","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_node_voltage_angle ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: node_voltage_angle_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Voltage angle at a node n for a specific stochastic scenario s and timestep t. See also: has_voltage_angle ","category":"page"},{"location":"mathematical_formulation/variables/#nonspin_units_shut_down","page":"Variables","title":"nonspin_units_shut_down","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_nonspin_units_shut_down ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: nonspin_units_shut_down_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u held available for non-spinning downward reserve provision via shutdown to node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#nonspin_units_started_up","page":"Variables","title":"nonspin_units_started_up","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_nonspin_units_started_up ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: nonspin_units_started_up_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u held available for non-spinning upward reserve provision via startup to node n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#storages_decommissioned","page":"Variables","title":"storages_decommissioned","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_decommissioned ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of decomissioned storage nodes n for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#storages_invested","page":"Variables","title":"storages_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of storage nodes n invested in at timestep t for the stochastic scenario s ","category":"page"},{"location":"mathematical_formulation/variables/#storages_invested_available","page":"Variables","title":"storages_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_storages_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (node=n, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: storages_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested storage nodes n that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow","page":"Variables","title":"unit_flow","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Commodity flow associated with node n over the unit u in the direction d for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow_op","page":"Variables","title":"unit_flow_op","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow_op ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_op_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Contribution of the unit flow assocaited with operating point i ","category":"page"},{"location":"mathematical_formulation/variables/#unit_flow_op_active","page":"Variables","title":"unit_flow_op_active","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_unit_flow_op_active ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, node=n, direction=d, i=i, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: unit_flow_op_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Control the activation of operating point i of units ","category":"page"},{"location":"mathematical_formulation/variables/#units_available","page":"Variables","title":"units_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of available units u for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_invested","page":"Variables","title":"units_invested","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_invested ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s invested in at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_invested_available","page":"Variables","title":"units_invested_available","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_invested_available ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of invested units u that are available still the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_mothballed","page":"Variables","title":"units_mothballed","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_mothballed ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_invested_available_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenariocenario s mothballed at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_on","page":"Variables","title":"units_on","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_on ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of online units u for the stochastic scenario s at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_shut_down","page":"Variables","title":"units_shut_down","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_shut_down ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s that switched to offline status at timestep t ","category":"page"},{"location":"mathematical_formulation/variables/#units_started_up","page":"Variables","title":"units_started_up","text":"","category":"section"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Math symbol: v_units_started_up ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices: (unit=u, stochastic_scenario=s, t=t) ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Indices function: units_on_indices ","category":"page"},{"location":"mathematical_formulation/variables/","page":"Variables","title":"Variables","text":"Number of units u for the stochastic scenario s that switched to online status at timestep t ","category":"page"},{"location":"concept_reference/minimum_reserve_activation_time/","page":"-","title":"-","text":"The parameter minimum_reserve_activation_time is the duration a reserve product needs to be online, before it can be replaced by another (slower) reserve product.","category":"page"},{"location":"concept_reference/minimum_reserve_activation_time/","page":"-","title":"-","text":"In SpineOpt, the parameter is used to model reserve provision through storages. If a storage provides reserves to a reserve node (see also is_reserve_node) one needs to ensure that the node state is sufficiently high to provide these scheduled reserves as least for the duration of the minimum_reserve_activation_time. The constraint on the minimum node state with reserve provision is triggered by the existence of the minimum_reserve_activation_time. See also Reserves","category":"page"},{"location":"concept_reference/fixed_pressure_constant_1/","page":"-","title":"-","text":"For the MILP representation of pressure driven gas transfer, we use an outer approximation approach as described by Schwele et al.. The Weymouth equation is approximated around fixed pressure points, as described by the constraint on fixed node pressure points, constraining the average flow in each direction dependent on the adjacent node pressures. The first fixed pressure constant, which will be multiplied with the pressure of the origin node, is represented by an Array value of the fixed_pressure_constant_1. The second pressure constant corresponds to the related parameter fixed_pressure_constant_0. Note that the fixed_pressure_constant_1 parameter should be defined on a connection__node__node relationship, for which the first node corresponds to the origin node, while the second node corresponds to the destination node. For a typical gas pipeline, the will be a fixed_pressure_constant_1 for both directions of flow.","category":"page"},{"location":"concept_reference/units_invested_avaiable_coefficient/","page":"-","title":"-","text":"The units_invested_available_coefficient is an optional parameter that can be used to include the units_invested_available variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_available_coefficient appears as a coefficient for the units_invested_available variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/fuel_cost/","page":"-","title":"-","text":"By defining the fuel_cost parameter for a specific unit, node, and direction, a cost term will be added to the objective function to account for costs associated with the unit's fuel usage over the course of its operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"online_variable_type is a method parameter to model the 'commitment' or 'activation' of a unit, that is the situation where the unit becomes online and active in the system. It can take the values \"unit_online_variable_type_binary\", \"unit_online_variable_type_integer\", \"unit_online_variable_type_linear\" and \"unit_online_variable_type_none\".","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_binary, then the commitment is modelled as an online/offline decision (classic unit commitment).","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_integer, then the commitment is modelled as the number of units that are online (clustered unit commitment). ","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_linear, then the commitment is modelled as the number of units that are online, but here it is also possible to activate 'fractions' of a unit. This should reduce computational burden compared to unit\\_online\\_variable\\_type\\_integer.","category":"page"},{"location":"concept_reference/online_variable_type/","page":"-","title":"-","text":"If unit\\_online\\_variable\\_type\\_none, then the committment is not modelled at all and the unit is assumed to be always online. This reduces the computational burden the most.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"The stochastic_scenario_end is a Duration-type parameter, defining when a stochastic_scenario ends relative to the start of the current optimization. As it is a parameter for the stochastic_structure__stochastic_scenario relationship, different stochastic_structures can have different values for the same stochastic_scenario, making it possible to define slightly different stochastic_structures using the same stochastic_scenarios. See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"When a stochastic_scenario ends at the point in time defined by the stochastic_scenario_end parameter, it spawns its children according to the parent_stochastic_scenario__child_stochastic_scenario relationship. Note that the children will be inherently assumed to belong to the same stochastic_structure their parent belonged to, even without explicit stochastic_structure__stochastic_scenario relationships! Thus, you might need to define the weight_relative_to_parents parameter for the children.","category":"page"},{"location":"concept_reference/stochastic_scenario_end/","page":"-","title":"-","text":"If no stochastic_scenario_end is defined, the stochastic_scenario is assumed to go on indefinitely.","category":"page"},{"location":"concept_reference/fractional_demand/","page":"-","title":"-","text":"Whenever a node is a member of a group, the fractional_demand parameter represents its share of the group's demand.","category":"page"},{"location":"concept_reference/node/","page":"-","title":"-","text":"The node is perhaps the most important object class out of the Systemic object classes, as it is what connects the rest together via the Systemic relationship classes. Essentially, nodes act as points in the modelled commodity network where commodity balance is enforced via the node balance and node injection constraints, tying together the inputs and outputs from units and connections, as well as any external demand. Furthermore, nodes play a crucial role for defining the temporal and stochastic structures of the model via the node__temporal_block and node__stochastic_structure relationships. For more details about the Temporal Framework and the Stochastic Framework, please refer to the dedicated sections.","category":"page"},{"location":"concept_reference/node/","page":"-","title":"-","text":"Since nodes act as the points where commodity balance is enforced, this also makes them a natural fit for implementing storage. The has_state parameter controls whether a node has a node_state variable, which essentially represents the commodity content of the node. The state_coeff parameter tells how the node_state variable relates to all the commodity flows. Storage losses are handled via the frac_state_loss parameter, and potential diffusion of commodity content to other nodes via the diff_coeff parameter for the node__node relationship.","category":"page"},{"location":"advanced_concepts/ramping/#Ramping","page":"Ramping","title":"Ramping","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"To enable the representation of units with a high level of technical detail, the ramping capability of units can be constrained in SpineOpt. This means that the user has the freedom to impose restrictions on the change in the output (or input) of units over time, for online (spinning) units, units starting up and units shutting down. In this section, the concept of ramps in SpineOpt will be introduced.","category":"page"},{"location":"advanced_concepts/ramping/#Relevant-objects,-relationships-and-parameters","page":"Ramping","title":"Relevant objects, relationships and parameters","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Everything that is related to ramping is defined in parameters of either the unit__to_node or unit__from_node relationship (where the node can be a group). Generally speaking, the ramping constraints will impose restrictions on the change in the unit_flow variable between two consecutive timesteps.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"All parameters that limit the ramping abilities of a unit are expressed as a fraction of the unit capacity. This means that a value of 1 indicates the full capacity of a unit.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The discussion here will be conceptual. For the mathematical formulation the reader is referred to the Ramping constraints","category":"page"},{"location":"advanced_concepts/ramping/#Constraining-spinning-up-and-down-ramps","page":"Ramping","title":"Constraining spinning up and down ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : limit the maximum increase in the unit_flow variable when the unit is online, over a period of time equal to the duration_unit. The parameter is given as a fraction of the unit_capacity. Inclusion of this parameter will trigger the creation of the Constraint on spinning upwards ramp\nramp_down_limit : limit the maximum decrease in the unit_flow variable when the unit is online, over a period of time equal to the duration_unit. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning downward ramps","category":"page"},{"location":"advanced_concepts/ramping/#Constraining-start-up-and-shut-down-ramps","page":"Ramping","title":"Constraining start up and shut down ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"start_up_limit : limit the maximum increase in the unit_flow variable when the unit is starting up. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning upwards ramp\nshut_down_limit : limit the maximum decrease in the unit_flow variable when the unit is shutting down. The parameter is given as a fraction of the unit_capacity parameter. Inclusion of this parameter will trigger the creation of the Constraint on spinning downward ramps","category":"page"},{"location":"advanced_concepts/ramping/#General-principle-and-example-use-cases","page":"Ramping","title":"General principle and example use cases","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The general principle of the Spine modelling ramping constraints is that all of these parameters can be defined separately for each unit. This allows the user to incorporate different units (which can either represent a single unit or a technology type) with different flexibility characteristics.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"It should be noted that it is perfectly possible to omit all of the ramp constraining parameters mentioned above, or to specify only some of them. Anything that is omitted is interpreted as if it shouldn't be constrained. For example, if you only specify start_up_limit and ramp_down_limit, then only the flow increase during start up and the flow decrease during online operation will be constrained (but not any other flow increase or decrease).","category":"page"},{"location":"advanced_concepts/ramping/#Illustrative-examples","page":"Ramping","title":"Illustrative examples","text":"","category":"section"},{"location":"advanced_concepts/ramping/#Step-1:-Simple-case-of-unrestricted-unit","page":"Ramping","title":"Step 1: Simple case of unrestricted unit","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When none of the ramping parameters mentioned above are specified, the unit is considered to have full ramping flexibility. This means that over any period of time, its flow can be any value between 0 and its capacity, regardless of what the flow of the unit was in previous timesteps, and regardless of the on- or offline status of the unit in previous timesteps (while still respecting, of course, the Unit commitment restrictions that are defined for this unit). This is equivalent to specifying the following:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"shut_down_limit : 1\nstart_up_limit : 1\nramp_up_limit : 1\nramp_down_limit : 1","category":"page"},{"location":"advanced_concepts/ramping/#Step-2:-Spinning-ramp-restriction","page":"Ramping","title":"Step 2: Spinning ramp restriction","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"A unit which is only restricted in spinning ramping can be created by changing the ramp_up/down_limit parameters:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.2\nramp_down_limit : 0.4","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"This parameter choice implies that the unit flow cannot increase more than 02 * 200 and cannot decrease more than 04 * 200 over a period of time equal to 'one' duration_unit. For example, when the unit is running at an output of 100 in some timestep t, its output for the next 'one' duration_unit must be somewhere in the interval 20 140 - unless it shuts down completely.","category":"page"},{"location":"advanced_concepts/ramping/#Step-3:-Shutdown-restrictions","page":"Ramping","title":"Step 3: Shutdown restrictions","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"By specifying the parameter shut_down_limit, an additional restriction is imposed on the maximum flow of the unit at the moment it goes offline:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"shut_down_limit : 0.5\nminimum_operating_point : 0.3","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When the unit goes offline in a given timestep t, the output of the unit must be below 05 * 200 = 100 in the timestep right before that t (and of course, above 03 * 200 = 60 - the minimum operating point).","category":"page"},{"location":"advanced_concepts/ramping/#Step-4:-Startup-restrictions","page":"Ramping","title":"Step 4: Startup restrictions","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The start up restrictions are very similar to the shut down restrictions, but of course apply to units that are starting up. THey are activated by specifying start_up_limit:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"start_up_limit : 0.4\nminimum_operating_point : 0.2","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"When the unit goes online in a given timestep t, its output will be restricted to the interval 40 80.","category":"page"},{"location":"advanced_concepts/ramping/#Using-node-groups-to-constraint-aggregated-flow-ramps","page":"Ramping","title":"Using node groups to constraint aggregated flow ramps","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"SpineOpt allows the user to constrain ramping abilities of units that are linked to multiple nodes by defining node groups. When a node group is defined, ramping restrictions can be imposed both on the group level (thus for the unit as a whole) as well as for the individual nodes. For example, let's assume that we have one unit and two nodes in a model. The unit is linked via unit__to_node relationships to each node individually, and on top of that, it is linked to a node group containing both nodes.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"If, for example a ramp_up_limit is defined for the node group, the sum of upward ramping of the two nodes will be restricted by this parameter. However, it is still possible to limit the individual flows to the nodes as well. Let's say that our unit is capable of ramping up by 20% of its capacity and down by 40%. We might want to impose tighter restrictions for the flows towards one of the nodes (e.g. because the energy has to be provided in a shorter time than the duration_unit). One can then simply define an additional parameter for that unit__to_node relationship as follows.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.15","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Which now restricts the flow of the unit into that node to 15% of its capacity.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Please note that by default, node groups are balanced in the same way as individual nodes. So if you're using node groups for the sole purpose of constraining flow ramps, you should set the balance type of the group to balance_type_none.","category":"page"},{"location":"advanced_concepts/ramping/#Ramping-with-reserves","page":"Ramping","title":"Ramping with reserves","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"If a unit is set to provide reserves, then it should be able to provide that reserve within one duration_unit. For this reason, reserve provision must be accounted for within ramp constraints. Please see Reserves for details on how to setup a node as a reserve.","category":"page"},{"location":"advanced_concepts/ramping/#Examples","page":"Ramping","title":"Examples","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"Let's assume that we have one unit and two nodes in a model, one for reserves and one for regular demand. The unit is then linked by the unit__to_node relationships to both the reserves and regular demand node.","category":"page"},{"location":"advanced_concepts/ramping/#Spinning-ramp-restriction","page":"Ramping","title":"Spinning ramp restriction","text":"","category":"section"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"The unit can be restricted in spinning ramping by defining the ramp_up/down_limit parameters in the unit__to_node relationship for the regular demand node:","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"ramp_up_limit : 0.2\nramp_down_limit : 0.4","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"This parameter choice implies that the unit's flow to the regular demand node cannot increase more than 02 * 200 - upward_reserve_demand or decrease more than 04 * 200 - downward_reserve_demand over one duration_unit. For example, when the unit is running at an output of 100 and there is an upward reserve demand of 10, then its output over the next duration_unit must be somewhere in the interval 20 130.","category":"page"},{"location":"advanced_concepts/ramping/","page":"Ramping","title":"Ramping","text":"It can be seen in this example that the demand for reserves is subtracted from the ramping capacity of the unit that is available for regular operation. This stems from the fact that in providing reserve capacity, the unit is expected to be able to provide the demanded reserve within one duration_unit as stated above.","category":"page"},{"location":"getting_started/output_data/#Managing-Output-Data","page":"Managing Outputs","title":"Managing Output Data","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Once a model is created and successfully run, it will hopefully produce results and output data. This section covers how the writing of output data is controlled and managed.","category":"page"},{"location":"getting_started/output_data/#Specifying-Your-Output-Data-Store","page":"Managing Outputs","title":"Specifying Your Output Data Store","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In your workflow (for more details see Setting up a workflow for SpineOpt in Spine Toolbox) you will normally have a output datastore connected to your RunSpineOpt workflow tool. This is where your output data will be written. If no output datastore is specified, the results will be written by default to the input datastore. However, it is generally preferable to define a separate output data store for results. See Setting up a workflow for SpineOpt in Spine Toolbox for the steps to add an output datastore to your workflow)","category":"page"},{"location":"getting_started/output_data/#Specifying-Outputs-to-Write","page":"Managing Outputs","title":"Specifying Outputs to Write","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Outputting of results to the output datastore is controlled using the output and report object classes. To output a specific variable to the output datastore, we need to create an output object of the same name. For example, to output the unit_flow variable, we must create an output object named unit_flow. The SpineOpt template contains output objects for most problem variables and importing or re-importing the SpineOpt template will add these to your input datastore. So it is probable these output objects will exist already in your input datastore. Once the output objects exist in your model, they must then be added to a report object by creating an report__output relationship","category":"page"},{"location":"getting_started/output_data/#Creating-Reports","page":"Managing Outputs","title":"Creating Reports","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Reports are essentially a collection of outputs that can be written to an output datastore. Any number of report objects can be created. We add output items to a report by creating report__output relationships between the output objects we want included and the desired report object. Finally, to write a specic report to the output database, we must create a model__report relationship for each report object we want included in the output datastore.","category":"page"},{"location":"getting_started/output_data/#Reporting-of-Input-Parameters","page":"Managing Outputs","title":"Reporting of Input Parameters","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In addition to writing results as outputs to a datastore, SpineOpt can also report input parameter data. To allow specific input parameters to be included in a report, they must be first added as output objects with a name corresponding exactly to the parameter name. For example, to allow the demand parameter to be included in a report, there must be a correspondingly named output object called demand. Similarly to outputs, to include an input parameter in a report, we must create a report__output relationship between the output object representing the input parameter (e.g. demand) and the desired report object.","category":"page"},{"location":"getting_started/output_data/#Reporting-of-Dual-Values","page":"Managing Outputs","title":"Reporting of Dual Values","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's marginal value to be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with constraint_ to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called constraint_units_available.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To report the reduced_cost() for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by bound_. So, to report the unitson reducedcost value, one would create an output item called bound_units_on. If added to a report, this will cause the reduced cost of unitson in the final fixed LP to be written to the output db. Finally, if any constraint duals or reducedcost values are requested via a report, calculate_duals is set to true and the final fixed LP solve is triggered.","category":"page"},{"location":"getting_started/output_data/#Output-Data-Temporal-Resolution","page":"Managing Outputs","title":"Output Data Temporal Resolution","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To control the resolution of report data (both output data and input data appearing in reports), we use the output_resolution output parameter. For the specific output (or input), this indicates the resolution at which the values should be reported. If output_resolution is null (the default), results are reported at the highest available resolution that will follow from the temporal structure of the model. If output_resolution is a duration value, then the average value is reported. ","category":"page"},{"location":"getting_started/output_data/#Output-Data-Structure","page":"Managing Outputs","title":"Output Data Structure","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"The structure of the output data will follow the structure of the input data with the inclusion of additional dimensions as described below:","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"The report object to which the output data items belong will be added as a dimension\nThe relevant stochastic scenario will be added as a dimension to all output data items. This allows for stochastic data to be written to the output datastore. However, in deterministic models, the single deterministic scenario will still appear as an additional dimension\nFor unit flows, the flow direction is added as a dimension to the output. ","category":"page"},{"location":"getting_started/output_data/#Example:-unit_flow","page":"Managing Outputs","title":"Example: unit_flow","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"For example, consider the unit_flow) optimisation variable. This variable is dimensioned on the unit__to_node and unit__from_node relationships. In the output datastore, the report, stochastic_scenario and flow direction are added as additional dimensions. Therefore, unit__to_node values will appear in the output datastore as timeseries parameters associated with the report__unit__node__direction__stochastic_scenario relationship as shown below.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To view the data, simply double-click on the timeseries value","category":"page"},{"location":"getting_started/output_data/#Example:-units_on","page":"Managing Outputs","title":"Example: units_on","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"Consider the units_on) optimisation variable. This variable is dimensioned on the unit object class. In the output datastore, the report and stochastic_scenario are added as additional dimensions. Therefore, units_on values will appear in the output datastore as timeseries parameters associated with the report__unit__stochastic_scenario relationship as shown below.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"To view the data, simply double-click on the timeseries value","category":"page"},{"location":"getting_started/output_data/#Alternatives-and-Multiple-Model-Runs","page":"Managing Outputs","title":"Alternatives and Multiple Model Runs","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"All outputs from a single run of a model will be tagged with a unique \"alternative\". Alternatives allow multiple values to be specified for the same parameter. If a model is run multiple times, the results will be appended to the output datastore with a new alternative which uniquely identifies the scenario and model run. This is convenient as it allows results from multiple runs and for multiple scenarios to be viewed and compared simultaneously. If a specific altnernative is not selected (the default condition) the results for all alternatives will be visible. If a single altnerative is selected or multiple alternatives are selected in the altnerative tree, then only the results for the selected alternatives will be shown. ","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"In the example below, the relationship class report__unit__stochastic_scenario is selected in the relationship treem therefore results for that relationship class are showing in the relationship parameter pane. Furthermore, in the alternative tree, the alternative 10h TP Load _Reun SpineOpt... is selected, meaning only results for that alternative are being displayed.","category":"page"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"(Image: image)","category":"page"},{"location":"getting_started/output_data/#Output-Writing-Summary","page":"Managing Outputs","title":"Output Writing Summary","text":"","category":"section"},{"location":"getting_started/output_data/","page":"Managing Outputs","title":"Managing Outputs","text":"We need an output object in our intput datastore for each variable or marginal value we want included in a report\nInputs data can also be reported. As above, we need to create an output object named after the input parameter we want reported \nWe need to create a report object to contain our desired outputs (or input parameters) which are added to our report via report__output relationships\nWe need to create a model__report object to write a specific report to the output datastore.\nThe temporal resolution of outputs (which may also be input parameters) is controlled by the output_resolution output duration parameter. If null, the highest available resolution is reported, otherwise the average is reported over the desired duration. \nAdditional dimensions are added to the output data such as the report object, stochastic_scenario and, in the case of unit_flow, the flow direction. \nModel outputs are tagged with altnernatives that are unique to the model run and scenario that generated them","category":"page"},{"location":"concept_reference/fix_connection_intact_flow/","page":"-","title":"-","text":"The fix_connection_intact_flow parameter can be used to fix the values of the connection_intact_flow variable to preset values. If set to a Scalar type value, the connection_intact_flow variable is fixed to that value for all time steps and stochastic_scenarios. Values for individual time steps can be fixed using TimeSeries type values.","category":"page"},{"location":"concept_reference/start_up_limit/","page":"-","title":"-","text":"The definition of the start_up_limit parameter sets an upper bound on the unit_flow variable for the timestep right after a startup.","category":"page"},{"location":"concept_reference/start_up_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/node__investment_stochastic_structure/","page":"-","title":"-","text":"The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.","category":"page"},{"location":"concept_reference/node__investment_stochastic_structure/","page":"-","title":"-","text":"The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"The definition of the min_up_time parameter will trigger the creation of the Constraint on minimum up time. It sets a lower bound on the period that a unit has to stay online after a startup.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"It can be defined for a unit and will then impose restrictions on the units_on variables that represent the on- or offline status of the unit. The parameter is given as a duration value. When the parameter is not included, the aforementioned constraint will not be created, which is equivalent to choosing a value of 0.","category":"page"},{"location":"concept_reference/min_up_time/","page":"-","title":"-","text":"For a more complete description of unit commmitment restrictions, see Unit commitment.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"Within an investments problem candidate_units determines the upper bound on the unit investment decision variable in constraint units_invested_available. In constraint unit_flow_capacity the maximum unit_flow will be the product of the units_invested_available and the corresponding unit_capacity. Thus, the interpretation of candidate_units depends on unit_investment_variable_type which determines the unit investment decision variable type. If unit_investment_variable_type is integer or binary, then candidate_units represents the maximum number of discrete units that may be invested in. If unit_investment_variable_type is continuous, candidate_units is more analagous to a maximum storage capacity.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"Note that candidate_units is the main investment switch and setting a value other than none/nothing triggers the creation of the investment variable for the unit. Note that a value of zero will still trigger the variable creation but its value will be fixed to zero. This can be useful if an inspection of the related dual variables will yield the value of this resource.","category":"page"},{"location":"concept_reference/candidate_units/","page":"-","title":"-","text":"See also Investment Optimization and unit_investment_variable_type","category":"page"},{"location":"getting_started/installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"getting_started/installation/#Compatibility","page":"Installation","title":"Compatibility","text":"","category":"section"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"This package requires Julia 1.2 or later.","category":"page"},{"location":"getting_started/installation/#Installation-2","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"If you haven't yet installed the tools yet, please follow the installation guides: ","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For Spine Toolbox: https://github.com/spine-tools/SpineOpt.jl#installation\nFor SpineOpt: https://github.com/spine-tools/Spine-Toolbox#installation","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For Spine Toolbox:","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"- If installed with pipx, then use `python -m pipx upgrade spinetoolbox`\n- If installed from sources using git, then
\n `git pull`
\n\t`python -m pip install -U -r requirements.txt`
","category":"page"},{"location":"getting_started/installation/","page":"Installation","title":"Installation","text":"For SpineOpt: https://github.com/spine-tools/SpineOpt.jl#upgrading","category":"page"},{"location":"concept_reference/variable_type_list/","page":"-","title":"-","text":"The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.","category":"page"},{"location":"concept_reference/fom_cost/","page":"-","title":"-","text":"By defining the fom_cost parameter for a specific unit, a cost term will be added to the objective function to account for the fixed operation and maintenance costs associated with that unit during the current optimization window. fom_cost differs from units_on_cost in a way that the fixed operation and maintenance costs apply to both the online and offline unit.","category":"page"},{"location":"concept_reference/ordered_unit_flow_op/","page":"-","title":"-","text":"If one defines the parameter ordered_unit_flow_op in a unit__from_node or unit__to_node relationship, SpineOpt will create variable unit_flow_op_active to order each unit_flow_op of the unit_flow according to the rank of defined operating_points. This setting is only necessary when the segmental unit_flow_ops are with increasing conversion efficiency. The numerical type of unit_flow_op_active (float, binary, or integer) follows that of variable units_on which can be set via parameter online_variable_type.","category":"page"},{"location":"concept_reference/ordered_unit_flow_op/","page":"-","title":"-","text":"Note that this functionality is based on SOS2 constraints so only a MILP configuration, i.e. make variable unit_flow_op_active a binary or integer, guarantees correct performance.","category":"page"},{"location":"concept_reference/reserve_procurement_cost/","page":"-","title":"-","text":"By defining the reserve_procurement_cost parameter for a specific unit__to_node or unit__from_node relationship, a cost term will be added to the objective function whenever that unit is used over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/max_ratio_out_in_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_in_unit_flow parameter triggers the generation of the constraint_max_ratio_out_in_unit_flow and enforces an upper bound on the ratio between outgoing and incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the unit, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 0.8 for a unit u between its outgoing flows to the node group el_heat (consisting of the two nodes el and heat) and its incoming gas flow from ng the max_ratio_out_in_unit_flow parameter would be set to 0.8 for the relationship u__el_heat__ng.","category":"page"},{"location":"concept_reference/connection__investment_temporal_block/","page":"-","title":"-","text":"connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.","category":"page"},{"location":"concept_reference/connection__investment_temporal_block/","page":"-","title":"-","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/node_state_coefficient/","page":"-","title":"-","text":"The node_state_coefficient is an optional parameter that can be used to include the node_state variable of a node in a user_constraint via the node__user_constraint relationship. Essentially, node_state_coefficient appears as a coefficient for the node_state variable of the node in the user constraint.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#Parameter-Value-Lists","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/#balance_type_list","page":"Parameter Value Lists","title":"balance_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: balance_type_group, balance_type_node and balance_type_none ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The balance_type_list parameter value list contains the possible values for the balance_type parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#boolean_value_list","page":"Parameter Value Lists","title":"boolean_value_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: false and true ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"A list of boolean values (True or False).","category":"page"},{"location":"concept_reference/Parameter Value Lists/#commodity_physics_list","page":"Parameter Value Lists","title":"commodity_physics_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: commodity_physics_lodf, commodity_physics_none and commodity_physics_ptdf ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"commodity_physics_list holds the possible values for the commodity parameter commodity_physics parameter. See commodity_physics for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#connection_investment_variable_type_list","page":"Parameter Value Lists","title":"connection_investment_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: connection_investment_variable_type_continuous and connection_investment_variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#connection_type_list","page":"Parameter Value Lists","title":"connection_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: connection_type_lossless_bidirectional and connection_type_normal ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"connection_type_list holds the possible values for the connection_type parameter. See connection_type for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#constraint_sense_list","page":"Parameter Value Lists","title":"constraint_sense_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: <=, == and >= ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#db_lp_solver_list","page":"Parameter Value Lists","title":"db_lp_solver_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: CDCS.jl, CDDLib.jl, COSMO.jl, CPLEX.jl, CSDP.jl, Clp.jl, ECOS.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Hypatia.jl, Ipopt.jl, KNITRO.jl, MadNLP.jl, MosekTools.jl, NLopt.jl, OSQP.jl, ProxSDP.jl, SCIP.jl, SCS.jl, SDPA.jl, SDPNAL.jl, SDPT3.jl, SeDuMi.jl and Xpress.jl ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#db_mip_solver_list","page":"Parameter Value Lists","title":"db_mip_solver_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: CPLEX.jl, Cbc.jl, GLPK.jl, Gurobi.jl, HiGHS.jl, Juniper.jl, KNITRO.jl, MosekTools.jl, SCIP.jl and Xpress.jl ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#duration_unit_list","page":"Parameter Value Lists","title":"duration_unit_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: hour and minute ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The duration_unit_list parameter value list contains the possible values for the duration_unit parameter.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#model_type_list","page":"Parameter Value Lists","title":"model_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: spineopt_benders, spineopt_mga, spineopt_other and spineopt_standard ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"model_type_list holds the possible values for the model parameter model_type parameter. See model_type for more details","category":"page"},{"location":"concept_reference/Parameter Value Lists/#node_opf_type_list","page":"Parameter Value Lists","title":"node_opf_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: node_opf_type_normal and node_opf_type_reference ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"See also powerflow.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#unit_investment_variable_type_list","page":"Parameter Value Lists","title":"unit_investment_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: unit_investment_variable_type_continuous and unit_investment_variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#unit_online_variable_type_list","page":"Parameter Value Lists","title":"unit_online_variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: unit_online_variable_type_binary, unit_online_variable_type_integer, unit_online_variable_type_linear and unit_online_variable_type_none ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"unit_online_variable_type_list holds the possible values for the type of a unit's commitment status variable which may be chosen from binary, integer, or linear. ","category":"page"},{"location":"concept_reference/Parameter Value Lists/#variable_type_list","page":"Parameter Value Lists","title":"variable_type_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: variable_type_binary, variable_type_continuous and variable_type_integer ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"The variable_type_list parameter value list contains the possible values for the connection_investment_variable_type and storage_investment_variable_type parameters.","category":"page"},{"location":"concept_reference/Parameter Value Lists/#write_mps_file_list","page":"Parameter Value Lists","title":"write_mps_file_list","text":"","category":"section"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Possible values: write_mps_always, write_mps_never and write_mps_on_no_solve ","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"This parameter value list is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/Parameter Value Lists/","page":"Parameter Value Lists","title":"Parameter Value Lists","text":"Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\\_mps\\_on\\_no\\_solve, and write\\_mps\\_never.","category":"page"},{"location":"concept_reference/max_mga_iterations/","page":"-","title":"-","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_iterations defines how many MGA iterations will be performed, i.e. how many near-optimal solutions will be generated.","category":"page"},{"location":"concept_reference/has_pressure/","page":"-","title":"-","text":"If a node is to represent a node in a pressure driven gas network, the boolean parameter has_pressure should be set true, in order to trigger the generation of the node_pressure variable. The pressure at a certain node can also be constrainted through the parameters max_node_pressure and min_node_pressure. More details on the use of pressure driven gas transfer are described here","category":"page"},{"location":"concept_reference/node_opf_type_list/","page":"-","title":"-","text":"Houses the different possible values for the node_opf_type parameter. To identify the reference node, set node_opf_type = :node_opf_type_reference, while node_opf_type = node_opf_type_normal is the default value for non-reference nodes.","category":"page"},{"location":"concept_reference/node_opf_type_list/","page":"-","title":"-","text":"See also powerflow.","category":"page"},{"location":"concept_reference/units_invested_big_m_mga/","page":"-","title":"-","text":"The units_invested_big_m_mga parameter is used in combination with the MGA algorithm (see mga-advanced). It defines an upper bound on the maximum difference between any MGA iteration. The big M should be chosen always sufficiently large. (Typically, a value equivalent to candidate_units could suffice.)","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_in/","page":"-","title":"-","text":"The max_units_on_coefficient_in_in parameter is an optional coefficient in the unit input-input ratio constraint controlled by the max_ratio_in_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the maximum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/max_units_on_coefficient_in_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, and max_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting minimum or fixed conversion rates, e.g. min_units_on_coefficient_in_in and fix_units_on_coefficient_in_in.","category":"page"},{"location":"concept_reference/units_invested_coefficient/","page":"-","title":"-","text":"The units_invested_coefficient is an optional parameter that can be used to include the units_invested variable in a user_constraint via the unit__user_constraint relationship. Essentially, units_invested_coefficient appears as a coefficient for the units_invested variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/unit_start_flow/","page":"-","title":"-","text":"Used to implement unit startup fuel consumption where node 1 is assumed to be input fuel and node 2 is assumed to be output elecrical energy. This is a flow from node 1 that is incurred when the value of the variable unitsstartedup is 1 in the corresponding time period. This flow does not result in additional output flow at node 2. Used in conjunction with unit_incremental_heat_rate. unit_start_flow is only currently considered if unit_incremental_heat_rate is specified. A trivial unit_incremental_heat_rate of zero can be defined if there is no incremental heat rate.","category":"page"},{"location":"concept_reference/connection_investment_variable_type_list/","page":"-","title":"-","text":"The connection_investment_variable_type_list holds the possible values for the type of a connection's investment variable which may be chosen between integer or continuous. ","category":"page"},{"location":"concept_reference/balance_type_list/","page":"-","title":"-","text":"The balance_type_list parameter value list contains the possible values for the balance_type parameter.","category":"page"},{"location":"concept_reference/connection_reactance/","page":"-","title":"-","text":"The per unit reactance of a transmission line. Used in ptdf based dc load flow where the relative reactances of lines determine the ptdfs of the network and in lossless dc powerflow where the flow on a line is given by flow = 1/x(theta_to-theta_from) where x is the reatance of the line, thetato is the voltage angle of the remote node and thetafrom is the voltage angle of the sending node. ","category":"page"},{"location":"concept_reference/fix_node_pressure/","page":"-","title":"-","text":"In a pressure driven gas model, gas network nodes are associated with the node_pressure variable. In order to fix the pressure at a certain node or to give intial conditions the fix_node_pressure parameter can be used.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_out_in_connection_flow parameter triggers the generation of the constraint_fix_ratio_out_in_connection_flow and fixes the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. In most cases the fix_ratio_out_in_connection_flow parameter is set to equal or lower than 1, linking the flows entering to the flows leaving the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right order. The parameter can be used to e.g. account for losses over a connection in a certain direction.","category":"page"},{"location":"concept_reference/fix_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 0.8 for a connection conn between its outgoing electricity flow to node el1 and its incoming flows from the node node el2, the fix_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship u__el1__el2.","category":"page"},{"location":"concept_reference/units_invested_mga/","page":"-","title":"-","text":"The units_invested_mga is a boolean parameter that can be used in combination with the MGA algorithm (see mga-advanced). As soon as the value of units_invested_mga is set to true, investment decisions in this connection, or group of units, will be included in the MGA algorithm.","category":"page"},{"location":"concept_reference/shut_down_limit/","page":"-","title":"-","text":"The definition of the shut_down_limit parameter sets an upper bound on the unit_flow variable for the timestep right before a shutdown.","category":"page"},{"location":"concept_reference/shut_down_limit/","page":"-","title":"-","text":"It can be defined for unit__to_node or unit__from_node relationships, as well as their counterparts for node groups. It will then impose restrictions on the unit_flow variables that indicate flows between the two members of the relationship for which the parameter is defined. The parameter is given as a fraction of the unit_capacity parameter. When the parameter is not specified the limit will not be imposed, which is equivalent to choosing a value of 1.","category":"page"},{"location":"concept_reference/Relationship Classes/#Relationship-Classes","page":"Relationship Classes","title":"Relationship Classes","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/#connection__from_node","page":"Relationship Classes","title":"connection__from_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the connection can take input from, and holds most connection_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__from_node is a two-dimensional relationship between a connection and a node and implies a connection_flow to the connection from the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:from_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__from_node__investment_group","page":"Relationship Classes","title":"connection__from_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which connection capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__from_node__user_constraint","page":"Relationship Classes","title":"connection__from_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_group","page":"Relationship Classes","title":"connection__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a connection belongs in an investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and investment_group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_stochastic_structure","page":"Relationship Classes","title":"connection__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the stochastic structure of the connections investments variable","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The connection__investment_stochastic_structure relationship defines the stochastic_structure of connection-related investment decisions. Essentially, it sets the stochastic_structure used by the connections_invested_available variable of the connection.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The connection__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__investment_temporal_block","page":"Relationship Classes","title":"connection__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the temporal resolution of the connections investments variable","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__investment_temporal_block is a two-dimensional relationship between a connection and a temporal_block. This relationship defines the temporal resolution and scope of a connection's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no connection__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if connection__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified connection.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__node__node","page":"Relationship Classes","title":"connection__node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters spanning multiple connection_flow variables to and from multiple nodes.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: compression_factor, connection_flow_delay, connection_linepack_constant, fix_ratio_out_in_connection_flow, fixed_pressure_constant_0, fixed_pressure_constant_1, max_ratio_out_in_connection_flow and min_ratio_out_in_connection_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node","page":"Relationship Classes","title":"connection__to_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the connection can output to, and holds most connection_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_capacity, connection_conv_cap_to_flow, connection_emergency_capacity, connection_flow_cost, connection_flow_non_anticipativity_margin, connection_flow_non_anticipativity_time, connection_intact_flow_non_anticipativity_margin, connection_intact_flow_non_anticipativity_time, fix_binary_gas_connection_flow, fix_connection_flow, fix_connection_intact_flow, graph_view_position, initial_binary_gas_connection_flow, initial_connection_flow and initial_connection_intact_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node__investment_group","page":"Relationship Classes","title":"connection__to_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which connection capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__to_node__user_constraint","page":"Relationship Classes","title":"connection__to_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"when specified this relationship allows the relevant flow connection flow variable to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection, node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connection_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#connection__user_constraint","page":"Relationship Classes","title":"connection__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Relationship required to involve a connections investment variables in a user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: connection and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: connections_invested_available_coefficient and connections_invested_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_investment_stochastic_structure","page":"Relationship Classes","title":"model__default_investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default stochastic structure used for investment variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_investment_stochastic_structure relationship can be used to set model-wide default unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific unit__investment_stochastic_structure, connection__investment_stochastic_structure, and node__investment_stochastic_structure relationships take priority over the model__default_investment_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_investment_temporal_block","page":"Relationship Classes","title":"model__default_investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default temporal block used for investment variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"model__default_investment_temporal_block is a two-dimensional relationship between a model and a temporal_block. This relationship defines the default temporal resolution and scope for all investment decisions in the model (units, connections and storages). Specifying model__default_investment_temporal_block for a model avoids the need to specify individual node__investment_temporal_block, unit__investment_temporal_block and connection__investment_temporal_block relationships. Conversely, if any of these individual relationships are defined (e.g. connection__investment_temporal_block) along with model__temporal_block, these will override model__default_investment_temporal_block.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_stochastic_structure","page":"Relationship Classes","title":"model__default_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default stochastic structure used for model variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__default_temporal_block","page":"Relationship Classes","title":"model__default_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the default temporal block used for model variables, which will be replaced by more specific definitions","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__report","page":"Relationship Classes","title":"model__report","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Determines which reports are written for each model and in turn, which outputs are written for each model","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and report","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__report relationship tells which reports are written by which model, where the contents of the reports are defined separately using the report__output relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/Relationship Classes/#model__stochastic_structure","page":"Relationship Classes","title":"model__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which stochastic_structures are included in which models.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.","category":"page"},{"location":"concept_reference/Relationship Classes/#model__temporal_block","page":"Relationship Classes","title":"model__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which temporal_blocks are included in which models.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: model and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__commodity","page":"Relationship Classes","title":"node__commodity","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Define a commodity for a node. Only a single commodity is permitted per node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: commodity and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__commodity is a two-dimensional relationship between a node and a commodity and specifies the commodity that flows to or from the node. Generally, since flows are not dimensioned by commodity, this has no meaning in terms of the variables and constraint equations. However, there are two specific uses for this relationship:","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To specify that specific network physics should apply to the network formed by the member nodes for that commodity. See powerflow\nOnly connection flows that are between nodes of the same or no commodity are included in the node_balance constraint.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_group","page":"Relationship Classes","title":"node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a node belongs in a investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group and node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_stochastic_structure","page":"Relationship Classes","title":"node__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"defines the stochastic structure for node related investments, currently only storages","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__investment_stochastic_structure relationship defines the stochastic_structure of node-related investment decisions. Essentially, it sets the stochastic_structure used by the storages_invested_available variable of the node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__investment_temporal_block","page":"Relationship Classes","title":"node__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"defines the temporal resolution for node related investments, currently only storages","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__investment_temporal_block is a two-dimensional relationship between a node and a temporal_block. This relationship defines the temporal resolution and scope of a node's investment decisions (currently only storage invesments). Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no node__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if node__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#node__node","page":"Relationship Classes","title":"node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters for direct interactions between two nodes, e.g. node_state diffusion coefficients.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: diff_coeff","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__node relationship is used for defining direct interactions between two nodes, like diffusion of commodity content. Note that the node__node relationship is assumed to be one-directional, meaning that","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"node__node(node1=n1, node2=n2) != node__node(node1=n2, node2=n1).","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Thus, when one wants to define symmetric relationships between two nodes, one needs to define both directions as separate relationships.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__stochastic_structure","page":"Relationship Classes","title":"node__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific stochastic_structure is used by the node and all flow variables associated with it. Only one stochastic_structure is permitted per node.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__stochastic_structure relationship defines which stochastic_structure the node uses. Essentially, it sets the stochastic_structure of all the flow variables connected to the node, as well as the potential node_state variable. Note that only one stochastic_structure can be defined per node per model, as interpreted based on the node__stochastic_structure and model__stochastic_structure relationships. Investment variables use dedicated relationships, as detailed in the Investment Optimization section.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The node__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__temporal_block","page":"Relationship Classes","title":"node__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the temporal_blocks used by the node and all the flow variables associated with it.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: cyclic_condition and is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"This relationship links a node to a temporal_block and as such it will determine which temporal block governs the temporal horizon and resolution of the variables associated with this node. Specifically, the resolution of the temporal block will directly imply the duration of the time slices for which both the flow variables and their associated constraints are created.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"For a more detailed description of how the temporal structure in SpineOpt can be created, see Temporal Framework.","category":"page"},{"location":"concept_reference/Relationship Classes/#node__user_constraint","page":"Relationship Classes","title":"node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"specifying this relationship allows a node's demand or node_state to be included in the specified user constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: demand_coefficient, node_state_coefficient, storages_invested_available_coefficient and storages_invested_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#parent_stochastic_scenario__child_stochastic_scenario","page":"Relationship Classes","title":"parent_stochastic_scenario__child_stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the master stochastic direct acyclic graph, meaning how the stochastic_scenarios are related to each other.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_scenario","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.","category":"page"},{"location":"concept_reference/Relationship Classes/#report__output","page":"Relationship Classes","title":"report__output","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Output object related to a report object are returned to the output database (if they appear in the model as variables)","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: output and report","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: overwrite_results_on_rolling","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The report__output relationship tells which output variables to include in which report when writing SpineOpt output. Note that the reports also need to be connected to a model using the model__report relationship. Without appropriately defined model__report and report__output and relationships, SpineOpt doesn't write any output, so be sure to include at least one report connected to all the output variables of interest in the model!","category":"page"},{"location":"concept_reference/Relationship Classes/#stochastic_structure__stochastic_scenario","page":"Relationship Classes","title":"stochastic_structure__stochastic_scenario","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which stochastic_scenarios are included in which stochastic_structure, and holds the parameters required for realizing the structure in combination with the temporal_blocks.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_scenario and stochastic_structure","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: stochastic_scenario_end and weight_relative_to_parents","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__commodity","page":"Relationship Classes","title":"unit__commodity","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters for commodities used by the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: commodity and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: max_cum_in_unit_flow_bound","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node","page":"Relationship Classes","title":"unit__from_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the unit can take input from, and holds most unit_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_from_node, min_total_cumulated_unit_flow_from_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Various parameters can be defined on the unit__from_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To associate costs with a certain commodity flows, cost terms, such as fuel_costs and vom_costs, can be included for the unit__from_node relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"It is important to note, that the parameters associated with the unit__from_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node__investment_group","page":"Relationship Classes","title":"unit__from_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which unit capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group, node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__from_node__user_constraint","page":"Relationship Classes","title":"unit__from_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which input unit_flows are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node, unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: graph_view_position and unit_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_group","page":"Relationship Classes","title":"unit__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates that a unit belongs in an investment_group.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_stochastic_structure","page":"Relationship Classes","title":"unit__investment_stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Sets the stochastic structure for investment decisions - overrides model__default_investment_stochastic_structure.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_structure and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__investment_temporal_block","page":"Relationship Classes","title":"unit__investment_temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Sets the temporal resolution of investment decisions - overrides model__default_investment_temporal_block","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: temporal_block and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"unit__investment_temporal_block is a two-dimensional relationship between a unit and a temporal_block. This relationship defines the temporal resolution and scope of a unit's investment decision. Note that in a decomposed investments problem with two model objects, one for the master problem model and another for the operations problem model, the link to the specific model is made indirectly through the model__temporal_block relationship. If a model__default_investment_temporal_block is specified and no unit__investment_temporal_block relationship is specified, the model__default_investment_temporal_block relationship will be used. Conversely if unit__investment_temporal_block is specified along with model__temporal_block, this will override model__default_investment_temporal_block for the specified unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"See also Investment Optimization","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__node__node","page":"Relationship Classes","title":"unit__node__node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Holds parameters spanning multiple unit_flow variables to and from multiple nodes.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_ratio_in_in_unit_flow, fix_ratio_in_out_unit_flow, fix_ratio_out_in_unit_flow, fix_ratio_out_out_unit_flow, fix_units_on_coefficient_in_in, fix_units_on_coefficient_in_out, fix_units_on_coefficient_out_in, fix_units_on_coefficient_out_out, max_ratio_in_in_unit_flow, max_ratio_in_out_unit_flow, max_ratio_out_in_unit_flow, max_ratio_out_out_unit_flow, max_units_on_coefficient_in_in, max_units_on_coefficient_in_out, max_units_on_coefficient_out_in, max_units_on_coefficient_out_out, min_ratio_in_in_unit_flow, min_ratio_in_out_unit_flow, min_ratio_out_in_unit_flow, min_ratio_out_out_unit_flow, min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, min_units_on_coefficient_out_in, min_units_on_coefficient_out_out, unit_idle_heat_rate, unit_incremental_heat_rate and unit_start_flow","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"While the relationships unit__to_node and unit__to_node take care of the automatic generation of the unit_flow variables, the unit__node__node relationships hold the information how the different commodity flows of a unit interact. Only through this relationship and the associated parameters, the topology of a unit, i.e. which intakes lead to which products etc., becomes unambiguous.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"In almost all cases, at least one of the ..._ratio_... parameters will be defined, e.g. to set a fixed ratio between outgoing and incoming commodity flows of unit (see also e.g. fix_ratio_out_in_unit_flow). Note that the parameters can also be defined on a relationship between groups of objects, e.g. to force a fixed ratio between a group of nodes. In the triggered constraints, this will lead to an aggregation of the individual unit flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node","page":"Relationship Classes","title":"unit__to_node","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines the nodes the unit can output to, and holds most unit_flow variable specific parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: fix_nonspin_units_shut_down, fix_nonspin_units_started_up, fix_unit_flow_op, fix_unit_flow, fuel_cost, graph_view_position, initial_nonspin_units_shut_down, initial_nonspin_units_started_up, initial_unit_flow_op, initial_unit_flow, is_active, max_total_cumulated_unit_flow_to_node, min_total_cumulated_unit_flow_to_node, min_unit_flow, minimum_operating_point, operating_points, ordered_unit_flow_op, ramp_down_limit, ramp_up_limit, reserve_procurement_cost, shut_down_limit, start_up_limit, unit_capacity, unit_conv_cap_to_flow, unit_flow_non_anticipativity_margin, unit_flow_non_anticipativity_time and vom_cost","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The unit__to_node and unit__from_node unit relationships are core elements of SpineOpt. For each unit__to_node or unit__from_node, a unit_flow variable is automatically added to the model, i.e. a commodity flow of a unit to or from a specific node, respectively.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Various parameters can be defined on the unit__to_node relationship, in order to constrain the associated unit flows. In most cases a unit_capacity will be defined for an upper bound on the commodity flows. Apart from that, ramping abilities of a unit can be defined. For further details on ramps see Ramping.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"To associate costs with a certain commodity flow, cost terms, such as fuel_costs and vom_costs, can be included for the unit__to_node relationship.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"It is important to note, that the parameters associated with the unit__to_node can be defined either for a specific node, or for a group of nodes. Grouping nodes for the described parameters will result in an aggregation of the unit flows for the triggered constraint, e.g. the definition of the unit_capacity on a group of nodes will result in an upper bound on the sum of all individual unit_flows.","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node__investment_group","page":"Relationship Classes","title":"unit__to_node__investment_group","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Indicates which unit capacities are included in the capacity invested available of an investment group","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: investment_group, node and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__to_node__user_constraint","page":"Relationship Classes","title":"unit__to_node__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which output unit_flows are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: node, unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: graph_view_position and unit_flow_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#unit__user_constraint","page":"Relationship Classes","title":"unit__user_constraint","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which units_on variables are included in the user_constraint, and holds their parameters.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: unit and user_constraint","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: units_invested_available_coefficient, units_invested_coefficient, units_on_coefficient and units_started_up_coefficient","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"TODO","category":"page"},{"location":"concept_reference/Relationship Classes/#units_on__stochastic_structure","page":"Relationship Classes","title":"units_on__stochastic_structure","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific stochastic_structure is used for the units_on variable of the unit. Only one stochastic_structure is permitted per unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: stochastic_structure and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The units_on__stochastic_structure relationship defines the stochastic_structure used by the units_on variable. Essentially, this relationship permits defining a different stochastic_structure for the online decisions regarding the units_on variable, than what is used for the production unit_flow variables. A common use-case is e.g. using only one units_on variable across multiple stochastic_scenarios for the unit_flow variables. Note that only one units_on__stochastic_structure relationship can be defined per unit per model, as interpreted by the units_on__stochastic_structure and model__stochastic_structure relationships.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"The units_on__stochastic_structure relationship uses the model__default_stochastic_structure relationship if not specified.","category":"page"},{"location":"concept_reference/Relationship Classes/#units_on__temporal_block","page":"Relationship Classes","title":"units_on__temporal_block","text":"","category":"section"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Defines which specific temporal_blocks are used by the units_on variable of the unit.","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Object Classes: temporal_block and unit","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"Related Parameters: is_active","category":"page"},{"location":"concept_reference/Relationship Classes/","page":"Relationship Classes","title":"Relationship Classes","text":"units_on__temporal_block is a relationship linking the units_on variable of a unit to a specific temporal_block object. As such, this relationship will determine which temporal block governs the on- and offline status of the unit. The temporal block holds information on the temporal scope and resolution for which the variable should be optimized. ","category":"page"},{"location":"concept_reference/has_state/","page":"-","title":"-","text":"The has_state parameter is simply a Bool flag for whether a node has a node_state variable. By default, it is set to false, so the nodes enforce instantaneous commodity balance according to the nodal balance and node injection constraints. If set to true, the node will have a node_state variable generated for it, allowing for commodity storage at the node. Note that you'll also have to specify a value for the state_coeff parameter, as otherwise the node_state variable has zero commodity capacity.","category":"page"},{"location":"concept_reference/unit__commodity/","page":"-","title":"-","text":"To impose a limit on the cumulative amount of commodity flows, the max_cum_in_unit_flow_bound can be imposed on a unit__commodity relationship. This can be very helpful, e.g. if a certain amount of emissions should not be surpased throughout the optimization.","category":"page"},{"location":"concept_reference/unit__commodity/","page":"-","title":"-","text":"Note that, next to the unit__commodity relationship, also the nodes connected to the units need to be associated with their corresponding commodities, see node__commodity.","category":"page"},{"location":"concept_reference/model/","page":"-","title":"-","text":"The model object holds general information about the optimization problem at hand. Firstly, the modelling horizon is specified on the model object, i.e. the scope of the optimization model, and if applicable the duration of the rolling window (see also model_start, model_end and roll_forward). Secondly, the model works as an overarching assembler - only through linking temporal_blocks and stochastic_structures to a model object via relationships, they become part of the optimization problem, and respectively linked nodes, connections and units. If desired the user can also specify defaults for temporals and stochastic via the designated default relationships (see e.g., model__default_temporal_block). In this case, the default temporal is populated for missing node__temporal_block relationships. Lastly, the model object contains information about the algorithm used for solving the problem (see model_type).","category":"page"},{"location":"concept_reference/write_lodf_file/","page":"-","title":"-","text":"If this parameter value is set to true, a diagnostics file containing all the network line outage distributions factors in CSV format will be written to the current directory.","category":"page"},{"location":"concept_reference/storage_investment_cost/","page":"-","title":"-","text":"By defining the storage_investment_cost parameter for a specific node, a cost term will be added to the objective function whenever a storage investment is made during the current optimization window.","category":"page"},{"location":"concept_reference/connection__node__node/","page":"-","title":"-","text":"connection__node__node is a three-dimensional relationship between a connection, a node (node 1) and another node (node 2). connection__node__node infers a conversion and a direction with respect to that conversion. Node 1 is assumed to be the input node and node 2 is assumed to be the output node. For example, the fix_ratio_out_in_connection_flow parameter defined on connection__node__node relates the output connection_flow to node 2 to the intput connection_flow from node 1","category":"page"},{"location":"concept_reference/node_state_cap/","page":"-","title":"-","text":"The node_state_cap parameter represents the maximum allowed value for the node_state variable. Note that in order for a node to have a node_state variable in the first place, the has_state parameter must be set to true. However, if the node has storage investments enabled using the candidate_storages parameter, the node_state_cap parameter acts as a coefficient for the storages_invested_available variable. Essentially, with investments, the node_state_cap parameter represents storage capacity per storage investment.","category":"page"},{"location":"concept_reference/operating_points/","page":"-","title":"-","text":"If operating_points is defined as an array type on a certain unit__to_node or unit__from_node flow, the corresponding unit_flow flow variable is decomposed into a number of sub operating segment variables, unit_flow_op one for each operating segment, with an additional index, i to reference the specific operating segment. Each value in the array represents the upper bound of the operating segment, normalized on unit_capacity for the corresponding unit__to_node or unit__from_node flow. operating_points is used in conjunction with unit_incremental_heat_rate where the array dimension must match and is used to define the normalized operating point bounds for the corresponding incremental heat rate. operating_points is also used in conjunction with user_constraint where the array dimension must match any corresponding piecewise linear unit_flow_coefficient. Here operating_points is used also to define the normalized operating point bounds for the corresponding unit_flow_coefficients.","category":"page"},{"location":"concept_reference/operating_points/","page":"-","title":"-","text":"Note that operating_points is defined on a capacity-normalized basis and the values represent the upper bound of the corresponding operating segment variable. So if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"concept_reference/tax_out_unit_flow/","page":"-","title":"-","text":"By defining the tax_out_unit_flow parameter for a specific node, a cost term will be added to the objective function to account the taxes associated with all unit_flow variables with direction from_node over the course of the operational dispatch during the current optimization window.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"The definition of the max_total_cumulated_unit_flow_from_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_from_node/","page":"-","title":"-","text":"It can be defined for the unit__from_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is limiting the consumption of commodities such as oil or gas. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/model__default_temporal_block/","page":"-","title":"-","text":"The model__default_temporal_block relationship can be used to set a model-wide default for the node__temporal_block and units_on__temporal_block relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__temporal_block or units_on__temporal_block relationships take priority over the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/mga_diff_relative/","page":"-","title":"-","text":"Currently, the MGA algorithm (see mga-advanced) only supports absolute differences between MGA variables (e.g. absolute differences between units_invested_available etc.). Hence, the default for this parameter is false and should not be changed for now.","category":"page"},{"location":"concept_reference/connection_emergency_capacity/","page":"-","title":"-","text":"The connection_emergency_capacity parameter represents the maximum post-contingency flow on a monitored connection if ptdf and lodf based security constrained unit commitment is enabled (commodity_physics is set to [commodity_physics_lodf]).","category":"page"},{"location":"concept_reference/connection_emergency_capacity/","page":"-","title":"-","text":"If you set this value, make sure that you also set connection_monitored to true for the involved connection.","category":"page"},{"location":"concept_reference/unit_investment_variable_type_list/","page":"-","title":"-","text":"unit_investment_variable_type_list holds the possible values for the type of a unit's investment variable which may be chosen from integer, binary or continuous. ","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the min_ratio_out_in_connection_flow parameter triggers the generation of the constraint_min_ratio_out_in_connection_flow and sets a lower bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"Note that the ratio can also be defined for connection__node__node relationships, where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/min_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a minimum ratio of 0.2 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the min_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/connection_flow_cost/","page":"-","title":"-","text":"By defining the connection_flow_cost parameter for a specific connection, a cost term will be added to the objective function that values all connection_flow variables associated with that connection during the current optimization window.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"Given two connections, the line outage distribution factor (LODF) is the fraction of the pre-contingency flow on the first one, that will flow on the second after the contingency. commodity_lodf_tolerance is the minimum absolute value of the LODF that is considered meaningful. Any value below this tolerance (in absolute value) will be treated as zero.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"The LODFs are used to model contingencies on some connections and their impact on some other connections. To model contingencies on a connection, set connection_contingency to true; to study the impact of such contingencies on another connection, set connection_monitored to true.","category":"page"},{"location":"concept_reference/commodity_lodf_tolerance/","page":"-","title":"-","text":"In addition, define a commodity with commodity_physics set to commodity_physics_lodf, and associate that commodity (via node__commodity) to both connections' nodes (given by connection__to_node and connection__from_node).","category":"page"},{"location":"concept_reference/roll_forward/","page":"-","title":"-","text":"This parameter defines how much the optimization window rolls forward in a rolling horizon optimization and should be expressed as a duration. In a rolling horizon optimization, the model is split in windows that are optimized iteratively; roll_forward indicates how much the window should roll forward after each iteration. Overlap between consecutive optimization windows is possible. In the practical approaches presented in Temporal Framework, the rolling window optimization will be explained in more detail. The default value of this parameter is the entire model time horizon, which leads to a single optimization for the entire time horizon.","category":"page"},{"location":"concept_reference/roll_forward/","page":"-","title":"-","text":"In case you want your model to roll a different amount of time after each iteration, you can specify an array of durations for roll_forward. Position ith in this array indicates how much the model should roll after iteration i. This allows you to perform a rolling horizon optimization over a selection of disjoint representative periods as if they were contiguous.","category":"page"},{"location":"concept_reference/write_mps_file_list/","page":"-","title":"-","text":"This parameter value list is deprecated and will be removed in a future version.","category":"page"},{"location":"concept_reference/write_mps_file_list/","page":"-","title":"-","text":"Houses the different values for the write_mps_file parameter. Possible values include write_mps_always, write\\_mps\\_on\\_no\\_solve, and write\\_mps\\_never.","category":"page"},{"location":"concept_reference/graph_view_position/","page":"-","title":"-","text":"The graph_view_position parameter can be used to fix the positions of various objects and relationships when plotted using the Spine Toolbox Graph View. If not defined, Spine Toolbox simply plots the element in question wherever it sees fit in the graph.","category":"page"},{"location":"concept_reference/model__stochastic_structure/","page":"-","title":"-","text":"The [model__stochastic_structure] relationship defines which stochastic_structures are active in which models. Essentially, this relationship allows for e.g. attributing multiple node__stochastic_structure relationships for a single node, and switching between them in different models. Any stochastic_structure in the model__default_stochastic_structure relationship is automatically assumed to be active in the connected model, so there's no need to include it in [model__stochastic_structure] separately.","category":"page"},{"location":"concept_reference/unit__from_node__unit_constraint/","page":"-","title":"-","text":"unit__from_node__user_constraint is a three-dimensional relationship between a unit, a node and a user_constraint. The relationship specifies that the unit_flow variable to the specified unit from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific unit_flow variable. For example the parameter unit_flow_coefficient defined on unit__from_node__user_constraint represents the coefficient on the specific unit_flow variable in the specified user_constraint","category":"page"},{"location":"advanced_concepts/powerflow/#ptdf-based-powerflow","page":"PTDF-Based Powerflow","title":"Power transfer distribution factors (PTDF) based DC power flow","text":"","category":"section"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"There are two main methodologies for directly including DC powerflow in unit commitment/energy system models. One method is to directly include the bus voltage angles as variables in the model. This method is described in Nodal lossless DC Powerflow.","category":"page"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"Here we discuss the method of using power transfer distribution factors (PTDF) for DC power flow and line outage distribution factors (lodf) for security constrained unit commitment.","category":"page"},{"location":"advanced_concepts/powerflow/#key-concepts-advanced-ptdf-DC","page":"PTDF-Based Powerflow","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/powerflow/","page":"PTDF-Based Powerflow","title":"PTDF-Based Powerflow","text":"ptdf: The power transfer distribution factors are a property of the network reactances and their derivation may be found here. ptdf(n, c) represents the fraction of an injection at node n that will flow on connection c. The flow on connection c is then the sum over all nodes of ptdf(n, c)*net_injection(c). The advantage of this method is that it introduces no additional variables into the problem and instead, introduces only one constraint for each connection whose flow we are interested in monitoring.\nlodf: Line outage distribution factors are a function of the network ptdfs and their derivation is also found here. lodf(c_contingency, c_monitored) represents the fraction of the pre-contingency flow on connection c_contingency that will flow on c_monitored if c_contingency is disconnected. Therefore, the post contingency flow on connection c_monitored is the pre_contingency flow plus lodf(c_contingency, c_monitored)\\*pre_contingency_flow(c_contingency)). Therefore, consideration of N contingencies on M monitored lines introduces N x M constraints into the model. Usually one wishes to contain this number and methods are given below to achieve this.\nDefining your network To identify the network for which ptdfs, lodfs and connection_flows will be calculated according to the ptdf method, one does the following:\nCreate node objects for each bus in the model.\nCreate connection objects representing each line of the network: For each connection specify the connection_reactance parameter and the connection_type parameter. Setting connection_type=connection_type_lossless_bidirectional simplifies the amount of data that needs to be specified for an eletrical network. See connection_type for more details \nSet the connection__to_node and connection__from_node relationships to define the topology of each connection along with the connection_capacity parameter on one or both of these relationships.\nSet the connection_emergency_capacity parameter to define the post contingency rating if lodf-based N-1 security constraints are to be included\nCreate a commodity object and node__commodity relationships for all the nodes that comprise the electrical network for which PTDFs are to be calculated.\nSpecify the commodity_physics parameter for the commodity to :commodity_physics_ptdf if ptdf-based DC load flow is desired with no N-1 security constraints or to :commodity_physics_lodf if it is desired to include lodf-based N-1 security constraints\nTo identify the reference bus(node) specify the node_opf_type parameter for the appropriate node with the value node_opf_type_reference.\nControlling problem size\nThe lines to be monitored are specified by setting the connection_monitored property for each connection for which a flow constraint is to be generated\nThe contingencies to be considered are specified by setting the connection_contingency property for the appropriate connections. For N contingencies and M monitored lines, N x M constraints will be generated.\nIf the lodf(c_contingency, c_monitored) is very small, it means the outage of c_contingency has a small impact on the flow on c_monitoredand there is little point in including this constraint in the model. This can be achieved by setting the commodity_lodf_tolerance commodity parameter. Contingency / Monotired line combinations with lodfs below this value will be ignored, reducing the size of the model.\nIf ptdf(n, c) is very small, it means an injection at n has a small impact on the flow on c and there is little point in considering it. This can be achieved by setting the commodity_ptdf_threshold commodity parameter. Node / Monotired line combinations with ptdfs below this value will be ignored, reducing the number of coefficients in the model.\nTo more easily identify which connections are worth being monitored or which contingencies are worth being considered, you can add the contingency_is_binding output to any of your reports (via a report__output relationship). This will run the model without the security constraints, and instead write a parameter called contingency_is_binding to the output database for each pair of contingency and monitored connection. The value of the parameter will be a (possibly stochastic) time-series where a value of one will indicate that the corresponding security constraint is binding, and zero otherwise.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/#pressure-driven-gas-transfer","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"","category":"section"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"The generic formulation of SpineOpt is based on a trade based model. However, network physics can be different depending on the traded commodity. This chapter specifically addresses the use of pressure driven gas transfer models and enabling linepack flexibility in SpineOpt. To this date, investments in pressure driven pipelines are not yet supported within SpineOpt. The use of multiple feed-in nodes, e.g. to represent multiple commodity flows through a pipeline is not yet supported.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"For the representation of pressure driven gas transfer, we use the MILP formulation, as described in Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling. Here, the non-linearities associated with the Weymouth equation are convexified through an outer approximation of the Weymouth equation through fixed pressure points.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/#key-concepts-advanced-gas","page":"Pressure driven gas transfer","title":"Key concept","text":"","category":"section"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"Here, we briefly describe the key objects and relationships required to model pressure driven gas transfers in SpineOpt.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"connection: A connection represents the gas pipeline being modelled. Usually the direction of flow is not known a priory. To ensure that the flow through the gas pipeline is unidirectional, the parameter has_binary_gas_flow needs to be set to true.\nnode: Nodes with different characteristics are used for the representation of pressure driven gas transfer.\nFor each connection, there will be two nodes representing the start and end point of the pipeline. Associated with these nodes are the following parameters: the has_pressure parameter, which needs to be set to true, in order to create the variable node_pressure; the max_node_pressure and min_node_pressure to constrain the pressure variable.\nTo leverage linepack flexibility, a third node is introduced representing the linepack storage of the pipeline. To trigger the storage linepack and hence, node_state variables, the has_state parameter needs to be set to true.\nconnection__to_node and connection__from_node To enable flows through the pipeline and into the linepack storage, each node has to have both these relationships in common with the connection pipeline. These relationships will trigger the generation of connection_flow variables in all possible directions.\nconnection__node__node This relationship is key to the pressure driven gas transfer, holding the information about the pipeline characteristics and bringing the elements into interaction.\nThe parameter connection_linepack_constant holds the linepack constant and triggers the generation of the line pack storage constraint. Note that the first node should be the linepack storage node, while the second node should be a node_group of both, the start and the end node of the pipeline.\nThe linearization of the Weymouth equation through outer approximation relies on the use of fixed pressure points. For this purpose, the two parameters fixed_pressure_constant_1 and fixed_pressure_constant_0 hold the fixed pressure constants and trigger the generation of the constraint_fix_node_pressure_point. The constraint introduces the relationship between pressure and gas flows. Note, that the pressure constants should be entered in a way, that the first node represents the origin node, the second node the destination node. Each connection should have a connection__node__node to each combination of its start and end nodes (and associated parameters). (See Schwele - Coordination of Power and Natural Gas Systems: Convexification Approaches for Linepack Modeling)\nBy default, pipelines are considered to be passive. However, a compression station between two pipeline pressure nodes can be represented by defining a compression_factor. The relationship should be defined in such a manner, that the first node represents the sending node, the second node represents the receiving node, which pressure is equal or smaller to the pressure at the sending node times the compression factor.\nLastly, to ensure the balance between incoming/outgoing flows and flows into the linepack, the ratio between the flows need to be fixed. The average incoming flows of the node group (of the pressure start and end nodes) have to equal the flows into the linepack storage, and vice versa. Therefore, the fix_ratio_out_in_connection_flow needs to be set to a value (typically 1) for the (pressure group, linepack storage) node pair, and for the (linepack storage, pressure group) node pair.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"A gas pipeline and its connected nodes are illustrated below. A complete mathematical formulation can be found here.","category":"page"},{"location":"advanced_concepts/pressure_driven_gas_transfer/","page":"Pressure driven gas transfer","title":"Pressure driven gas transfer","text":"(Image: Illustration of gas pipeline)","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"Indicates the start of this temporal block. The main use of this parameter is to create an offset from the model start. The default value is equal to a duration of 0. It is useful to distinguish here between two cases: a single solve, or a rolling window optimization.","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"single solve When a Date time value is chosen, this is directly the start of the optimization for this temporal block. When a duration is chosen, it is added to the model_start to obtain the start of this temporal_block. In the case of a duration, the chosen value directly marks the offset of the optimization with respect to the model_start. The default value for this parameter is the model_start.","category":"page"},{"location":"concept_reference/block_start/","page":"-","title":"-","text":"rolling window optimization To create a temporal block that is rolling along with the optimization window, a rolling temporal block, a duration value should be chosen. The temporal block_start will again mark the offset of the optimization start but now with respect to the start of each optimization window.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_in/","page":"-","title":"-","text":"The min_units_on_coefficient_out_in parameter is an optional coefficient in the unit output-input ratio constraint controlled by the min_ratio_out_in_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_in/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_in and fix_units_on_coefficient_out_in.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"The definition of the max_ratio_out_in_connection_flow parameter triggers the generation of the constraint_max_ratio_out_in_connection_flow and sets an upper bound on the ratio between outgoing and incoming flows of a connection. The parameter is defined on the relationship class connection__node__node, where the first node (or group of nodes) in this relationship represents the to_node, i.e. the outgoing flow from the connection, and the second node (or group of nodes), represents the from_node, i.e. the incoming flows to the connection. The ratio parameter is interpreted such that it constrains the ratio of out over in, where out is the connection_flow variable from the first node in the connection__node__node relationship in a left-to-right reading order.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"To enforce e.g. a maximum ratio of 0.8 for a connection conn between its outgoing electricity flow to node commodity1 and its incoming flows from the node node commodity2, the max_ratio_out_in_connection_flow parameter would be set to 0.8 for the relationship conn__commodity1__commodity2.","category":"page"},{"location":"concept_reference/max_ratio_out_in_connection_flow/","page":"-","title":"-","text":"Note that the ratio can also be defined for connection__node__node relationships where one or both of the nodes correspond to node groups in order to impose a ratio on aggregated connection flows.","category":"page"},{"location":"concept_reference/boolean_value_list/","page":"-","title":"-","text":"A list of boolean values (True or False).","category":"page"},{"location":"concept_reference/frac_state_loss/","page":"-","title":"-","text":"The frac_state_loss parameter allows setting self-discharge losses for nodes with the node_state variables enabled using the has_state variable. Effectively, the frac_state_loss parameter acts as a coefficient on the node_state variable in the node injection constraint, imposing losses for the node. In simple cases, storage losses are typically fractional, e.g. a frac_state_loss parameter value of 0.01 would represent 1% of node_state lost per unit of time. However, a more general definition of what the frac_state_loss parameter represents in SpineOpt would be loss power per unit of node_state.","category":"page"},{"location":"concept_reference/connections_invested_avaiable_coefficient/","page":"-","title":"-","text":"The connections_invested_available_coefficient is an optional parameter that can be used to include the connections_invested_available variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_available_coefficient appears as a coefficient for the connections_invested_available variable in the user constraint.","category":"page"},{"location":"concept_reference/unit_capacity/","page":"-","title":"-","text":"To set an upper bound on the commodity flow of a unit in a certain direction, the unit_capacity constraint needs to be defined on a unit__to_node or unit__from_node relationship. By defining the parameter, the unit_flow variables to or from a node or a group of nodes will be constrained by the capacity constraint.","category":"page"},{"location":"concept_reference/unit_capacity/","page":"-","title":"-","text":"Note that if the unit_capacity parameter is defined on a node group, the sum of all unit_flows within the specified node group will be constrained by the unit_capacity.","category":"page"},{"location":"#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"SpineOpt.jl is an integrated energy systems optimization model, striving towards adaptability for a multitude of modelling purposes. The data-driven model structure allows for highly customizable energy system descriptions, as well as flexible temporal and stochastic structures, without the need to alter the model source code directly. The methodology is based on mixed-integer linear programming (MILP), and SpineOpt relies on JuMP.jl for interfacing with the different solvers.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"While, in principle, it is possible to run SpineOpt by itself, it has been designed to be used through the Spine toolbox, and take maximum advantage of the data and modelling workflow management tools therein. Thus, we highly recommend installing Spine toolbox as well, as outlined in the Installation guide.","category":"page"},{"location":"#Getting-Started","page":"Introduction","title":"Getting Started","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"As the name implies, this chapter contains guides for starting to use SpineOpt.jl for the first time. The Installation links to the guides how to install SpineOpt.jl and Spine Toolbox on your computer. The Setting up a workflow for SpineOpt in Spine Toolbox section explains how to set up and run SpineOpt.jl from Spine Toolbox. The Creating Your Own Model section explains how to create a new model from scratch. This includes a list of the necessary Object Classes and Relationship Classes, but for more information, you will probably need to consult the Concept Reference chapter.","category":"page"},{"location":"#Tutorials","page":"Introduction","title":"Tutorials","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"We learn a lot from examples and that is what you will find in the tutorial chapter. The tutorials come in different shapes: videos, written text and example files. The SpineOpt.jl repository includes a folder examples for ready-made example models. Each example is its own sub-folder, where the input data is provided as .json or .sqlite files. This way, you can easily get a feel for how SpineOpt works with pre-made datasets, either through Spine Toolbox, or directly from the Julia REPL.","category":"page"},{"location":"#How-to","page":"Introduction","title":"How to","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"The other parts of the documentation are good as a reference when you know what you are looking for but this chapter adds explanations on how to do specific high-level things that might involve multiple elements (e.g. how to print the model).","category":"page"},{"location":"#Concept-Reference","page":"Introduction","title":"Concept Reference","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter lists and explains all the important data and model structure related concepts to understand in SpineOpt.jl. For a mathematical modelling point of view, see the Mathematical Formulation chapter instead. The Basics of the model structure section briefly explains the general purpose of the most important concepts, like Object Classes and Relationship Classes. Meanwhile, the Object Classes, Relationship Classes, Parameters, and Parameter Value Lists sections contain detailed explanations of each and every aspect of SpineOpt.jl, organized into the respective sections for clarity.","category":"page"},{"location":"#Mathematical-Formulation","page":"Introduction","title":"Mathematical Formulation","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter provides the mathematical view of SpineOpt.jl, as some of the methodology-related aspects of the model are more easily understood as math than Julia code. The Variables section explains the purpose of each variable in the model, as well as how the variables are related to the different Object Classes and Relationship Classes. The Constraints section contains the mathematical formulation of each constraint, as well as explanations to their purpose and how they are controlled via different Parameters. Finally, the Objective section explains the default objective function used in SpineOpt.jl.","category":"page"},{"location":"#Advanced-Concepts","page":"Introduction","title":"Advanced Concepts","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This chapter explains some of the more complicated aspects of SpineOpt.jl in more detail, hopefully making it easier for you to better understand and apply them in your own modelling. The first few sections focus on aspects of SpineOpt.jl that most users are likely to use, or which are more or less required to understand for advanced use. The Temporal Framework section explains how defining time works in SpineOpt.jl, and how it can be used for different purposes. The Stochastic Framework section details how different stochastic structures can be defined, how they interact with each other, and how this impacts writing Constraints in SpineOpt.jl. The Unit commitment section explains how clustered unit-commitment is defined, while the Ramping and Reserves sections explain how to enable these operational details in your model. The Investment Optimization section explains how to include investment variables in your models, while the User Constraints section details how to include generic data-driven custom constraints.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"The last few sections focus on highly specialized use-cases for SpineOpt.jl, which are unlikely to be relevant for simple modelling tasks. The Decomposition section explains the Benders decomposition implementation included in SpineOpt.jl, as well as how to use it. The remaining sections, namely PTDF-Based Powerflow, Pressure driven gas transfer, Lossless nodal DC power flows, and Representative days with seasonal storages, explain various use-case specific modelling approaches supported by SpineOpt.jl.","category":"page"},{"location":"#Implementation-details","page":"Introduction","title":"Implementation details","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"For those who are interested in how things work under the hood, this chapter explains some parts of the code. Note that this chapter is particularly sensitive to changes in the code and as such might get out of sync. If you do notice a discrepancy, please create an issue in github. That is also the place to be if you don't find what you are looking for in this documentation.","category":"page"},{"location":"concept_reference/output/","page":"-","title":"-","text":"An output is essentially a handle for a SpineOpt variable and Objective function to be included in a report and written into an output database. Typically, e.g. the unit_flow variables are desired as output from most models, so creating an output object called unit_flow allows one to designate it as something to be written in the desired report. Note that unless appropriate model__report and report__output relationships are defined, SpineOpt doesn't write any output!","category":"page"},{"location":"concept_reference/connection_conv_cap_to_flow/","page":"-","title":"-","text":"The connection_conv_cap_to_flow can be used to perform the conversion between the measurement unit of the connection_capacity to the measurement unit of the connection_flow variable. The default of this parameter is 1, i.e. assuming that both are given in the same measurement unit.","category":"page"},{"location":"concept_reference/max_mga_slack/","page":"-","title":"-","text":"In the MGA algorithm the original problem is reoptimized (see also mga-advanced), and finds near-optimal solutions. The parameter max_mga_slack defines how far from the optimum the new solutions can maximally be (e.g. a value of 0.05 would alow for a 5% increase of the orginal objective value).","category":"page"},{"location":"concept_reference/max_voltage_angle/","page":"-","title":"-","text":"If a node has a node_voltage_angle variable (see also the parameter has_voltage_angle and this chapter), an upper bound on the voltage angle can be introduced through the max_voltage_angle parameter, which triggers the generation of the maximum node voltage angle constraint.","category":"page"},{"location":"concept_reference/stochastic_structure/","page":"-","title":"-","text":"The stochastic_structure is the key component of the scenario-based Stochastic Framework in SpineOpt.jl, and essentially represents a group of stochastic_scenarios with set Parameters. The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structures, and the weight_relative_to_parents and stochastic_scenario_end Parameters define the exact shape and impact of the stochastic_structure, along with the parent_stochastic_scenario__child_stochastic_scenario relationship.","category":"page"},{"location":"concept_reference/stochastic_structure/","page":"-","title":"-","text":"The main reason as to why stochastic_structures are so important is, that they act as handles connecting the Stochastic Framework to the modelled system. This is handled using the Structural relationship classes e.g. node__stochastic_structure, which define the stochastic_structure applied to each object describing the modelled system. Connecting each system object to the appropriate stochastic_structure individually can be a bit bothersome at times, so there are also a number of convenience Meta relationship classes like the model__default_stochastic_structure, which allow setting model-wide defaults to be used whenever specific definitions are missing.","category":"page"},{"location":"concept_reference/connections_invested_coefficient/","page":"-","title":"-","text":"The connections_invested_coefficient is an optional parameter that can be used to include the connections_invested variable in a user_constraint via the connection__user_constraint relationship. Essentially, connections_invested_coefficient appears as a coefficient for the connections_invested variable in the user constraint.","category":"page"},{"location":"concept_reference/db_lp_solver/","page":"-","title":"-","text":"Specifies the Julia solver package to be used to solve Linear Programming Problems (LPs) for the specific model. The value must correspond exactly (case sensitive) to the name of the Julia solver package (e.g. Clp.jl). Installation and configuration of solvers is the responsibility of the user. A full list of solvers supported by JuMP can be found here. Note that the specified problem must support LP problems. Solver options are specified using the db_lp_solver_options parameter for the model. Note also that if run_spineopt() is called with the lp_solver keyword argument specified, this will override this parameter.","category":"page"},{"location":"concept_reference/connection_flow_delay/","page":"-","title":"-","text":"The connection_flow_delay parameter denotes the amount of time that it takes for the flow to go through a connection. In other words, the flow that enters the connection is only seen at the other side after connection_flow_delay units of time.","category":"page"},{"location":"concept_reference/constraint_sense_list/","page":"-","title":"-","text":"The constraint_sense_list parameter value list contains the possible values for the constraint_sense parameter.","category":"page"},{"location":"concept_reference/parent_stochastic_scenario__child_stochastic_scenario/","page":"-","title":"-","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship defines how the individual stochastic_scenarios are related to each other, forming what is referred to as the stochastic direct acyclic graph (DAG) in the Stochastic Framework section. It acts as a sort of basis for the stochastic_structures, but doesn't contain any Parameters necessary for describing how it relates to the Temporal Framework or the Objective function.","category":"page"},{"location":"concept_reference/parent_stochastic_scenario__child_stochastic_scenario/","page":"-","title":"-","text":"The parent_stochastic_scenario__child_stochastic_scenario relationship and the stochastic DAG it forms are crucial for Constraint generation with stochastic path indexing. Every finite stochastic DAG has a limited number of unique ways of traversing it, called full stochastic paths, which are used when determining how many different constraints need to be generated over time periods where stochastic_structures branch or converge, or when generating constraints involving different stochastic_structures. See the Stochastic Framework section for more information.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"The definition of the max_total_cumulated_unit_flow_to_node parameter will trigger the creation of the constraint_total_cumulated_unit_flow. It sets an upper bound on the sum of the unit_flow variable for all timesteps.","category":"page"},{"location":"concept_reference/max_total_cumulated_unit_flow_to_node/","page":"-","title":"-","text":"It can be defined for the unit__to_node relationships, as well as their counterparts for node- and unit groups. It will then restrict the total accumulation of unit_flow variables to be below the given value. A possible use case is the capping of CO2 emissions. The parameter is given as an absolute value thus has to be coherent with the units used for the unit flows.","category":"page"},{"location":"concept_reference/connection_linepack_constant/","page":"-","title":"-","text":"The linepack constant is a physical property of a connection representing a pipeline and holds information on how the linepack flexibility relates to pressures of the adjacent nodes. If, and only if, this parameter is defined, the linepack flexibility of a pipeline can be modelled. The existence of the parameter triggers the generation of the constraint on line pack storage. The connection_linepack_constant should always be defined on the tuple (connection pipeline, linepack storage node, node group (containing both pressure nodes, i.e. start and end of the pipeline)). See also.","category":"page"},{"location":"concept_reference/db_lp_solver_list/","page":"-","title":"-","text":"List of supported LP solvers which may be specified for the db_lp_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Clp.jl) and is case sensitive.","category":"page"},{"location":"concept_reference/temporal_block/","page":"-","title":"-","text":"A temporal block defines the temporal properties of the optimization that is to be solved in the current window. It is the key building block of the Temporal Framework. Most importantly, it holds the necessary information about the resolution and horizon of the optimization. A single model can have multiple temporal blocks, which is one of the main sources of temporal flexibility in Spine: by linking different parts of the model to different temporal blocks, a single model can contain aspects that are solved with different temporal resolutions or time horizons.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_out/","page":"-","title":"-","text":"The min_units_on_coefficient_out_out parameter is an optional coefficient in the unit output-output ratio constraint controlled by the min_ratio_out_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_out_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_in_out, and min_units_on_coefficient_out_in, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_out_out and fix_units_on_coefficient_out_out.","category":"page"},{"location":"concept_reference/fix_ratio_in_out_unit_flow/","page":"-","title":"-","text":"The definition of the fix_ratio_in_out_unit_flow parameter triggers the generation of the constraint_fix_ratio_in_out_unit_flow and fixes the ratio between incoming and outgoing flows of a unit. The parameter is defined on the relationship class unit__node__node, where the first node (or group of nodes) in this relationship represents the from_node,i i.e. the incoming flows to the unit, and the second node (or group of nodes), represents the to_node i.e. the outgoing flow from the unit. The ratio parameter is interpreted such that it constrains the ratio of in over out, where in is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right order.","category":"page"},{"location":"concept_reference/fix_ratio_in_out_unit_flow/","page":"-","title":"-","text":"To enforce e.g. a fixed ratio of 1.4 for a unit u between its incoming gas flow from the node ng and its outgoing flows to the node group el_heat (consisting of the two nodes el and heat), the fix_ratio_in_out_unit_flow parameter would be set to 1.4 for the relationship u__ng__el_heat.","category":"page"},{"location":"concept_reference/right_hand_side/","page":"-","title":"-","text":"Used to specify the right-hand-side, constant term in a user_constraint. See also user_constraint.","category":"page"},{"location":"concept_reference/model__temporal_block/","page":"-","title":"-","text":"The model__temporal_block relationship is used to determine which temporal_blocks are included in a specific model. Note that defining this relationship does not yet imply that any element of the model will be governed by the specified temporal_block, for this to happen additional relationships have to be defined such as the model__default_temporal_block relationship.","category":"page"},{"location":"concept_reference/unit_incremental_heat_rate/","page":"-","title":"-","text":"Used to implement simple or piecewise linear incremental heat rate functions. Used in the constraint unit_pw_heat_rate - the input fuel flow at node 1 is the sum of the electrical MW output at node 2 times the incremental heat rate over all heat rate segments, plus the unit_idle_heat_rate. The units are detmerined by the data, but generally, incremental heat rates are given in GJ/MWh. Note that the formulation assumes a convex, monitonically increasing heat rate function. The formulation relies on optimality to load the heat rate segments in the correct order and no additional integer variables are created to enforce the correct loading order. The heat rate segment MW operating points are defined by operating_points.","category":"page"},{"location":"concept_reference/unit_incremental_heat_rate/","page":"-","title":"-","text":"To implement a simple incremental heat rate function,unit_incremental_heat_rate should be given as a simple scalar representing the incremental heat rate over the entire operating range of the unit. To implement a piecewise linear heat rate function, unit_incremental_heat_rate should be specified as an array type. It is then used in conjunction with the unit parameter operating_points which should also be defined as an array type of equal dimension. When defined as an array type unit_incremental_heat_rate[i] is the effective incremental heat rate between operating_points [i-1] (or zero if i=1) and operating_points[i]. Note that operating_points is defined on a capacity-normalized basis so if operating_points is specified as [0.5, 1], this creates two operating segments, one from zero to 50% of the corresponding unit_capacity and a second from 50% to 100% of the corresponding unit_capacity.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/#Lossless-nodal-DC-power-flows","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"","category":"section"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"Currently, there are two different methods to represent lossless DC power flows. In the following the implementation of the nodal model is presented, based of node voltage angles.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/#key-concepts-advanced-nodal-DC","page":"Lossless nodal DC power flows","title":"Key concepts","text":"","category":"section"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"In the following, it is described how to set up a connection in order to represent a nodal lossless DC power flow network. Therefore, key object - and relationship classes as well as parameters are introduced.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"connection: A connection represents the electricity line being modelled. A physical property of a connection is its connection_reactance, which is defined on the connection object. Furthermore, if the reactance is given in a p.u. different from the standard unit used (e.g. p.u. = 100MVA), the parameter connection_reactance_base can be used to perform this conversion.\nnode: In a lossless DC power flow model, nodes correspond to buses. To use voltage angles for the representation of a lossless DC model, the has_voltage_angle needs to be true for these nodes (which will trigger the generation of the node_voltage_angle variable). Limits on the voltage angle can be enforced through the max_voltage_angle and min_voltage_angle parameters. The reference node of the system should have a voltage angle equal to zero, assigned through the parameter fix_node_voltage_angle.\nconnection__to_node and connection__from_node : These relationships need to be introduced between the connection and each node, in order to allow power flows (i.e. connection_flow). Furthermore, a capacity limit on the connection line can be introduced on these relationships through the parameter connection_capacity.\nconnection__node__node: To ensure energy conservation across the power line, a fixed ratio between incoming and outgoing flows should be given. The fix_ratio_out_in_connection_flow parameter enforces a fixed ratio between outgoing flows (i.e. to_node) and incoming flows (i.e. from_node). This parameter should be defined for both flow direction.","category":"page"},{"location":"advanced_concepts/Lossless_DC_power_flow/","page":"Lossless nodal DC power flows","title":"Lossless nodal DC power flows","text":"The mathematical formulation of the lossless DC power flow model using voltage angles is fully described here.","category":"page"},{"location":"concept_reference/max_ratio_in_in_unit_flow/","page":"-","title":"-","text":"The definition of the max_ratio_in_in_unit_flow parameter triggers the generation of the constraint_max_ratio_in_in_unit_flow and enforces an upper bound on the ratio between incoming flows of a unit. The parameter is defined on the relationship class unit__node__node, where both nodes (or group of nodes) in this relationship represent from_nodes, i.e. the incoming flows to the unit. The ratio parameter is interpreted such that it constrains the ratio of in1 over in2, where in1 is the unit_flow variable from the first node in the unit__node__node relationship in a left-to-right reading order. This parameter can be useful, for instance if a unit requires a specific commodity mix as a fuel supply.","category":"page"},{"location":"concept_reference/max_ratio_in_in_unit_flow/","page":"-","title":"-","text":"To enforce e.g. for a unit u a maximum share of 0.8 of its incoming flow from the node supply_fuel_1 compared to its incoming flow from the node group supply_fuel_2 (consisting of the two nodes supply_fuel_2_component_a and supply_fuel_2_component_b) the max_ratio_in_in_unit_flow parameter would be set to 0.8 for the relationship u__supply_fuel_1__supply_fuel_2.","category":"page"},{"location":"concept_reference/model__default_stochastic_structure/","page":"-","title":"-","text":"The model__default_stochastic_structure relationship can be used to set a model-wide default for the node__stochastic_structure and units_on__stochastic_structure relationships. Its main purpose is to allow users to avoid defining each relationship individually, and instead allow them to focus on defining only the exceptions. As such, any specific node__stochastic_structure or units_on__stochastic_structure relationships take priority over the model__default_stochastic_structure relationship.","category":"page"},{"location":"concept_reference/db_mip_solver_options/","page":"-","title":"-","text":"MIP solver options are specified for a model using the db_mip_solver_options parameter. This parameter value must take the form of a nested map where the outer key corresponds to the solver package name (case sensitive). E.g. Cbc.jl. The inner map consists of option name and value pairs. See the below example. By default, the SpineOpt template contains some common parameters for some common solvers. For a list of supported solver options, one should consult the documentation for the solver and//or the julia solver wrapper package. (Image: example db_mip_solver_options map parameter)","category":"page"},{"location":"concept_reference/connection__from_node__unit_constraint/","page":"-","title":"-","text":"connection__from_node__user_constraint is a three-dimensional relationship between a connection, a node and a user_constraint. The relationship specifies that the connection_flow variable to the specified connection from the specified node is involved in the specified user_constraint. Parameters on this relationship generally apply to this specific connection_flow variable. For example the parameter connection_flow_coefficient defined on connection__from_node__user_constraint represents the coefficient on the specific connection_flow variable in the specified user_constraint","category":"page"},{"location":"concept_reference/storage_investment_lifetime/","page":"-","title":"-","text":"Duration parameter that determines the minimum duration of storage investment decisions. Once a storage has been invested-in, it must remain invested-in for storage_investment_lifetime. Note that storage_investment_lifetime is a dynamic parameter that will impact the amount of solution history that must remain available to the optimisation in each step - this may impact performance.","category":"page"},{"location":"concept_reference/storage_investment_lifetime/","page":"-","title":"-","text":"See also Investment Optimization and candidate_storages","category":"page"},{"location":"concept_reference/unit_flow_coefficient/","page":"-","title":"-","text":"The unit_flow_coefficient is an optional parameter that can be used to include the unit_flow or unit_flow_op variables from or to a node in a user_constraint via the unit__from_node__user_constraint and unit__to_node__user_constraint relationships. Essentially, unit_flow_coefficient appears as a coefficient for the unit_flow and unit_flow_op variables from or to the node in the user constraint.","category":"page"},{"location":"concept_reference/unit_flow_coefficient/","page":"-","title":"-","text":"Note that the unit_flow_op variables are a bit of a special case, defined using the operating_points parameter.","category":"page"},{"location":"concept_reference/max_iterations/","page":"-","title":"-","text":"When the model in question is of type :spineopt_benders_master, this determines the maximum number of Benders iterations.","category":"page"},{"location":"concept_reference/storages_invested_avaiable_coefficient/","page":"-","title":"-","text":"The storages_invested_available_coefficient is an optional parameter that can be used to include the storages_invested_available variable in a user_constraint via the node__user_constraint relationship. Essentially, storages_invested_available_coefficient appears as a coefficient for the storages_invested_available variable in the user constraint. For more information, see the [User Constraints Concept Reference][#User-Constraints]","category":"page"},{"location":"concept_reference/unit_conv_cap_to_flow/","page":"-","title":"-","text":"The unit_conv_cap_to_flow, as defined for a unit__to_node or unit__from_node, allows the user to align between unit_flow variables and the unit_capacity parameter, which may be expressed in different units. An example would be when the unit_capacity is expressed in GWh, while the demand on the node is expressed in MWh. In that case, a unit_conv_cap_to_flow parameter of 1000 would be applicable. ","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"The weight_relative_to_parents parameter defines how much weight the stochastic_scenario gets in the Objective function. As a stochastic_structure__stochastic_scenario relationship parameter, different stochastic_structures can use different weights for the same stochastic_scenario. Note that every stochastic_scenario that appears in the model must have a weight_relative_to_parents defined for it related to the used stochastic_structure! See the Stochastic Framework section for more information about how different stochastic_structures interact in SpineOpt.jl.)","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"Since the Stochastic Framework in SpineOpt.jl supports stochastic directed acyclic graphs instead of simple stochastic trees, it is possible to define stochastic_structures with converging stochastic_scenarios. In these cases, the child stochastic_scenarios inherint the weight of all of their parents, and the final weight that will appear in the Objective function is calculated as shown below:","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"# For root `stochastic_scenarios` (meaning no parents)\n\nweight(scenario) = weight_relative_to_parents(scenario)\n\n# If not a root `stochastic_scenario`\n\nweight(scenario) = sum([weight(parent) * weight_relative_to_parents(scenario)] for parent in parents)","category":"page"},{"location":"concept_reference/weight_relative_to_parents/","page":"-","title":"-","text":"The above calculation is performed starting from the roots, generation by generation, until the leaves of the stochastic DAG. Thus, the final weight of each stochastic_scenario is dependent on the weight_relative_to_parents Parameters of all its ancestors.","category":"page"},{"location":"concept_reference/unit__investment_stochastic_structure/","page":"-","title":"-","text":"The unit__investment_stochastic_structure relationship defines the stochastic_structure of unit-related investment decisions. Essentially, it sets the stochastic_structure used by the units_invested_available variable of the unit.","category":"page"},{"location":"concept_reference/unit__investment_stochastic_structure/","page":"-","title":"-","text":"The unit__investment_stochastic_structure relationship uses the model__default_investment_stochastic_structure relationship if not defined.","category":"page"},{"location":"concept_reference/commodity_physics_duration/","page":"-","title":"-","text":"This parameter determines the duration, relative to the start of the optimisation window, over which the physics determined by commodity_physics should be applied. This is useful when the optimisation window includes a long look-ahead where the detailed physics are not necessary. In this case one can set commodity_physics_duration to a shorter value to reduce problem size and increase performace.","category":"page"},{"location":"concept_reference/commodity_physics_duration/","page":"-","title":"-","text":"See also powerflow","category":"page"},{"location":"concept_reference/connection__to_node/","page":"-","title":"-","text":"connection__to_node is a two-dimensional relationship between a connection and a node and implies a connection_flow from the connection to the node. Specifying such a relationship will give rise to a connection_flow_variable with indices connection=connection, node=node, direction=:to_node. Relationships defined on this relationship will generally apply to this specific flow variable. For example, connection_capacity will apply only to this specific flow variable, unless the connection parameter connection_type is specified.","category":"page"},{"location":"concept_reference/stochastic_structure__stochastic_scenario/","page":"-","title":"-","text":"The stochastic_structure__stochastic_scenario relationship defines which stochastic_scenarios are included in which stochastic_structure, as well as holds the stochastic_scenario_end and weight_relative_to_parents Parameters defining how the stochastic_structure interacts with the Temporal Framework and the Objective function. Along with parent_stochastic_scenario__child_stochastic_scenario, this relationship is used to define the exact properties of each stochastic_structure, which are then applied to the objects describing the modelled system according to the Structural relationship classes, like the node__stochastic_structure relationship.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_out/","page":"-","title":"-","text":"The min_units_on_coefficient_in_out parameter is an optional coefficient in the unit input-output ratio constraint controlled by the min_ratio_in_out_unit_flow parameter. Essentially, it acts as a coefficient for the units_on variable in the constraint, allowing for making the minimum conversion ratio dependent on the amount of online capacity.","category":"page"},{"location":"concept_reference/min_units_on_coefficient_in_out/","page":"-","title":"-","text":"Note that there are different parameters depending on the directions of the unit_flow variables being constrained: min_units_on_coefficient_in_in, min_units_on_coefficient_out_in, and min_units_on_coefficient_out_out, all of which apply to their respective constraints. Similarly, there are different parameters for setting maximum or fixed conversion rates, e.g. max_units_on_coefficient_in_out and fix_units_on_coefficient_in_out.","category":"page"},{"location":"concept_reference/db_mip_solver_list/","page":"-","title":"-","text":"List of supported MIP solvers which may be specified for the db_mip_solver_options parameter. The value must correspond exactly to the name of the Julia solver package (e.g. Cbc.jl) and is case sensitive.","category":"page"}] } diff --git a/dev/tutorial/case_study_a5/index.html b/dev/tutorial/case_study_a5/index.html index 846bc54f65..3deaaa6e3a 100644 --- a/dev/tutorial/case_study_a5/index.html +++ b/dev/tutorial/case_study_a5/index.html @@ -13,4 +13,4 @@ Granfors_pwr_plant Krångfors_pwr_plant Selsfors_pwr_plant - Kvistforsen_pwr_plant
  • Go to Object tree (on the top left of the window, usually), right-click on unit and select Add objects from the context menu. This will open the Add objects dialog.
  • Select the first cell under the object name column and press Ctrl+V. This will paste the list of plant names from the clipboard into that column; the object class name column will be filled automatically with ‘unit‘. The form should now be looking similar to this: image
  • Click Ok.
  • Back in the Spine DB Editor, under Object tree, double click on unit to confirm that the objects are effectively there.
  • Commit changes with the message ‘Add power plants’.
  • Add discharge and spillway connections by creating objects of class connection with the following names:

    RebnistoBergnäsdisch SadvatoBergnäsdisch BergnästoSlagnäsdisch SlagnästoBastuseldisch BastuseltoGrytforsdisch GrytforstoGallejaurdisch GallejaurtoVargforsdisch VargforstoRengårddisch RengårdtoBåtforsdisch BåtforstoFinnforsdisch FinnforstoGranforsdisch GranforstoKrångforsdisch KrångforstoSelsforsdisch SelsforstoKvistforsendisch Kvistforsentodownstreamdisch RebnistoBergnässpill SadvatoBergnässpill BergnästoSlagnässpill SlagnästoBastuselspill BastuseltoGrytforsspill GrytforstoGallejaurspill GallejaurtoVargforsspill VargforstoRengårdspill RengårdtoBåtforsspill BåtforstoFinnforsspill FinnforstoGranforsspill GranforstoKrångforsspill KrångforstoSelsforsspill SelsforstoKvistforsenspill Kvistforsentodownstreamspill

  • Add water nodes by creating objects of class node with the following names:

    Rebnisupper Sadvaupper Bergnäsupper Slagnäsupper Bastuselupper Grytforsupper Gallejaurupper Vargforsupper Rengårdupper Båtforsupper Finnforsupper Granforsupper Krångforsupper Selsforsupper Kvistforsenupper Rebnislower Sadvalower Bergnäslower Slagnäslower Bastusellower Grytforslower Gallejaurlower Vargforslower Rengårdlower Båtforslower Finnforslower Granforslower Krångforslower Selsforslower Kvistforsenlower

  • Next, create the following objects (all names in lower-case):

    • instance of class model.
    • water and electricity of class commodity.
    • electricity_node of class node.
    • electricity_load of class unit.
    • some_week of class temporal_block.
    • deterministic of class stochastic_structure.
    • realization of class stochastic_scenario.
  • Finally, create the following objects to get results back from SpineOpt (again, all names in lower-case):

    • my_report of class report.
    • unit_flow, connection_flow, and node_state of class output.
  • Note

    To modify an object after you enter it, right click on it and select Edit... from the context menu.

    Specifying object parameter values

    • To specify the general behaviour of our model, stay in the Spine DB Editor and enter model parameter values as follows:

      • Select the model parameter value data (i.e. select all, Ctrl+A) from the file below and copy it to the clipboard (Ctrl+C): cs-a5-model-parameter-values.txt
      • Select instance in the Object tree and inspect the table in Object parameter value (on the top-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order):
        object_class_name | object_name | parameter_name | alternative_name | value | database
      • Select the first cell under object_class_name and press Ctrl+V. This will paste the model parameter value data from the clipboard into the table. The form should be looking like this: image
    • Specify the resolution of our temporal block some_week in the same way using the data below: cs-a5-temporal_block-parameter-values.txt

    • Specify the behaviour of all system nodes with the data below, where:

      • demand represents the local inflow (negative in most cases).
      • fix_node_state represents fixed reservoir levels (at the beginning and the end).
      • has_state indicates whether or not the node is a reservoir (true for all the upper nodes).
      • state_coeff is the reservoir 'efficienty' (always 1, meaning that there aren't any loses).
      • node_state_cap is the maximum level of the reservoirs.

      To do this in one single step, simply select node in the Object tree and paste the following values in the first empty cell: cs-a5-node-parameter-values.txt

    Establishing relationships

    Tip

    To enter the same text on several cells, copy the text into the clipboard, then select all target cells and press Ctrl+V.

    • Create relationships of the class unit__from_node to represent that a power plant receives water from the station's upper water node, and that the electricity load takes electricity from the common electricity node. Both the power plants and the electricity load belong to the class unit.

      • Select the list of unit and node names from below and copy it to the clipboard (Ctrl+C). cs-a5-unit__from_node.txt
      • In the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), right-click on unit__from_node and select Add relationships from the context menu. This will open the Add relationships dialog.
      • Select the first cell under the unit column and press Ctrl+V. This will paste the list of plant and node names from the clipboard into the table. The form should be looking like this: image
      • Click Ok.
      • Back in the Spine DB Editor, under Relationship tree, double click on unit__from_node to confirm that the relationships are effectively there.
      • From the main menu (Alt + F), select Session -> Commit to open the Commit changes dialog. Enter ‘Add from nodes of power plants‘ as the commit message and click Commit.
    • Create relationships of the class unit__to_node to represent that a power plant releases water to the station's lower water node, and that the power plants supply electricity to the common electricity node. Use the following data and do as before: cs-a5-unit__to_node.txt

    Note

    At this point, you might be wondering what's the purpose of the unit__node__node relationship class. Shouldn't it be enough to have unit__from_node and unit__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the conversion process that happens in the unit, where the water from one node is turned into electricty for another node. And for this purpose, we use a relationship parameter value on the unit__node__node relationships (see Specifying relationship parameter values).

    • Create relationships of the class connection__from_node to represent that water can be either discharged or spilled. If discharged, it is taken from the lower water node of the station, if spilled it is taken from the upper water node of the station. Use the following data and do as before: cs-a5-connection__from_node.txt

    • Create relationships of the class connection__to_node to represent that both discharge and spill are released into the upper node of the next downstream station. Use the following data and do as before: cs-a5-connection__to_node.txt

    Note

    At this point, you might be wondering what's the purpose of the connection__node__node relationship class. Shouldn't it be enough to have connection__from_node and connection__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the delay in the river branches. And for this purpose, we use a relationship parameter value on the connection__node__node relationships (see Specifying relationship parameter values).

    • Create relationships of the class node__commodity to represent that each node has to be in balance, for water nodes with respect to water, for electricity nodes with respect to electricity. This way, you link all nodes to either the commocity water or the commodity electricity. Use the following data and do as before: cs-a5-node__commodity.txt

    • Define that all nodes in our model have to be balanced at each time step. To do this, you create a relationship of the class model__default_temporal_block between the model instance and the temporalblock `someweek` in the same way as before.

    • Define that our model is deterministic. To do this, you create a relationship of the class model__default_stochastic_structure between the model instance and the stochastic structure deterministic, as well as a relationship of class stochastic_structure__stochastic_scenario between the stochastid structure deterministic and the stochastic scenario realization in the same way as before.

    • In order to get the results from running Spine Opt written to the ouput database, create relationships of the class report__output between the report my_report and each of the following output objects: unit_flow, connection_flow, and node_state. In addition, you also need to create a relationship of the class model__report between the model instance and the report my_report.

    Specifying parameter values of the relationships

    • Finally, the values of all parameters have to be entered. Specify the capacity of all hydropower plants, and their respective variable operating cost by entering unit__from_node parameter values as follows:

      • Select the data from the text-box below and copy it to the clipboard (Ctrl+C): cs-a5-unit__from_node-relationship-parameter-values.txt
      • In the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), and click on unit__from_node. Then, go to Relationship parameter value (on the bottom-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order):
        relationship_class_name | object_name_list | parameter_name | alternative_name | value | database
      • Select the first cell under relationship_class_name and press Ctrl+V. This will paste the parameter value data from the clipboard into the table.
    • Specify the conversion ratio between discharged water and generated electricity for each hydropower station as well as a similar conversion rate (set to 1) to represent that water cannot be lost between upper and lower water nodes. Use the following data to enter the parameter values unit__from_node: cs-a5-unit__node__node-relationship-parameter-values.txt

    • Specify the average discharge and spillage in the first hours of the simulation. Use the following data to enter the parameter values connection__from_node: cs-a5-connection__from_node-relationship-parameter-values.txt

    • Finally, specify the delay (the time it takes for the water to run between water nodes) and the transfer ratio (being equal to 1) of different water connections. Use the following data to enter the parameter values connection__node_node: cs-a5-connection__node__node-relationship-parameter-values.txt

    • When you're ready, commit all changes to the database via the main menu (Alt + F).

    Using the Importer

    Additional Steps for Project Setup

    • Drag the Data Connection icon image from the tool bar and drop it into the Design View. This will open the Add Data connection dialogue. Type in ‘Data Connection’ and click on Ok.
    • To import the model into the Spine database, you need to create an Import specification. Create an Import specification by clicking on the small arrow next to the Importer item (in the Main section of the toolbar) and press New. The Importer specification editor will pop-up.
    • Type ‘Import Model’ as the name of the specification. Save the specification by using Ctrl+S and close the window.
    • Drag the newly created Import Model Importer item icon image from the tool bar and drop it into the Design View. This will open the Add Importer dialogue. Type in ‘Import Model’ and click on Ok.
    • Connect ‘Data Connection’ with ‘Import Model’ by first clicking on one of the Data Connection’s connectors and then on one of the Importer’s connectors. Connect similarly the importer with the input database. Now the project should look similar to this: image
    • From the main menu, select File -> Save project.

    Importing the model

    • Download the data and the accompanying mapping (right click on the links, then select Save link as...).
    • Add a reference to the file containing the model.
      • Select the Data Connection item in the Design View to show the Data Connection properties window (on the right side of the window usually).
      • In Data Connection Properties, click on , click on the icon furthest to the left Add file references and select the previously downloaded Excel file.
      • Next, double click on the Import model in the Design view. A window called Select connector for Import Model will pop-up, select Excel and klick OK. Next, still in the Importer specification editor, click on the main menu icon in the top right (or Press Alt + F to automatically display it) and import the mappings previously downloaded (by clicking on Import mappings). Finally, save by clicking Ctrl+S and exit the Importer specification editor.

    Executing the workflow

    Once the workflow is defined and input data is in place, the project is ready to be executed. Hit the Execute project button image on the tool bar.

    You should see ‘Executing All Directed Acyclic Graphs’ printed in the Event log (on the lower left by default). SpineOpt output messages will appear in the Process Log panel in the middle. After some processing, ‘DAG 1/1 completed successfully’ appears and the execution is complete.

    Examining the results

    Select the output data store and open the Spine DB editor.

    image

    To checkout the flow on the electricity load (i.e., the total electricity production in the system), go to Object tree, expand the unit object class, and select electricity_load, as illustrated in the picture above. Next, go to Relationship parameter value and double-click the first cell under value. The Parameter value editor will pop up. You should see something like this:

    image

    Note

    If you have used the importer to instantiate the model you can easily modify the parameters in the model worksheet, run the project and observe the differences in the results. If you need to make changes directly to the input database, in order for the importer not to overwrite them, you will need to dissassociate the importer from the input DB (right click in the connecting yellow arrow between the two items and click on remove).

    + Kvistforsen_pwr_plant
  • Go to Object tree (on the top left of the window, usually), right-click on unit and select Add objects from the context menu. This will open the Add objects dialog.
  • Select the first cell under the object name column and press Ctrl+V. This will paste the list of plant names from the clipboard into that column; the object class name column will be filled automatically with ‘unit‘. The form should now be looking similar to this: image
  • Click Ok.
  • Back in the Spine DB Editor, under Object tree, double click on unit to confirm that the objects are effectively there.
  • Commit changes with the message ‘Add power plants’.
  • Add discharge and spillway connections by creating objects of class connection with the following names:

    RebnistoBergnäsdisch SadvatoBergnäsdisch BergnästoSlagnäsdisch SlagnästoBastuseldisch BastuseltoGrytforsdisch GrytforstoGallejaurdisch GallejaurtoVargforsdisch VargforstoRengårddisch RengårdtoBåtforsdisch BåtforstoFinnforsdisch FinnforstoGranforsdisch GranforstoKrångforsdisch KrångforstoSelsforsdisch SelsforstoKvistforsendisch Kvistforsentodownstreamdisch RebnistoBergnässpill SadvatoBergnässpill BergnästoSlagnässpill SlagnästoBastuselspill BastuseltoGrytforsspill GrytforstoGallejaurspill GallejaurtoVargforsspill VargforstoRengårdspill RengårdtoBåtforsspill BåtforstoFinnforsspill FinnforstoGranforsspill GranforstoKrångforsspill KrångforstoSelsforsspill SelsforstoKvistforsenspill Kvistforsentodownstreamspill

  • Add water nodes by creating objects of class node with the following names:

    Rebnisupper Sadvaupper Bergnäsupper Slagnäsupper Bastuselupper Grytforsupper Gallejaurupper Vargforsupper Rengårdupper Båtforsupper Finnforsupper Granforsupper Krångforsupper Selsforsupper Kvistforsenupper Rebnislower Sadvalower Bergnäslower Slagnäslower Bastusellower Grytforslower Gallejaurlower Vargforslower Rengårdlower Båtforslower Finnforslower Granforslower Krångforslower Selsforslower Kvistforsenlower

  • Next, create the following objects (all names in lower-case):

    • instance of class model.
    • water and electricity of class commodity.
    • electricity_node of class node.
    • electricity_load of class unit.
    • some_week of class temporal_block.
    • deterministic of class stochastic_structure.
    • realization of class stochastic_scenario.
  • Finally, create the following objects to get results back from SpineOpt (again, all names in lower-case):

    • my_report of class report.
    • unit_flow, connection_flow, and node_state of class output.
  • Note

    To modify an object after you enter it, right click on it and select Edit... from the context menu.

    Specifying object parameter values

    • To specify the general behaviour of our model, stay in the Spine DB Editor and enter model parameter values as follows:

      • Select the model parameter value data (i.e. select all, Ctrl+A) from the file below and copy it to the clipboard (Ctrl+C): cs-a5-model-parameter-values.txt
      • Select instance in the Object tree and inspect the table in Object parameter value (on the top-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order):
        object_class_name | object_name | parameter_name | alternative_name | value | database
      • Select the first cell under object_class_name and press Ctrl+V. This will paste the model parameter value data from the clipboard into the table. The form should be looking like this: image
    • Specify the resolution of our temporal block some_week in the same way using the data below: cs-a5-temporal_block-parameter-values.txt

    • Specify the behaviour of all system nodes with the data below, where:

      • demand represents the local inflow (negative in most cases).
      • fix_node_state represents fixed reservoir levels (at the beginning and the end).
      • has_state indicates whether or not the node is a reservoir (true for all the upper nodes).
      • state_coeff is the reservoir 'efficienty' (always 1, meaning that there aren't any loses).
      • node_state_cap is the maximum level of the reservoirs.

      To do this in one single step, simply select node in the Object tree and paste the following values in the first empty cell: cs-a5-node-parameter-values.txt

    Establishing relationships

    Tip

    To enter the same text on several cells, copy the text into the clipboard, then select all target cells and press Ctrl+V.

    • Create relationships of the class unit__from_node to represent that a power plant receives water from the station's upper water node, and that the electricity load takes electricity from the common electricity node. Both the power plants and the electricity load belong to the class unit.

      • Select the list of unit and node names from below and copy it to the clipboard (Ctrl+C). cs-a5-unit__from_node.txt
      • In the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), right-click on unit__from_node and select Add relationships from the context menu. This will open the Add relationships dialog.
      • Select the first cell under the unit column and press Ctrl+V. This will paste the list of plant and node names from the clipboard into the table. The form should be looking like this: image
      • Click Ok.
      • Back in the Spine DB Editor, under Relationship tree, double click on unit__from_node to confirm that the relationships are effectively there.
      • From the main menu (Alt + F), select Session -> Commit to open the Commit changes dialog. Enter ‘Add from nodes of power plants‘ as the commit message and click Commit.
    • Create relationships of the class unit__to_node to represent that a power plant releases water to the station's lower water node, and that the power plants supply electricity to the common electricity node. Use the following data and do as before: cs-a5-unit__to_node.txt

    Note

    At this point, you might be wondering what's the purpose of the unit__node__node relationship class. Shouldn't it be enough to have unit__from_node and unit__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the conversion process that happens in the unit, where the water from one node is turned into electricty for another node. And for this purpose, we use a relationship parameter value on the unit__node__node relationships (see Specifying relationship parameter values).

    • Create relationships of the class connection__from_node to represent that water can be either discharged or spilled. If discharged, it is taken from the lower water node of the station, if spilled it is taken from the upper water node of the station. Use the following data and do as before: cs-a5-connection__from_node.txt

    • Create relationships of the class connection__to_node to represent that both discharge and spill are released into the upper node of the next downstream station. Use the following data and do as before: cs-a5-connection__to_node.txt

    Note

    At this point, you might be wondering what's the purpose of the connection__node__node relationship class. Shouldn't it be enough to have connection__from_node and connection__to_node to represent the topology of the system? The answer is yes; but in addition to topology, we also need to represent the delay in the river branches. And for this purpose, we use a relationship parameter value on the connection__node__node relationships (see Specifying relationship parameter values).

    • Create relationships of the class node__commodity to represent that each node has to be in balance, for water nodes with respect to water, for electricity nodes with respect to electricity. This way, you link all nodes to either the commocity water or the commodity electricity. Use the following data and do as before: cs-a5-node__commodity.txt

    • Define that all nodes in our model have to be balanced at each time step. To do this, you create a relationship of the class model__default_temporal_block between the model instance and the temporalblock `someweek` in the same way as before.

    • Define that our model is deterministic. To do this, you create a relationship of the class model__default_stochastic_structure between the model instance and the stochastic structure deterministic, as well as a relationship of class stochastic_structure__stochastic_scenario between the stochastid structure deterministic and the stochastic scenario realization in the same way as before.

    • In order to get the results from running Spine Opt written to the ouput database, create relationships of the class report__output between the report my_report and each of the following output objects: unit_flow, connection_flow, and node_state. In addition, you also need to create a relationship of the class model__report between the model instance and the report my_report.

    Specifying parameter values of the relationships

    • Finally, the values of all parameters have to be entered. Specify the capacity of all hydropower plants, and their respective variable operating cost by entering unit__from_node parameter values as follows:

      • Select the data from the text-box below and copy it to the clipboard (Ctrl+C): cs-a5-unit__from_node-relationship-parameter-values.txt
      • In the Spine DB Editor, go to Relationship tree (on the bottom left of the window, usually), and click on unit__from_node. Then, go to Relationship parameter value (on the bottom-center of the window, usually). Make sure that the columns in the table are ordered as follows (drag and drop columns if you need to change their order):
        relationship_class_name | object_name_list | parameter_name | alternative_name | value | database
      • Select the first cell under relationship_class_name and press Ctrl+V. This will paste the parameter value data from the clipboard into the table.
    • Specify the conversion ratio between discharged water and generated electricity for each hydropower station as well as a similar conversion rate (set to 1) to represent that water cannot be lost between upper and lower water nodes. Use the following data to enter the parameter values unit__from_node: cs-a5-unit__node__node-relationship-parameter-values.txt

    • Specify the average discharge and spillage in the first hours of the simulation. Use the following data to enter the parameter values connection__from_node: cs-a5-connection__from_node-relationship-parameter-values.txt

    • Finally, specify the delay (the time it takes for the water to run between water nodes) and the transfer ratio (being equal to 1) of different water connections. Use the following data to enter the parameter values connection__node_node: cs-a5-connection__node__node-relationship-parameter-values.txt

    • When you're ready, commit all changes to the database via the main menu (Alt + F).

    Using the Importer

    Additional Steps for Project Setup

    • Drag the Data Connection icon image from the tool bar and drop it into the Design View. This will open the Add Data connection dialogue. Type in ‘Data Connection’ and click on Ok.
    • To import the model into the Spine database, you need to create an Import specification. Create an Import specification by clicking on the small arrow next to the Importer item (in the Main section of the toolbar) and press New. The Importer specification editor will pop-up.
    • Type ‘Import Model’ as the name of the specification. Save the specification by using Ctrl+S and close the window.
    • Drag the newly created Import Model Importer item icon image from the tool bar and drop it into the Design View. This will open the Add Importer dialogue. Type in ‘Import Model’ and click on Ok.
    • Connect ‘Data Connection’ with ‘Import Model’ by first clicking on one of the Data Connection’s connectors and then on one of the Importer’s connectors. Connect similarly the importer with the input database. Now the project should look similar to this: image
    • From the main menu, select File -> Save project.

    Importing the model

    • Download the data and the accompanying mapping (right click on the links, then select Save link as...).
    • Add a reference to the file containing the model.
      • Select the Data Connection item in the Design View to show the Data Connection properties window (on the right side of the window usually).
      • In Data Connection Properties, click on , click on the icon furthest to the left Add file references and select the previously downloaded Excel file.
      • Next, double click on the Import model in the Design view. A window called Select connector for Import Model will pop-up, select Excel and klick OK. Next, still in the Importer specification editor, click on the main menu icon in the top right (or Press Alt + F to automatically display it) and import the mappings previously downloaded (by clicking on Import mappings). Finally, save by clicking Ctrl+S and exit the Importer specification editor.

    Executing the workflow

    Once the workflow is defined and input data is in place, the project is ready to be executed. Hit the Execute project button image on the tool bar.

    You should see ‘Executing All Directed Acyclic Graphs’ printed in the Event log (on the lower left by default). SpineOpt output messages will appear in the Process Log panel in the middle. After some processing, ‘DAG 1/1 completed successfully’ appears and the execution is complete.

    Examining the results

    Select the output data store and open the Spine DB editor.

    image

    To checkout the flow on the electricity load (i.e., the total electricity production in the system), go to Object tree, expand the unit object class, and select electricity_load, as illustrated in the picture above. Next, go to Relationship parameter value and double-click the first cell under value. The Parameter value editor will pop up. You should see something like this:

    image

    Note

    If you have used the importer to instantiate the model you can easily modify the parameters in the model worksheet, run the project and observe the differences in the results. If you need to make changes directly to the input database, in order for the importer not to overwrite them, you will need to dissassociate the importer from the input DB (right click in the connecting yellow arrow between the two items and click on remove).

    diff --git a/dev/tutorial/reserves/index.html b/dev/tutorial/reserves/index.html index 4ce709cc2c..a4cf3c7cfa 100644 --- a/dev/tutorial/reserves/index.html +++ b/dev/tutorial/reserves/index.html @@ -1,2 +1,2 @@ -Reserve requirements · SpineOpt.jl

    Reserve definition tutorial

    This tutorial provides a step-by-step guide to include reserve requirements in a simple energy system with Spine Toolbox for SpineOpt.

    Introduction

    Welcome to our tutorial, where we will walk you through the process of adding a new reserve node in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.

    Reserves refer to the capacity or energy that is kept as a backup to ensure the power system's reliability. This reserve capacity can be brought online automatically or manually in the event of unforeseen system disruptions such as generation failure, transmission line failure, or a sudden increase in demand. Operating reserves are essential to ensure that there is always enough generation capacity available to meet demand, even in the face of unforeseen system disruptions.

    Model assumptions

    • The reserve node has a requirement of 20MW for upwards reserve
    • Power plants 'a' and 'b' can both provide reserve to this node

    image

    Guide

    Entering input data

    • Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.
    • Locate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.
    • Select the 'input' Data Store item in the Design View.
    • Go to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.

    In this tutorial, you will learn how to add a new reserve node to the Simple System.

    Creating objects

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Right click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.
    • Enter the names for the new reserve node as seen in the image below, then press Ok. This will create a new object of class node, called upward_reserve_node.

    image

    • Right click on the node class, and select Add object group from the context menu. The Add object group dialog will pop up. In the Group name field write upward_reserve_group to refer to this group. Then, add as a members of the group the nodes electricity_node and upward_reserve_node, as shown in the image below; then press Ok.
    Note

    In SpineOpt, groups of nodes allow the user to create constraints that involve variables from its members. Later in this tutorial, the group named upward_reserve_group will help to link the flow variables for electricity production and reserve procurement.

    image

    Establishing relationships

    • Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.
    • Select the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into both the upward_reserve_node and the upward_reserve_group.

    image

    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Enter report1 under report, and variable_om_costs under output. Repeat the same procedure in the second line to add the res_proc_costs under output as seen in the image below; then press Ok. This will write the total vom_cost and procurement reserve cost values in the objective function to the output database as a part of report1.

    image

    Specifying object parameter values

    • Back to Object tree, expand the node class and select upward_reserve_node.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:
      • demand parameter and the Base alternative, and enter the value 20. This will establish that there's a demand of '20' at the reverse node.
      • is_reserve_node parameter and the Base alternative, and enter the value True. This will establish that it is a reverse node.
      • upward_reserve parameter and the Base alternative, then right-click on the value cell and then, in the context menu, select 'Edit...' and select the option True. This will establish the direction of the reserve is upwards.
      • nodal_balance_sense parameter and the Base alternative, and enter the value $\geq$. This will establish that the total reserve procurement must be greater or equal than the reserve demand.

    image

    • Select upward_reserve_group in the Object tree.

    • In the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that there is no need to create an extra balance between the members of the group.

    image

    Specifying relationship parameter values

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity to provide reserve for power_plant_a.

    Note

    The value is equal to the unit capacity defined for the electricity node. However, the value can be lower if the unit cannot provide reserves with its total capacity.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity to provide reserve for power_plant_b.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_group.

    • In the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:

      • unit_capacity parameter and the Base alternative, and enter the value 100. This will set the total capacity for power_plant_a in the group.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_group.

    • In the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:

      • unit_capacity parameter and the Base alternative, and enter the value 200. This will set the total capacity for power_plant_b in the group.

    image

    When you're ready, save/commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    Examining the results

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables or use a pivot table.

    • For the pivot table, press Alt + F for the shortcut to the hamburger menu, and select Pivot -> Index.

    • Select report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.

    • Under alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.

    • The Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.

    image

    As anticipated, the power_plant_b is supplying the necessary reserve due to its surplus capacity, while power_plant_a is operating at full capacity. Additionally, in this model, we have not allocated a cost for reserve procurement. One way to double-check it is by selecting report__model under Relationship tree and look at the costs the Pivot table, see image below.

    image

    So, is it possible to assign costs to this reserve procurement in SpineOpt? Yes, it is indeed possible.

    Specifying a reserve procurement cost value

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 5 as seen in the image below. This will set the cost of providing reserve for power_plant_a.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 35 as seen in the image below. This will set the cost of providing reserve for power_plant_b.

    image

    Don't forget to commit the new changes to the database!

    Executing the worflow and examining the results again

    • Go back to Spine Toolbox's main window, and hit again the Execute project button as before.

    • Select the output data store and open the Spine DB editor. You can inspect results as before, which should look like the image below.

    image

    Since the cost of reserve procurement is way cheaper in power_plant_a than in power_plant_b, then the optimal solution is to reduce the production of electricity in power_plant_a to provide reserve with this unit rather than power_plant_b as before. By looking at the total costs, we can see that the reserve procurement costs are no longer zero.

    image

    +Reserve requirements · SpineOpt.jl

    Reserve definition tutorial

    This tutorial provides a step-by-step guide to include reserve requirements in a simple energy system with Spine Toolbox for SpineOpt.

    Introduction

    Welcome to our tutorial, where we will walk you through the process of adding a new reserve node in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.

    Reserves refer to the capacity or energy that is kept as a backup to ensure the power system's reliability. This reserve capacity can be brought online automatically or manually in the event of unforeseen system disruptions such as generation failure, transmission line failure, or a sudden increase in demand. Operating reserves are essential to ensure that there is always enough generation capacity available to meet demand, even in the face of unforeseen system disruptions.

    Model assumptions

    • The reserve node has a requirement of 20MW for upwards reserve
    • Power plants 'a' and 'b' can both provide reserve to this node

    image

    Guide

    Entering input data

    • Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.
    • Locate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.
    • Select the 'input' Data Store item in the Design View.
    • Go to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.

    In this tutorial, you will learn how to add a new reserve node to the Simple System.

    Creating objects

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Right click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.
    • Enter the names for the new reserve node as seen in the image below, then press Ok. This will create a new object of class node, called upward_reserve_node.

    image

    • Right click on the node class, and select Add object group from the context menu. The Add object group dialog will pop up. In the Group name field write upward_reserve_group to refer to this group. Then, add as a members of the group the nodes electricity_node and upward_reserve_node, as shown in the image below; then press Ok.
    Note

    In SpineOpt, groups of nodes allow the user to create constraints that involve variables from its members. Later in this tutorial, the group named upward_reserve_group will help to link the flow variables for electricity production and reserve procurement.

    image

    Establishing relationships

    • Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.
    • Select the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into both the upward_reserve_node and the upward_reserve_group.

    image

    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Enter report1 under report, and variable_om_costs under output. Repeat the same procedure in the second line to add the res_proc_costs under output as seen in the image below; then press Ok. This will write the total vom_cost and procurement reserve cost values in the objective function to the output database as a part of report1.

    image

    Specifying object parameter values

    • Back to Object tree, expand the node class and select upward_reserve_node.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:
      • demand parameter and the Base alternative, and enter the value 20. This will establish that there's a demand of '20' at the reverse node.
      • is_reserve_node parameter and the Base alternative, and enter the value True. This will establish that it is a reverse node.
      • upward_reserve parameter and the Base alternative, then right-click on the value cell and then, in the context menu, select 'Edit...' and select the option True. This will establish the direction of the reserve is upwards.
      • nodal_balance_sense parameter and the Base alternative, and enter the value $\geq$. This will establish that the total reserve procurement must be greater or equal than the reserve demand.

    image

    • Select upward_reserve_group in the Object tree.

    • In the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that there is no need to create an extra balance between the members of the group.

    image

    Specifying relationship parameter values

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity to provide reserve for power_plant_a.

    Note

    The value is equal to the unit capacity defined for the electricity node. However, the value can be lower if the unit cannot provide reserves with its total capacity.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity to provide reserve for power_plant_b.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_group.

    • In the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:

      • unit_capacity parameter and the Base alternative, and enter the value 100. This will set the total capacity for power_plant_a in the group.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_group.

    • In the Relationship parameter table (typically at the bottom-center), select the following parameter as seen in the image below:

      • unit_capacity parameter and the Base alternative, and enter the value 200. This will set the total capacity for power_plant_b in the group.

    image

    When you're ready, save/commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    Examining the results

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables or use a pivot table.

    • For the pivot table, press Alt + F for the shortcut to the hamburger menu, and select Pivot -> Index.

    • Select report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.

    • Under alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.

    • The Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.

    image

    As anticipated, the power_plant_b is supplying the necessary reserve due to its surplus capacity, while power_plant_a is operating at full capacity. Additionally, in this model, we have not allocated a cost for reserve procurement. One way to double-check it is by selecting report__model under Relationship tree and look at the costs the Pivot table, see image below.

    image

    So, is it possible to assign costs to this reserve procurement in SpineOpt? Yes, it is indeed possible.

    Specifying a reserve procurement cost value

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 5 as seen in the image below. This will set the cost of providing reserve for power_plant_a.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_b | upward_reserve_node.

    • In the Relationship parameter table (typically at the bottom-center), select the reserve_procurement_cost parameter and the Base alternative, and enter the value 35 as seen in the image below. This will set the cost of providing reserve for power_plant_b.

    image

    Don't forget to commit the new changes to the database!

    Executing the worflow and examining the results again

    • Go back to Spine Toolbox's main window, and hit again the Execute project button as before.

    • Select the output data store and open the Spine DB editor. You can inspect results as before, which should look like the image below.

    image

    Since the cost of reserve procurement is way cheaper in power_plant_a than in power_plant_b, then the optimal solution is to reduce the production of electricity in power_plant_a to provide reserve with this unit rather than power_plant_b as before. By looking at the total costs, we can see that the reserve procurement costs are no longer zero.

    image

    diff --git a/dev/tutorial/simple_system/index.html b/dev/tutorial/simple_system/index.html index 1b1c297fe2..f5c57c5cf2 100644 --- a/dev/tutorial/simple_system/index.html +++ b/dev/tutorial/simple_system/index.html @@ -1,2 +1,2 @@ -Simple system · SpineOpt.jl

    Simple System tutorial

    Welcome to Spine Toolbox's Simple System tutorial.

    This tutorial provides a step-by-step guide to setup a simple energy system on Spine Toolbox.

    Introduction

    Model assumptions

    • Two power plants take fuel from a source node and release electricity to another node in order to supply a demand.
    • Power plant 'a' has a capacity of 100 MWh, a variable operating cost of 25 euro/fuel unit, and generates 0.7 MWh of electricity per unit of fuel.
    • Power plant 'b' has a capacity of 200 MWh, a variable operating cost of 50 euro/fuel unit, and generates 0.8 MWh of electricity per unit of fuel.
    • The demand at the electricity node is 150 MWh.
    • The fuel node is able to provide infinite energy.

    image

    Installation and upgrades

    If you haven't yet installed the tools yet, please follow the installation guides:

    If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.

    • For Spine Toolbox:

      • If installed with pipx, then use python -m pipx upgrade spinetoolbox
      • If installed from sources using git, then git pull, python -m pip install -U -r requirements.txt
    • For SpineOpt: SpineOpt upgrade guide

    Guide

    Entering input data

    Importing the SpineOpt database template

    • Download the SpineOpt database template and the basic SpineOpt model (right click on the links, then select Save link as...)

    • Select the 'input' Data Store item in the Design View.

    • Go to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB editor, looking similar to this:

    image

    Note

    The Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.

    • Press Alt + F to display the main menu, select File -> Import..., and then select the template file you previously downloaded (spineopt_template.json). The contents of that file will be imported into the current database, and you should then see classes like 'commodity', 'connection' and 'model' under the root node in the Object tree (on the left). Then import the second file (basic_model_template.json).

    • From the main menu, select Session -> Commit. Enter 'Import SpineOpt template' as message in the popup dialog, and click Commit.

    Note

    The SpineOpt basic template contains (i) the fundamental entity classes and parameter definitions that SpineOpt recognizes and expects; and (ii) some predefined entities for a common deterministic model with a 'flat' temporal structure.

    Creating objects

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.

    • Right click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.

    • Enter the names for the system nodes as seen in the image below, then press Ok. This will create two objects of class node, called fuel_node and electricity_node.

    image

    • Right click on the unit class, and select Add objects from the context menu. The Add objects dialog will pop up.
    Note

    In SpineOpt, nodes are points where an energy balance takes place, whereas units are energy conversion devices that can take energy from nodes, and release energy to nodes.

    • Enter the names for the system units as seen in the image below, then press Ok. This will create two objects of class unit, called power_plant_a and power_plant_b.

    image

    Note

    To modify an object after you enter it, right click on it and select Edit... from the context menu.

    Establishing relationships

    • Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.

    • Right click on the unit__from_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Select the names of the two units and their sending nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b take energy from the fuel_node.

    image

    • Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Select the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into the electricity_node.

    image

    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Enter report1 under report, and unit_flow under output, as seen in the image below; then press Ok. This will tell SpineOpt to write the value of the unit_flow optimization variable to the output database, as part of report1.

    image

    Note

    In SpineOpt, outputs represent optimization variables that can be written to the output database as part of a report.

    Specifying object parameter values

    • Back to Object tree, expand the node class and select electricity_node.

    • Locate the Object parameter table (typically at the top-center).

    • In the Object parameter table (typically at the top-center), select the demand parameter and the Base alternative, and enter the value 100 as seen in the image below. This will establish that there's a demand of '100' at the electricity node.

    image

    • Select fuel_node in the Object tree.

    • In the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that the fuel node is not balanced, and thus provide as much fuel as needed.

    image

    Specifying relationship parameter values

    • In Relationship tree, expand the unit__from_node class and select power_plant_a | fuel_node.

    • In the Relationship parameter table (typically at the bottom-center), select the vom_cost parameter and the Base alternative, and enter the value 25 as seen in the image below. This will set the operating cost for power_plant_a.

    image

    • Select power_plant_b | fuel_node in the Relationship tree.

    • In the Relationship parameter table, select the vom_cost parameter and the Base alternative, and enter the value 50 as seen in the image below. This will set the operating cost for power_plant_b.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | electricity_node.

    • In the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity for power_plant_a.

    image

    • Select power_plant_b | electricity_node in the Relationship tree.

    • In the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity for power_plant_b.

    image

    • In Relationship tree, select the unit__node__node class, and come back to the Relationship parameter table.

    • In the Relationship parameter table, select power_plant_a | electricity_node | fuel_node under object name list, fix_ratio_out_in_unit_flow under parameter name, Base under alternative name, and enter 0.7 under value. Repeat the operation for power_plant_b, but this time enter 0.8 under value. This will set the conversion ratio from fuel to electricity for power_plant_a and power_plant_b to 0.7 and 0.8, respectively. It should like the image below.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt 1' Tool. You should see the output from SpineOpt in the Julia Console.

    Examining the results

    • Select the output data store and open the Spine DB editor.
    • Press Alt + F to display the main menu, and select Pivot -> Index.
    • Select report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.
    • Under alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.
    • The Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.

    image

    +Simple system · SpineOpt.jl

    Simple System tutorial

    Welcome to Spine Toolbox's Simple System tutorial.

    This tutorial provides a step-by-step guide to setup a simple energy system on Spine Toolbox.

    Introduction

    Model assumptions

    • Two power plants take fuel from a source node and release electricity to another node in order to supply a demand.
    • Power plant 'a' has a capacity of 100 MWh, a variable operating cost of 25 euro/fuel unit, and generates 0.7 MWh of electricity per unit of fuel.
    • Power plant 'b' has a capacity of 200 MWh, a variable operating cost of 50 euro/fuel unit, and generates 0.8 MWh of electricity per unit of fuel.
    • The demand at the electricity node is 150 MWh.
    • The fuel node is able to provide infinite energy.

    image

    Installation and upgrades

    If you haven't yet installed the tools yet, please follow the installation guides:

    If you are not sure whether you have the latest version, please upgrade to ensure compatibility with this guide.

    • For Spine Toolbox:

      • If installed with pipx, then use python -m pipx upgrade spinetoolbox
      • If installed from sources using git, then git pull, python -m pip install -U -r requirements.txt
    • For SpineOpt: SpineOpt upgrade guide

    Guide

    Entering input data

    Importing the SpineOpt database template

    • Download the SpineOpt database template and the basic SpineOpt model (right click on the links, then select Save link as...)

    • Select the 'input' Data Store item in the Design View.

    • Go to Data Store Properties and hit Open editor. This will open the newly created database in the Spine DB editor, looking similar to this:

    image

    Note

    The Spine DB editor is a dedicated interface within Spine Toolbox for visualizing and managing Spine databases.

    • Press Alt + F to display the main menu, select File -> Import..., and then select the template file you previously downloaded (spineopt_template.json). The contents of that file will be imported into the current database, and you should then see classes like 'commodity', 'connection' and 'model' under the root node in the Object tree (on the left). Then import the second file (basic_model_template.json).

    • From the main menu, select Session -> Commit. Enter 'Import SpineOpt template' as message in the popup dialog, and click Commit.

    Note

    The SpineOpt basic template contains (i) the fundamental entity classes and parameter definitions that SpineOpt recognizes and expects; and (ii) some predefined entities for a common deterministic model with a 'flat' temporal structure.

    Creating objects

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.

    • Right click on the [node] class, and select Add objects from the context menu. The Add objects dialog will pop up.

    • Enter the names for the system nodes as seen in the image below, then press Ok. This will create two objects of class node, called fuel_node and electricity_node.

    image

    • Right click on the unit class, and select Add objects from the context menu. The Add objects dialog will pop up.
    Note

    In SpineOpt, nodes are points where an energy balance takes place, whereas units are energy conversion devices that can take energy from nodes, and release energy to nodes.

    • Enter the names for the system units as seen in the image below, then press Ok. This will create two objects of class unit, called power_plant_a and power_plant_b.

    image

    Note

    To modify an object after you enter it, right click on it and select Edit... from the context menu.

    Establishing relationships

    • Always in the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.

    • Right click on the unit__from_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Select the names of the two units and their sending nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b take energy from the fuel_node.

    image

    • Right click on the unit__to_node class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Select the names of the two units and their receiving nodes, as seen in the image below; then press Ok. This will establish that both power_plant_a and power_plant_b release energy into the electricity_node.

    image

    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.

    • Enter report1 under report, and unit_flow under output, as seen in the image below; then press Ok. This will tell SpineOpt to write the value of the unit_flow optimization variable to the output database, as part of report1.

    image

    Note

    In SpineOpt, outputs represent optimization variables that can be written to the output database as part of a report.

    Specifying object parameter values

    • Back to Object tree, expand the node class and select electricity_node.

    • Locate the Object parameter table (typically at the top-center).

    • In the Object parameter table (typically at the top-center), select the demand parameter and the Base alternative, and enter the value 100 as seen in the image below. This will establish that there's a demand of '100' at the electricity node.

    image

    • Select fuel_node in the Object tree.

    • In the Object parameter table, select the balance_type parameter and the Base alternative, and enter the value balance_type_none as seen in the image below. This will establish that the fuel node is not balanced, and thus provide as much fuel as needed.

    image

    Specifying relationship parameter values

    • In Relationship tree, expand the unit__from_node class and select power_plant_a | fuel_node.

    • In the Relationship parameter table (typically at the bottom-center), select the vom_cost parameter and the Base alternative, and enter the value 25 as seen in the image below. This will set the operating cost for power_plant_a.

    image

    • Select power_plant_b | fuel_node in the Relationship tree.

    • In the Relationship parameter table, select the vom_cost parameter and the Base alternative, and enter the value 50 as seen in the image below. This will set the operating cost for power_plant_b.

    image

    • In Relationship tree, expand the unit__to_node class and select power_plant_a | electricity_node.

    • In the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 100 as seen in the image below. This will set the capacity for power_plant_a.

    image

    • Select power_plant_b | electricity_node in the Relationship tree.

    • In the Relationship parameter table, select the unit_capacity parameter and the Base alternative, and enter the value 200 as seen in the image below. This will set the capacity for power_plant_b.

    image

    • In Relationship tree, select the unit__node__node class, and come back to the Relationship parameter table.

    • In the Relationship parameter table, select power_plant_a | electricity_node | fuel_node under object name list, fix_ratio_out_in_unit_flow under parameter name, Base under alternative name, and enter 0.7 under value. Repeat the operation for power_plant_b, but this time enter 0.8 under value. This will set the conversion ratio from fuel to electricity for power_plant_a and power_plant_b to 0.7 and 0.8, respectively. It should like the image below.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt 1' Tool. You should see the output from SpineOpt in the Julia Console.

    Examining the results

    • Select the output data store and open the Spine DB editor.
    • Press Alt + F to display the main menu, and select Pivot -> Index.
    • Select report__unit__node__direction__stochastic_scenario under Relationship tree, and the first cell under alternative in the Frozen table.
    • Under alternative in the Frozen table, you can choose results from different runs. Pick the run you want to view. If the workflow has been run several times, the most recent run will usually be found at the bottom.
    • The Pivot table will be populated with results from the SpineOpt run. It will look something like the image below.

    image

    diff --git a/dev/tutorial/tutorialTwoHydro/index.html b/dev/tutorial/tutorialTwoHydro/index.html index 7830263fd4..d4f2ce1127 100644 --- a/dev/tutorial/tutorialTwoHydro/index.html +++ b/dev/tutorial/tutorialTwoHydro/index.html @@ -1,2 +1,2 @@ -Two hydro plants · SpineOpt.jl

    Hydro Power Planning

    Welcome to this Spine Toolbox tutorial for building hydro power planning models. The tutorial guides you through the implementation of different ways of modelling hydrodologically-coupled hydropower systems.

    Introduction

    This tutorial aims at demonstrating how we can model a hydropower system in Spine (SpineOpt.jl and Spine-Toolbox) with different assumptions and goals. It starts off by setting up a simple model of system of two hydropower plants and gradually introduces additional features. The goal of the model is to capture the combined operation of two hydropower plants (Språnget and Fallet) that operate on the same river as shown in the picture bellow. Each power plant has its own reservoir and generates electricity by discharging water. The plants might need to spill water, i.e., release water from their reservoirs without generating electricity, for various reasons. The water discharged or spilled by the upstream power plant follows the river route and becomes available to the downstream power plant.

    A system of two hydropower plants.

    A system of two hydropower plants

    In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing-the-spineopt-database-template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.

    Note

    Just remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Two_hydro’) in the corresponding step, so to not mix up the Spine Toolbox projects!

    That is all you need at the moment, you can now start inserting the data.

    Setting up a Basic Hydropower Model

    For creating a SpineOpt model you need to create Objects, Relationships (associating the objects), and in some cases, parameters values accompanying them. To do this, open the input database using the Spine DB Editor (double click on the input database in the Design View pane of Spine Toolbox).

    Note

    To save your work in the Spine DB Editor you need to commit your changes (please check the Simple System tutorial for how to do that). As a good practice, you should commit often as you enter the data in the model to avoid data loss.

    Defining objects

    Commodities

    Since we are modelling a hydropower system we will have to define two commodities, water and electricity. In the Spine DB editor, locate the Object tree, expand the root element if required, right click on the commodity class, and select Add objects from the context menu. In the Add objects dialogue that should pop up, enter the object names for the commodities as you see in the image below and then press Ok.

    image

    Defining commodities.

    Nodes

    Follow a similar path to add nodes, right click on the node class, and select Add objects from the context menu. In the dialogue, enter the node names as shown:

    image

    Defining nodes.

    Nodes in SpineOpt are used to balance commodities. As you noticed, we defined two nodes for each hydropower station (water nodes) and a single electricity node. This is one possible way to model the hydropower plant operation. This will become clearer in the next steps, but in a nutshell, the upper node represents the water arriving at each plant, while the lower node represents the water that is discharged and becomes available to the next plant.

    Connections

    Similarly, add connections, right click on the connection class, select Add objects from the context menu and add the following connections:

    image

    Defining connections.

    Connections enable the nodes to interact. Since, for each plant we need to model the amount of water that is discharged and the amount that is spilled, we must define two connections accordingly. When defining relationships we shall associate the connections with the nodes.

    Units

    To convert from one type of commodity associated with one node to another, you need a unit. You guessed it! Right click on the unit class, select Add objects from the context menu and add the following units:

    image

    Defining units.

    We have defined one unit for each hydropower plant that converts water to electricity and an additional unit that we will use to model the income from selling the electricity production in the electricity market.

    Relationships

    Assinging commodities to nodes

    Since we have defined more than one commodities, we need to assign them to nodes. In the Spine DB editor, locate the Relationship tree, expand the root element if required, right click on the node__commodity class, and select Add relationships from the context menu. In the Add relationships dialogue, enter the following relationships as you see in the image below and then press Ok.

    image

    Introducing node__commodity relationships.

    Associating connections to nodes

    Next step is to define the topology of flows between the nodes. To do that insert the following relationships in the connection__from_node class:

    image

    Introducing connection__from_node relationships.

    as well as the following the following connection__node_node relationships as you see in the figure:

    Introducing connection__node_node relationships.

    Introducing connection__node_node relationships.

    Placing the units in the model

    To define the topology of the units and be able to introduce their parameters later on, you need to define the following relationships in the unit__from_node class:

    Introducing unit__from_node relationships.

    Introducing unit__from_node relationships.

    in the unit__node_node class:

    Introducing unit__node_node relationships.

    Introducing unit__node_node relationships.

    and in the unit__to_node class as you see in the following figure:

    Introducing unit__to_node relationships.

    Introducing unit__to_node relationships.

    Defining the report outputs

    To force Spine to export the optimal values of the optimization variables to the output database you need to specify them in the form of report_output relationships. Add the following relationships to the report_output class:

    Introducing report outputs with report_output relationships.

    Introducing report outputs with report_output relationships.

    Objects and Relationships parameter values

    Defining model parameter values

    The specify modelling properties of both objects and relationships you need to introduce respective parameter values. To introduce object parameter values first select the model class in the Object tree and enter the following values in the Object parameter value pane:

    Defining model execution parameters.

    Defining model execution parameters.

    Observe the difference between the Object parameter value and the Object parameter definition sub-panes of the Object parameter value pane. The first one is for the modeller to introduce values for specific parameters, while the second one holds the definition of all available parameters with their default values (these are overwritten when the user introduces their own values). Feel free to explore the different parameters and their default values. While entering data in each row you will also observe that, in most cases, clicking on each cell activates a drop-down list of elements that the user must choose from. In the case of the value cells, however, unless you need to input a scalar value or a string, you should right-click on the cell and select edit for specifying the data type of the parameter value. As you see in the figure above, for the first duration_unit parameter you is of type string, while the model_start and model_end parameters are of type Date time. The Date time parameters can be edited by right-clicking on the corresponding value cells, selecting Edit, and then inserting the Date time values that you see in the figure above in the Datetime field using the correct format.

    Defining node parameter values

    Going back to hydropower modelling, we need to specify several parameters for the nodes of the systems. In the same pane as before, but this time selecting the node class from the Object tree, we need to add the following entries:

    Defining model execution parameters.

    Defining model execution parameters.

    Before we go through the interpretation of each parameter, click on the following link for each fix_node_state parameter (Node state Språnget, Node state Fallet), select all, copy the data and then paste them directly in the respective parameter value cell. Spine should automatically detect and input the timeseries data as a parameter value. The data type for those entries should be Timeseries as shown in the figure above. Alternatively, you can select the data type as Timeseries and manually insert the data (values with their corresponding datetimes).

    To model the reservoirs of each hydropower plant, we leverage the state feature that a node can have to represent storage capability. We only need to do this for one of the two nodes that we have used to model each plant and we choose the upper level node. To define storage, we set the value of the parameter has_state as True (be careful to not set it as a string but select the boolean true value by right clicking and selecting Edit in the respective cells). This activates the storage capability of the node. Then, we need to set the capacity of the reservoir by setting the node_state_cap parameter value. Finally, we fix the initial and final values of the reservoir by setting the parameter fix_node_state to the respective values (we introduce nan values for the time steps that we don't want to impose such constraints). To model the local inflow we use the demand parameter but using the negated value of the actual inflow, due to the definition of the parameter in Spine as a demand.

    Defining the temporal resolution of the model

    Spine automates the creation of the temporal resolution of the optimization model and even supports different temporal resolutions for different parts of the model. To define a model with an hourly resolution we select the temporal_block class in the Object tree and we set the resolution parameter value to 1h as shown in the figure:

    Setting the temporal resolution of the model.

    Setting the temporal resolution of the model.

    Defining connection parameter values

    The water that is discharged from Språnget will flow from Språnget_lower node to Fallet_upper through the Språnget_to_Fallet_disc connection, while the water that is spilled will flow from Språnget_upper directly to to Fallet_upper through the Språnget_to_Fallet_spill connection. To model this we need to select the connection__node_node class in the Relationship tree and add the following entries in the Relationship parameter value pane, as shown next:

    Defining discharge and spillage ratio flows.

    Defining discharge and spillage ratio flows.

    Defining unit parameter values

    Similarly, for each one of the unit__from_node, unit__node_node, and unit__to_node relationship classes we need to add the the maximal water that can be discharged by each hydropower plant:

    Setting the maximal water discharge of each plant.

    Setting the maximal water discharge of each plant.

    To define the income from selling the produced electricity we use the vom_cost parameter and negate the values of the electricity prices. To automatically insert the timeseries data in Spine, click on the Electricity prices timeseries, select all values, copy, and paste them, after having selected the value cell of the corresponding row. You can plot and edit the timeseries data by double clicking on the same cell afterwards:

    Previewing and editing the electricity prices timeseries.

    Previewing and editing the electricity prices timeseries.

    Carrying on with our hydropower model we must define the conversion ratios between the nodes. Assuming that water is not "lost" from the upper node toward the lower node and electricity is produced with the discharged water with a given efficiency we define the following parameter values for each hydropower plant, in the unit__node_node class:

    Defining conversion efficiencies.

    Defining conversion efficiencies.

    Lastly, we can define the maximal electricity production of each plant by inserting the following unit__to_node relationship parameter values:

    Setting the maximal electricity production of each plant.

    Setting the maximal electricity production of each plant.

    Hooray! You can now commit the database, close the Spine DB Editor and run your model! Go to the main Spine window and click on Execute image.

    Examining the results

    Select the output data store and open the Spine DB editor. To quickly plot some results, you can expand the unit class in the Object tree and select the electricity_load unit. In the Relationship parameter value pane double click on the value cell of

    report1 | electricity_load | electricity_node | from_node | realization

    object name. This will open a plotting window from were you can also examine closer and retrieve the data, as shown in the next figure. The unit_flow variable of the electricity_load unit represents the total electricity production in the system:

    Total electricity produced in the system.

    Total electricity produced in the system.

    Now, take to a minute to reflect on how you could retrieve the data representing the water that is discharged by each hydropower plant as shown in the next figure:

    Water discharge of Språnget hydropower plant.

    Water discharge of Språnget hydropower plant.

    The right answer is that you need to select some hydropower plant (e.g., Språnget) and then double-click on the value cell of the object name

    report1 | Språnget_pwr_plant | Språnget_lower | to_node | realization

    or

    report1 | Språnget_pwr_plant | Språnget_upper | from_node | realization

    It could be useful to also reflect on why these objects give the same results, and what do the results from the third element represent. (Hint: observe the to_ or from_ directions in the object names). As an exercise, you can try to retrieve the timeseries data for spilled water as well as the water levels at the reservoir of each hydropower plant.

    You can further explore the model, or make changes in the input database to observe how these affect the results, e.g., you can use different electricity prices, values for the reservoir capacity (and initialization points), as well as change the temporal resolution of the model. All you need to do is commit the changes and run your model. Every time that you run the model, your results are appended in the output database with an execution timestamp. You can however filter your results per execution, by selecting the Alternative that you want from the Alternative/Scenario tree pane. You can use the exporter too to export specific variables in an Excel sheet. Alternatively, you can export all the data of the output database by going to the main menu (Press Alt + F to display it), selecting File -> Export, then select the items that you want, click ok and export the data in Excel, or json format.

    In the following, we extend this simple hydropower system to include more elaborate modelling choices.

    Note

    In each of the next sections, we perform incremental changes to the initial simple hydropower model. If you want to keep the database that you created, you can duplicate the database file (right-click on the input database and select Duplicate and duplicate files) and perform the changes in the new database. You need to configure the workflow accordingly in order to run the database you want (please check the Simple System tutorial for how to do that).

    Maximisation of Stored Water

    Instead of fixing the water content of the reservoirs at the end of the planning period, we can consider that the remaining water in the reservoirs has a value and then maximize the value along with the revenues for producing electricity within the planning horizon. This objective term is often called the Value of stored water and we can approximate it by assuming that this water will be used to generate electricity in the future that would be sold at a forecasted price. The water stored in the upstream hydropower plant will become also available to the downstream plant and this should be taken into account.

    To model the value of stored water we need to make some additions and modifications to the initial model.

    • First, add a new node (see adding nodes) and give it a name (e.g., stored_water). This node will accumulate the water stored in the reservoirs at the end of the planning horizon. Associate the node with the water commodity (see node__commodity).

    • Add three more units (see adding units); two will transfer the water at the end of the planning horizon in the new node that we just added (e.g., Språnget_stored_water, Fallet_stored_water), and one will be used as a sink introducing the value of stored water in the objective function (e.g., value_stored_water).

    • To establish the topology of the new units and nodes (see adding unit relationships):

      • add one unit__from_node relationship, between the value_stored_water unit from the stored_water node, another one between the Språnget_stored_water unit from the Språnget_upper node and one for Faller_stored_water from Fallet_upper.
      • add one unit__node__node relationship between the Språnget_stored_water unit with the stored_water and Språnget_upper nodes and another one for Fallet_stored_water unit with the stored_water and Fallet_upper nodes,
      • add a unit__to_node relationship between the Fallet_stored_water and the stored_water node and another one between the Språnget_stored_water unit and the stored_water node.
    • Now we need to make some changes in object parameter values.

      • Extend the planning horizon of the model by one hour, i.e., change the model_end parameter value to 2021-01-02T01:00:00 (right-click on the value cell, click edit and paste the new datetime in the popup window).
      • Remove the fix_node_state parameter values for the end of the optimization horizon as you seen in the following figure: double click on the value cell of the Språnget_upper and Fallet_upper nodes, select the third data row, right-click, select Remove rows, and click OK.
      • Add an electricity price for the extra hour. Enter the parameter vom_cost on the unit__from_node relationship between the electricity_node and the electricity_load and set 0 as the price of electricity for the last hour 2021-01-02T00:00:00. The price is set to zero to ensure no electricity is sold during this hour.

      Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes. Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.

    • Finally, we need to add some relationship parameter values for the new units:

      • Add a vom_cost parameter value on a value_stored_water|stored_water instance of a unit__from_node relationship, as you see in the figure bellow. For the timeseries you can copy-paste the data directly from this link. If you examine the timeseries data you'll notice that we have imposed a zero cost for all the optimisation horizon, while we use an assumed future electricity value for the additional time step at the end of the horizon.

      Adding vom_cost parameter value on the value_stored_water unit. Adding vom_cost parameter value on the value_stored_water unit.

      • Add two fix_ratio_out_in_unit_flow parameter values as you see in the figure bellow. The efficiency of Fallet_stored_water is the same as the Fallet_pwr_plant as the water in Fallet's reservoir will be used to produce electricity by the the Fallet plant only. On the other hand, the water from Språnget's reservoir will be used both by Fallet and Språnget plant, therefore we use the sum of the two efficiencies in the parameter value of Språnget_stored_water.

      Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units. Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.

    You can now commit your changes in the database, execute the project and examine the results! As an exercise, try to retrieve the value of stored water as it is calculated by the model.

    Spillage Constraints - Minimisation of Spilt Water

    It might be the case that we need to impose certain limits to the amount of water that is spilt on each time step of the planning horizon, e.g., for environmental reasons, there can be a minimum and a maximum spillage level. At the same time, to avoid wasting water that could be used for producing electricity, we could explicitly impose the spillage minimisation to be added in the objective function.

    • Add one unit (see adding units) to impose the spillage constraints to each plant and name it (for example Språnget_spill).

    • Remove the Språnget_to_Fallet_spill connection (in the Object tree expand the connection class, right-click on Språnget_to_Fallet_spill, and the click Remove).

    • To establish the topology of the unit (see adding unit relationships):

      • Add a unit__from_node relationship, between the Språnget_spill unit from the Språnget_upper node,
      • add a unit__node__node relationship between the Språnget_spill unit with the Fallet_upper and Språnget_upper nodes,
      • add a unit__to_node relationship between the Språnget_spill and the Fallet_upper node,
    • Add the relationship parameter values for the new units:

      • Set the unit_capacity (to apply a maximum), the minimum_operating_point (defined as a percentage of the unit_capacity) to impose a minimum, and the vom_cost to penalise the water that is spilt:

      Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.

      Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.

    • For the Språnget_spill unit define the fix_ratio_out_in_unit_flow parameter value of the min_spillage|Fallet_upper|Språnget_upper relationship to 1 (see adding unit relationships).

    Commit your changes in the database, execute the project and examine the results! As an exercise, you can perform this process for and Fallet plant (you would also need to add another water node, downstream of Fallet).

    Follow Contracted Load Curve

    It is often the case that a system of hydropower plants should follow a given production profile. To model this in the given system, all we have to do is set a demand in the form of a timeseries to the electricity_node.

    Commit your changes in the database, execute the project and examine the results!

    This concludes the tutorial, we hope that you enjoyed building hydropower systems in Spine as much as we do!

    +Two hydro plants · SpineOpt.jl

    Hydro Power Planning

    Welcome to this Spine Toolbox tutorial for building hydro power planning models. The tutorial guides you through the implementation of different ways of modelling hydrodologically-coupled hydropower systems.

    Introduction

    This tutorial aims at demonstrating how we can model a hydropower system in Spine (SpineOpt.jl and Spine-Toolbox) with different assumptions and goals. It starts off by setting up a simple model of system of two hydropower plants and gradually introduces additional features. The goal of the model is to capture the combined operation of two hydropower plants (Språnget and Fallet) that operate on the same river as shown in the picture bellow. Each power plant has its own reservoir and generates electricity by discharging water. The plants might need to spill water, i.e., release water from their reservoirs without generating electricity, for various reasons. The water discharged or spilled by the upstream power plant follows the river route and becomes available to the downstream power plant.

    A system of two hydropower plants.

    A system of two hydropower plants

    In order to run this tutorial you must first execute some preliminary steps from the Simple System tutorial. Specifically, execute all steps from the guide, up to and including the step of importing-the-spineopt-database-template. It is advisable to go through the whole tutorial in order to familiarise yourself with Spine.

    Note

    Just remember to give a different name for the Spine Project of the hydropower tutorial (e.g., ‘Two_hydro’) in the corresponding step, so to not mix up the Spine Toolbox projects!

    That is all you need at the moment, you can now start inserting the data.

    Setting up a Basic Hydropower Model

    For creating a SpineOpt model you need to create Objects, Relationships (associating the objects), and in some cases, parameters values accompanying them. To do this, open the input database using the Spine DB Editor (double click on the input database in the Design View pane of Spine Toolbox).

    Note

    To save your work in the Spine DB Editor you need to commit your changes (please check the Simple System tutorial for how to do that). As a good practice, you should commit often as you enter the data in the model to avoid data loss.

    Defining objects

    Commodities

    Since we are modelling a hydropower system we will have to define two commodities, water and electricity. In the Spine DB editor, locate the Object tree, expand the root element if required, right click on the commodity class, and select Add objects from the context menu. In the Add objects dialogue that should pop up, enter the object names for the commodities as you see in the image below and then press Ok.

    image

    Defining commodities.

    Nodes

    Follow a similar path to add nodes, right click on the node class, and select Add objects from the context menu. In the dialogue, enter the node names as shown:

    image

    Defining nodes.

    Nodes in SpineOpt are used to balance commodities. As you noticed, we defined two nodes for each hydropower station (water nodes) and a single electricity node. This is one possible way to model the hydropower plant operation. This will become clearer in the next steps, but in a nutshell, the upper node represents the water arriving at each plant, while the lower node represents the water that is discharged and becomes available to the next plant.

    Connections

    Similarly, add connections, right click on the connection class, select Add objects from the context menu and add the following connections:

    image

    Defining connections.

    Connections enable the nodes to interact. Since, for each plant we need to model the amount of water that is discharged and the amount that is spilled, we must define two connections accordingly. When defining relationships we shall associate the connections with the nodes.

    Units

    To convert from one type of commodity associated with one node to another, you need a unit. You guessed it! Right click on the unit class, select Add objects from the context menu and add the following units:

    image

    Defining units.

    We have defined one unit for each hydropower plant that converts water to electricity and an additional unit that we will use to model the income from selling the electricity production in the electricity market.

    Relationships

    Assinging commodities to nodes

    Since we have defined more than one commodities, we need to assign them to nodes. In the Spine DB editor, locate the Relationship tree, expand the root element if required, right click on the node__commodity class, and select Add relationships from the context menu. In the Add relationships dialogue, enter the following relationships as you see in the image below and then press Ok.

    image

    Introducing node__commodity relationships.

    Associating connections to nodes

    Next step is to define the topology of flows between the nodes. To do that insert the following relationships in the connection__from_node class:

    image

    Introducing connection__from_node relationships.

    as well as the following the following connection__node_node relationships as you see in the figure:

    Introducing connection__node_node relationships.

    Introducing connection__node_node relationships.

    Placing the units in the model

    To define the topology of the units and be able to introduce their parameters later on, you need to define the following relationships in the unit__from_node class:

    Introducing unit__from_node relationships.

    Introducing unit__from_node relationships.

    in the unit__node_node class:

    Introducing unit__node_node relationships.

    Introducing unit__node_node relationships.

    and in the unit__to_node class as you see in the following figure:

    Introducing unit__to_node relationships.

    Introducing unit__to_node relationships.

    Defining the report outputs

    To force Spine to export the optimal values of the optimization variables to the output database you need to specify them in the form of report_output relationships. Add the following relationships to the report_output class:

    Introducing report outputs with report_output relationships.

    Introducing report outputs with report_output relationships.

    Objects and Relationships parameter values

    Defining model parameter values

    The specify modelling properties of both objects and relationships you need to introduce respective parameter values. To introduce object parameter values first select the model class in the Object tree and enter the following values in the Object parameter value pane:

    Defining model execution parameters.

    Defining model execution parameters.

    Observe the difference between the Object parameter value and the Object parameter definition sub-panes of the Object parameter value pane. The first one is for the modeller to introduce values for specific parameters, while the second one holds the definition of all available parameters with their default values (these are overwritten when the user introduces their own values). Feel free to explore the different parameters and their default values. While entering data in each row you will also observe that, in most cases, clicking on each cell activates a drop-down list of elements that the user must choose from. In the case of the value cells, however, unless you need to input a scalar value or a string, you should right-click on the cell and select edit for specifying the data type of the parameter value. As you see in the figure above, for the first duration_unit parameter you is of type string, while the model_start and model_end parameters are of type Date time. The Date time parameters can be edited by right-clicking on the corresponding value cells, selecting Edit, and then inserting the Date time values that you see in the figure above in the Datetime field using the correct format.

    Defining node parameter values

    Going back to hydropower modelling, we need to specify several parameters for the nodes of the systems. In the same pane as before, but this time selecting the node class from the Object tree, we need to add the following entries:

    Defining model execution parameters.

    Defining model execution parameters.

    Before we go through the interpretation of each parameter, click on the following link for each fix_node_state parameter (Node state Språnget, Node state Fallet), select all, copy the data and then paste them directly in the respective parameter value cell. Spine should automatically detect and input the timeseries data as a parameter value. The data type for those entries should be Timeseries as shown in the figure above. Alternatively, you can select the data type as Timeseries and manually insert the data (values with their corresponding datetimes).

    To model the reservoirs of each hydropower plant, we leverage the state feature that a node can have to represent storage capability. We only need to do this for one of the two nodes that we have used to model each plant and we choose the upper level node. To define storage, we set the value of the parameter has_state as True (be careful to not set it as a string but select the boolean true value by right clicking and selecting Edit in the respective cells). This activates the storage capability of the node. Then, we need to set the capacity of the reservoir by setting the node_state_cap parameter value. Finally, we fix the initial and final values of the reservoir by setting the parameter fix_node_state to the respective values (we introduce nan values for the time steps that we don't want to impose such constraints). To model the local inflow we use the demand parameter but using the negated value of the actual inflow, due to the definition of the parameter in Spine as a demand.

    Defining the temporal resolution of the model

    Spine automates the creation of the temporal resolution of the optimization model and even supports different temporal resolutions for different parts of the model. To define a model with an hourly resolution we select the temporal_block class in the Object tree and we set the resolution parameter value to 1h as shown in the figure:

    Setting the temporal resolution of the model.

    Setting the temporal resolution of the model.

    Defining connection parameter values

    The water that is discharged from Språnget will flow from Språnget_lower node to Fallet_upper through the Språnget_to_Fallet_disc connection, while the water that is spilled will flow from Språnget_upper directly to to Fallet_upper through the Språnget_to_Fallet_spill connection. To model this we need to select the connection__node_node class in the Relationship tree and add the following entries in the Relationship parameter value pane, as shown next:

    Defining discharge and spillage ratio flows.

    Defining discharge and spillage ratio flows.

    Defining unit parameter values

    Similarly, for each one of the unit__from_node, unit__node_node, and unit__to_node relationship classes we need to add the the maximal water that can be discharged by each hydropower plant:

    Setting the maximal water discharge of each plant.

    Setting the maximal water discharge of each plant.

    To define the income from selling the produced electricity we use the vom_cost parameter and negate the values of the electricity prices. To automatically insert the timeseries data in Spine, click on the Electricity prices timeseries, select all values, copy, and paste them, after having selected the value cell of the corresponding row. You can plot and edit the timeseries data by double clicking on the same cell afterwards:

    Previewing and editing the electricity prices timeseries.

    Previewing and editing the electricity prices timeseries.

    Carrying on with our hydropower model we must define the conversion ratios between the nodes. Assuming that water is not "lost" from the upper node toward the lower node and electricity is produced with the discharged water with a given efficiency we define the following parameter values for each hydropower plant, in the unit__node_node class:

    Defining conversion efficiencies.

    Defining conversion efficiencies.

    Lastly, we can define the maximal electricity production of each plant by inserting the following unit__to_node relationship parameter values:

    Setting the maximal electricity production of each plant.

    Setting the maximal electricity production of each plant.

    Hooray! You can now commit the database, close the Spine DB Editor and run your model! Go to the main Spine window and click on Execute image.

    Examining the results

    Select the output data store and open the Spine DB editor. To quickly plot some results, you can expand the unit class in the Object tree and select the electricity_load unit. In the Relationship parameter value pane double click on the value cell of

    report1 | electricity_load | electricity_node | from_node | realization

    object name. This will open a plotting window from were you can also examine closer and retrieve the data, as shown in the next figure. The unit_flow variable of the electricity_load unit represents the total electricity production in the system:

    Total electricity produced in the system.

    Total electricity produced in the system.

    Now, take to a minute to reflect on how you could retrieve the data representing the water that is discharged by each hydropower plant as shown in the next figure:

    Water discharge of Språnget hydropower plant.

    Water discharge of Språnget hydropower plant.

    The right answer is that you need to select some hydropower plant (e.g., Språnget) and then double-click on the value cell of the object name

    report1 | Språnget_pwr_plant | Språnget_lower | to_node | realization

    or

    report1 | Språnget_pwr_plant | Språnget_upper | from_node | realization

    It could be useful to also reflect on why these objects give the same results, and what do the results from the third element represent. (Hint: observe the to_ or from_ directions in the object names). As an exercise, you can try to retrieve the timeseries data for spilled water as well as the water levels at the reservoir of each hydropower plant.

    You can further explore the model, or make changes in the input database to observe how these affect the results, e.g., you can use different electricity prices, values for the reservoir capacity (and initialization points), as well as change the temporal resolution of the model. All you need to do is commit the changes and run your model. Every time that you run the model, your results are appended in the output database with an execution timestamp. You can however filter your results per execution, by selecting the Alternative that you want from the Alternative/Scenario tree pane. You can use the exporter too to export specific variables in an Excel sheet. Alternatively, you can export all the data of the output database by going to the main menu (Press Alt + F to display it), selecting File -> Export, then select the items that you want, click ok and export the data in Excel, or json format.

    In the following, we extend this simple hydropower system to include more elaborate modelling choices.

    Note

    In each of the next sections, we perform incremental changes to the initial simple hydropower model. If you want to keep the database that you created, you can duplicate the database file (right-click on the input database and select Duplicate and duplicate files) and perform the changes in the new database. You need to configure the workflow accordingly in order to run the database you want (please check the Simple System tutorial for how to do that).

    Maximisation of Stored Water

    Instead of fixing the water content of the reservoirs at the end of the planning period, we can consider that the remaining water in the reservoirs has a value and then maximize the value along with the revenues for producing electricity within the planning horizon. This objective term is often called the Value of stored water and we can approximate it by assuming that this water will be used to generate electricity in the future that would be sold at a forecasted price. The water stored in the upstream hydropower plant will become also available to the downstream plant and this should be taken into account.

    To model the value of stored water we need to make some additions and modifications to the initial model.

    • First, add a new node (see adding nodes) and give it a name (e.g., stored_water). This node will accumulate the water stored in the reservoirs at the end of the planning horizon. Associate the node with the water commodity (see node__commodity).

    • Add three more units (see adding units); two will transfer the water at the end of the planning horizon in the new node that we just added (e.g., Språnget_stored_water, Fallet_stored_water), and one will be used as a sink introducing the value of stored water in the objective function (e.g., value_stored_water).

    • To establish the topology of the new units and nodes (see adding unit relationships):

      • add one unit__from_node relationship, between the value_stored_water unit from the stored_water node, another one between the Språnget_stored_water unit from the Språnget_upper node and one for Faller_stored_water from Fallet_upper.
      • add one unit__node__node relationship between the Språnget_stored_water unit with the stored_water and Språnget_upper nodes and another one for Fallet_stored_water unit with the stored_water and Fallet_upper nodes,
      • add a unit__to_node relationship between the Fallet_stored_water and the stored_water node and another one between the Språnget_stored_water unit and the stored_water node.
    • Now we need to make some changes in object parameter values.

      • Extend the planning horizon of the model by one hour, i.e., change the model_end parameter value to 2021-01-02T01:00:00 (right-click on the value cell, click edit and paste the new datetime in the popup window).
      • Remove the fix_node_state parameter values for the end of the optimization horizon as you seen in the following figure: double click on the value cell of the Språnget_upper and Fallet_upper nodes, select the third data row, right-click, select Remove rows, and click OK.
      • Add an electricity price for the extra hour. Enter the parameter vom_cost on the unit__from_node relationship between the electricity_node and the electricity_load and set 0 as the price of electricity for the last hour 2021-01-02T00:00:00. The price is set to zero to ensure no electricity is sold during this hour.

      Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes. Modify the fix_node_state parameter value of Språnget_upper and Fallet_upper nodes.

    • Finally, we need to add some relationship parameter values for the new units:

      • Add a vom_cost parameter value on a value_stored_water|stored_water instance of a unit__from_node relationship, as you see in the figure bellow. For the timeseries you can copy-paste the data directly from this link. If you examine the timeseries data you'll notice that we have imposed a zero cost for all the optimisation horizon, while we use an assumed future electricity value for the additional time step at the end of the horizon.

      Adding vom_cost parameter value on the value_stored_water unit. Adding vom_cost parameter value on the value_stored_water unit.

      • Add two fix_ratio_out_in_unit_flow parameter values as you see in the figure bellow. The efficiency of Fallet_stored_water is the same as the Fallet_pwr_plant as the water in Fallet's reservoir will be used to produce electricity by the the Fallet plant only. On the other hand, the water from Språnget's reservoir will be used both by Fallet and Språnget plant, therefore we use the sum of the two efficiencies in the parameter value of Språnget_stored_water.

      Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units. Adding fix_ratio_out_in_unit_flow parameter values on the Språnget_stored_water and Fallet_stored_water units.

    You can now commit your changes in the database, execute the project and examine the results! As an exercise, try to retrieve the value of stored water as it is calculated by the model.

    Spillage Constraints - Minimisation of Spilt Water

    It might be the case that we need to impose certain limits to the amount of water that is spilt on each time step of the planning horizon, e.g., for environmental reasons, there can be a minimum and a maximum spillage level. At the same time, to avoid wasting water that could be used for producing electricity, we could explicitly impose the spillage minimisation to be added in the objective function.

    • Add one unit (see adding units) to impose the spillage constraints to each plant and name it (for example Språnget_spill).

    • Remove the Språnget_to_Fallet_spill connection (in the Object tree expand the connection class, right-click on Språnget_to_Fallet_spill, and the click Remove).

    • To establish the topology of the unit (see adding unit relationships):

      • Add a unit__from_node relationship, between the Språnget_spill unit from the Språnget_upper node,
      • add a unit__node__node relationship between the Språnget_spill unit with the Fallet_upper and Språnget_upper nodes,
      • add a unit__to_node relationship between the Språnget_spill and the Fallet_upper node,
    • Add the relationship parameter values for the new units:

      • Set the unit_capacity (to apply a maximum), the minimum_operating_point (defined as a percentage of the unit_capacity) to impose a minimum, and the vom_cost to penalise the water that is spilt:

      Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.

      Setting minimum (the minimal value is defined as percentage of capacity), maximum, and spillage penalty.

    • For the Språnget_spill unit define the fix_ratio_out_in_unit_flow parameter value of the min_spillage|Fallet_upper|Språnget_upper relationship to 1 (see adding unit relationships).

    Commit your changes in the database, execute the project and examine the results! As an exercise, you can perform this process for and Fallet plant (you would also need to add another water node, downstream of Fallet).

    Follow Contracted Load Curve

    It is often the case that a system of hydropower plants should follow a given production profile. To model this in the given system, all we have to do is set a demand in the form of a timeseries to the electricity_node.

    Commit your changes in the database, execute the project and examine the results!

    This concludes the tutorial, we hope that you enjoyed building hydropower systems in Spine as much as we do!

    diff --git a/dev/tutorial/unit_commitment/index.html b/dev/tutorial/unit_commitment/index.html index ced5365797..de45947061 100644 --- a/dev/tutorial/unit_commitment/index.html +++ b/dev/tutorial/unit_commitment/index.html @@ -1,2 +1,2 @@ -Unit Commitment · SpineOpt.jl

    Unit commitment constraints tutorial

    This tutorial provides a step-by-step guide to include unit commitment constraints in a simple energy system with Spine Toolbox for SpineOpt.

    Introduction

    Welcome to our tutorial, where we will walk you through the process of adding unit commitment constraints in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.

    Model assumptions

    This tutorial is built on top of the Simple System. The main changes to that system are:

    • The demand at electricity_node is a 24-hour time series instead of a unique value
    • The power_plant_b has new parameters to account for the unit commitment constraints, such as minimum operating point, minimum uptime, and minimum downtime
    • The optimization is done a mixed-integer programming (MIP) to account for the binary nature of the unit commitment decision variables

    This tutorial includes a step-by-step guide to include the parameters to help analyze the results in SpineOpt and the unit commitment concepts.

    Step 1 - Update the demand

    Opening the Simple System project

    • Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.
    • Locate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.
    • Select the 'input' Data Store item in the Design View.
    • Go to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.

    In this tutorial, you will learn how to add unit commitment constraints to the Simple System using the Spine DB editor, but first let's start by updating the electricity demand from a single value to a 24-hour time series.

    Editing demand value

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [node] class, and select the electricity_node from the expanded tree.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table, identify the demand parameter which should have a 150 value from the Simple System first run.
    • Right click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.
    • Change the Parameter type to Time series fixed resolution, Resolution to 1h, and the demand values to the time series as in the image below. You can copy and paste the values from the file: ucelectricitynode_demand.csv
    • Finish by pressing OK in the Edit value menu. In the Object parameter table you will see that the value of the demand has changed to Time series.

    image

    Editing the temporal block

    You might or might not notice that the Simple System has, by default, a temporal block resolution of 1D (i.e., one day); wait, what! Yes, by default, it has 1D in its template. So, we want to change that to 1h since our unit commitment case study is for a day-ahead dispatch of 24 hours.

    • Locate again the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [temporal_block] class, and select the flat from the expanded tree.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table, identify the resolution parameter which should have a 1D value from the Simple System first run.
    • Right click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.
    • Change the Duration from 1D to 1h as shown in the image below.

    image

    Establishing new output relationships

    Since we will have the new unit commitment variables, we want to see the results of these variables and their total cost in the objective function. So, we will create new relationships to report these results:

    • In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.
    • Enter report1 under report, and units_on under output. Repete the same procedure for the following outputs as seen in the image below; then press OK.
    • This will write the unit commitment variable values and costs in the objective function to the output database as a part of report1.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    Examining the results

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. As expected, the power_plant_a (i.e., the cheapest unit) always covers the demand first until its maximum capacity, and then the power_plant_b (i.e., the more expensive unit) covers the demand that is left. This is the most economical dispatch since the problem has no extra constraints (so far!).

    image

    To explore the cost results, the pivot table view shows a more user-friendly option to analyze the results. Remember that you can find a description of how to create the pivot table view in the Simple System tutorial here. The cost components in the objective function are shown in the image below. As expected, all the costs are associated with the variable_om_costs since we haven't included the unit-commitment constraints yet.

    image

    Step 2 - Include the minimum operating point

    Let's assume that the power_plant_b has a minimum operating point of 10%, meaning that if the power plant is on, it must produce at least 20MW.

    Adding the minium operating point

    • In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • In Relationship tree, expand the unit__to_node class and select power_plant_b | electricity_node.
    • In the Relationship parameter table (typically at the bottom-center), select the minimum_operating_point parameter and the Base alternative, and enter the value 0.1 as seen in the image below. This will set the minimum operating point of power_plant_b when producing electricity.

    image

    Adding the unit commitment costs and initial states

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:
      • online_variable_type parameter and the Base alternative, and select the value unit_online_variable_type_binary. This will define that the unit commitment variables will be binary. SpineOpt identifies this situation from the input data and internally changes the model from LP to MIP.
      • shut_down_cost parameter and the Base alternative, and enter the value 7. This will establish that there's a cost of '7' EUR per shutdown.
      • start_up_cost parameter and the Base alternative, and enter the value 5. This will establish that there's a cost of '5' EUR per startup.
      • units_on_cost parameter and the Base alternative, and enter the value 3. This will establish that there's a cost of '3' EUR per units on (e.g., idling cost).
      • initial_units_on parameter and the Base alternative, and enter the value 0. This will establish that there are no units 'on' before the first time step.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum operating point

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    • Do you notice something different in your solver log? Depending on the solver, the output might change, but you should be able to see that the solver is using MIP to solve the problem. For instance, if you are using the solver HiGHS (i.e., the default solver in SpineOpt), then you will see something like "Solving MIP model with:" and the Branch and Bound (B&B) tree solution. Since this is a tiny problem, sometimes the solver can find the optimal solution from the presolve step, avoiding going into the B&B step.

    Examining the results including the minimum operating point

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Any difference? What happended to the flows in power_plant_a and power_plant_b?

    image

    • Let's take a look to the units_on and units_started_up in the image below to get wider perspective.

    image

    • So, since power_plant_b needs to be at least producing 20MW when it is 'on', then power_plant_a needs to reduce its output even though it has the lower variable cost, making the total system cost (i.e., objective function) more expensive than in the previous run. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.

    image

    Step 3 - Include the minimum uptime

    Let's assume that the power_plant_b also has a minimum uptime of 8 hours, meaning that if the power plant starts up, it must be on at least eight hours.

    Adding the minimum uptime

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the min_up_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.

    image

    • The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum uptime is eight hours.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum uptime

    You know the drill, go ahead :wink:

    Examining the results including the minimum uptime

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Interesting. Don't you think?

    image

    • Let's take a look again to the units_on and units_started_up in the image below.

    image

    • So, since power_plant_b needs to be at least producing 20MW when it is 'on' and also needs to be at least 8h 'on' each time it starts, then power_plant_b starts even before the demand is greater than the capacity of power_plant_a. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.

    image

    Step 4 - Include the minimum downtime

    Let's assume that the power_plant_b also has a minimum downtime of 8 hours, meaning that if the power plant shuts down, it must be off at least eight hours.

    Adding the minimum downtime

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the min_down_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.

    image

    • The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum downtime is eight hours.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum downtime

    One last time, don't give up!

    Examining the results including the minimum downtime

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Wow! This result is even more interesting :stuckouttonguewinkingeye:. Do you know what happened?

    image

    • Let's take a look again to the units_on and units_started_up in the image below. Instead of two start-ups, the power_plant_b only starts once. Why?

    image

    • Since power_plant_b needs to be at least producing 20MW when it is 'on' plus also needs to be at least 8h 'on' each time it starts, and it needs to be at least 8h 'off' if it shutdowns, then power_plant_b never shuts down and stays 'on' after it starts because it is the only way to fulfil the unit commitment constraints. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs (which is zero this time), and the increase in the variable_om_costs due to flow changes.

    image

    If you have completed this tutorial, congratulations! You have mastered the basic concepts of unit commitment using SpineToolbox and SpineOpt. Keep up the good work!

    +Unit Commitment · SpineOpt.jl

    Unit commitment constraints tutorial

    This tutorial provides a step-by-step guide to include unit commitment constraints in a simple energy system with Spine Toolbox for SpineOpt.

    Introduction

    Welcome to our tutorial, where we will walk you through the process of adding unit commitment constraints in SpineOpt using Spine Toolbox. To get the most out of this tutorial, we suggest first completing the Simple System tutorial, which can be found here.

    Model assumptions

    This tutorial is built on top of the Simple System. The main changes to that system are:

    • The demand at electricity_node is a 24-hour time series instead of a unique value
    • The power_plant_b has new parameters to account for the unit commitment constraints, such as minimum operating point, minimum uptime, and minimum downtime
    • The optimization is done a mixed-integer programming (MIP) to account for the binary nature of the unit commitment decision variables

    This tutorial includes a step-by-step guide to include the parameters to help analyze the results in SpineOpt and the unit commitment concepts.

    Step 1 - Update the demand

    Opening the Simple System project

    • Launch the Spine Toolbox and select File and then Open Project or use the keyboard shortcut Ctrl + O to open the desired project.
    • Locate the folder that you saved in the Simple System tutorial and click Ok. This will prompt the Simple System workflow to appear in the Design View section for you to start working on.
    • Select the 'input' Data Store item in the Design View.
    • Go to Data Store Properties and hit Open editor. This will open the database in the Spine DB editor.

    In this tutorial, you will learn how to add unit commitment constraints to the Simple System using the Spine DB editor, but first let's start by updating the electricity demand from a single value to a 24-hour time series.

    Editing demand value

    • Always in the Spine DB editor, locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [node] class, and select the electricity_node from the expanded tree.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table, identify the demand parameter which should have a 150 value from the Simple System first run.
    • Right click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.
    • Change the Parameter type to Time series fixed resolution, Resolution to 1h, and the demand values to the time series as in the image below. You can copy and paste the values from the file: ucelectricitynode_demand.csv
    • Finish by pressing OK in the Edit value menu. In the Object parameter table you will see that the value of the demand has changed to Time series.

    image

    Editing the temporal block

    You might or might not notice that the Simple System has, by default, a temporal block resolution of 1D (i.e., one day); wait, what! Yes, by default, it has 1D in its template. So, we want to change that to 1h since our unit commitment case study is for a day-ahead dispatch of 24 hours.

    • Locate again the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [temporal_block] class, and select the flat from the expanded tree.
    • Locate the Object parameter table (typically at the top-center).
    • In the Object parameter table, identify the resolution parameter which should have a 1D value from the Simple System first run.
    • Right click on the value cell and then select edit from the context menu. The Edit value dialog will pop up.
    • Change the Duration from 1D to 1h as shown in the image below.

    image

    Establishing new output relationships

    Since we will have the new unit commitment variables, we want to see the results of these variables and their total cost in the objective function. So, we will create new relationships to report these results:

    • In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • Right click on the report__output class, and select Add relationships from the context menu. The Add relationships dialog will pop up.
    • Enter report1 under report, and units_on under output. Repete the same procedure for the following outputs as seen in the image below; then press OK.
    • This will write the unit commitment variable values and costs in the objective function to the output database as a part of report1.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    Examining the results

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. As expected, the power_plant_a (i.e., the cheapest unit) always covers the demand first until its maximum capacity, and then the power_plant_b (i.e., the more expensive unit) covers the demand that is left. This is the most economical dispatch since the problem has no extra constraints (so far!).

    image

    To explore the cost results, the pivot table view shows a more user-friendly option to analyze the results. Remember that you can find a description of how to create the pivot table view in the Simple System tutorial here. The cost components in the objective function are shown in the image below. As expected, all the costs are associated with the variable_om_costs since we haven't included the unit-commitment constraints yet.

    image

    Step 2 - Include the minimum operating point

    Let's assume that the power_plant_b has a minimum operating point of 10%, meaning that if the power plant is on, it must produce at least 20MW.

    Adding the minium operating point

    • In the Spine DB editor, locate the Relationship tree (typically at the bottom-left). Expand the root element if not expanded.
    • In Relationship tree, expand the unit__to_node class and select power_plant_b | electricity_node.
    • In the Relationship parameter table (typically at the bottom-center), select the minimum_operating_point parameter and the Base alternative, and enter the value 0.1 as seen in the image below. This will set the minimum operating point of power_plant_b when producing electricity.

    image

    Adding the unit commitment costs and initial states

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the following parameter as seen in the image below:
      • online_variable_type parameter and the Base alternative, and select the value unit_online_variable_type_binary. This will define that the unit commitment variables will be binary. SpineOpt identifies this situation from the input data and internally changes the model from LP to MIP.
      • shut_down_cost parameter and the Base alternative, and enter the value 7. This will establish that there's a cost of '7' EUR per shutdown.
      • start_up_cost parameter and the Base alternative, and enter the value 5. This will establish that there's a cost of '5' EUR per startup.
      • units_on_cost parameter and the Base alternative, and enter the value 3. This will establish that there's a cost of '3' EUR per units on (e.g., idling cost).
      • initial_units_on parameter and the Base alternative, and enter the value 0. This will establish that there are no units 'on' before the first time step.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum operating point

    • Go back to Spine Toolbox's main window, and hit the Execute project button image from the tool bar. You should see 'Executing All Directed Acyclic Graphs' printed in the Event log (at the bottom left by default).

    • Select the 'Run SpineOpt' Tool. You should see the output from SpineOpt in the Julia Console after clicking the object activity control.

    • Do you notice something different in your solver log? Depending on the solver, the output might change, but you should be able to see that the solver is using MIP to solve the problem. For instance, if you are using the solver HiGHS (i.e., the default solver in SpineOpt), then you will see something like "Solving MIP model with:" and the Branch and Bound (B&B) tree solution. Since this is a tiny problem, sometimes the solver can find the optimal solution from the presolve step, avoiding going into the B&B step.

    Examining the results including the minimum operating point

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Any difference? What happended to the flows in power_plant_a and power_plant_b?

    image

    • Let's take a look to the units_on and units_started_up in the image below to get wider perspective.

    image

    • So, since power_plant_b needs to be at least producing 20MW when it is 'on', then power_plant_a needs to reduce its output even though it has the lower variable cost, making the total system cost (i.e., objective function) more expensive than in the previous run. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.

    image

    Step 3 - Include the minimum uptime

    Let's assume that the power_plant_b also has a minimum uptime of 8 hours, meaning that if the power plant starts up, it must be on at least eight hours.

    Adding the minimum uptime

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the min_up_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.

    image

    • The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum uptime is eight hours.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum uptime

    You know the drill, go ahead :wink:

    Examining the results including the minimum uptime

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Interesting. Don't you think?

    image

    • Let's take a look again to the units_on and units_started_up in the image below.

    image

    • So, since power_plant_b needs to be at least producing 20MW when it is 'on' and also needs to be at least 8h 'on' each time it starts, then power_plant_b starts even before the demand is greater than the capacity of power_plant_a. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs, and the increase in the variable_om_costs due to flow changes.

    image

    Step 4 - Include the minimum downtime

    Let's assume that the power_plant_b also has a minimum downtime of 8 hours, meaning that if the power plant shuts down, it must be off at least eight hours.

    Adding the minimum downtime

    • Locate the Object tree (typically at the top-left). Expand the [root] element if not expanded.
    • Expand the [unit] class, and select the power_plant_b from the expanded tree.
    • In the Object parameter table (typically at the top-center), select the min_down_time parameter, the Base alternative, and then right click on the value and select the Edit option in the context menu, as shown in the image below.

    image

    • The Edit value dialog will pop up. Select the Parameter_type as Duration and enter the value 8h. This will establish that minimum downtime is eight hours.

    image

    When you're ready, commit all changes to the database.

    Executing the workflow including the minimum downtime

    One last time, don't give up!

    Examining the results including the minimum downtime

    • Select the output data store and open the Spine DB editor. You can already inspect the fields in the displayed tables.
    • You can also activate the table view by pressing Alt + F for the shortcut to the hamburger menu, and select View -> Table.
    • Remember to select the latest run in the Alternative tree. Expand the Output element if not expanded.
    • In the Relationship parameter value table, double click in the Time series values to explore the results of the different variables.
    • The image below shows the electricity flow results for both power plants. Wow! This result is even more interesting :stuckouttonguewinkingeye:. Do you know what happened?

    image

    • Let's take a look again to the units_on and units_started_up in the image below. Instead of two start-ups, the power_plant_b only starts once. Why?

    image

    • Since power_plant_b needs to be at least producing 20MW when it is 'on' plus also needs to be at least 8h 'on' each time it starts, and it needs to be at least 8h 'off' if it shutdowns, then power_plant_b never shuts down and stays 'on' after it starts because it is the only way to fulfil the unit commitment constraints. Therefore, power_plant_a needs to reduce even further its output, making the total system cost more expensive than in the previous runs. The image below shows the cost components, where we can see the costs of having the power_plant_b on, its start-up and shutdown costs (which is zero this time), and the increase in the variable_om_costs due to flow changes.

    image

    If you have completed this tutorial, congratulations! You have mastered the basic concepts of unit commitment using SpineToolbox and SpineOpt. Keep up the good work!

    diff --git a/dev/tutorial/webinars/index.html b/dev/tutorial/webinars/index.html index ee23096ef1..db244f6fd3 100644 --- a/dev/tutorial/webinars/index.html +++ b/dev/tutorial/webinars/index.html @@ -1,2 +1,2 @@ -Webinars · SpineOpt.jl +Webinars · SpineOpt.jl