diff --git a/doc/_static/custom_math/net_import_share.yaml b/doc/_static/custom_math/net_import_share.yaml index 0b3e87e58..8f0c6604f 100644 --- a/doc/_static/custom_math/net_import_share.yaml +++ b/doc/_static/custom_math/net_import_share.yaml @@ -1,37 +1,44 @@ +# Force upper limit on carrier imports within nodes or across all nodes as a share of all carrier flows at a node/across nodes. +# Imports of transmission technologies are defined by `flow_out` (outflow from a transmission technology that originated in a remote node). + constraints: net_import_share_max: + description: Limit upper bound on electricity imports within nodes as a share of all electricity flows at each node. foreach: [nodes, timesteps] - where: "defined(techs=ac_transmission, within=nodes, how=any)" + where: "defined(techs=test_transmission_elec, within=nodes, how=any)" equations: - - expression: net_import_share * sum(flow_in[techs=$transmission_techs, carriers=power], over=techs) <= $total_energy_balance + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, carriers=electricity], over=techs) <= $total_energy_balance sub_expressions: total_energy_balance: - - expression: sum(flow_out[carriers=power], over=techs) - sum(flow_in[carriers=power], over=techs) + - expression: sum(flow_out[carriers=electricity], over=techs) - sum(flow_in[carriers=electricity], over=techs) slices: transmission_techs: - - expression: get_transmission_techs(ac_transmission) + - expression: get_transmission_techs(test_transmission_elec) net_annual_import_share_max: + description: Limit upper bound on annual electricity imports within nodes as a share of all electricity flows at each node. foreach: [nodes] - where: "defined(techs=ac_transmission, within=nodes, how=any)" + where: "defined(techs=test_transmission_elec, within=nodes, how=any)" equations: - - expression: net_import_share * sum(flow_in[techs=$transmission_techs, carriers=power], over=[techs, timesteps]) <= $total_energy_balance + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, carriers=electricity], over=[techs, timesteps]) <= $total_energy_balance sub_expressions: total_energy_balance: - - expression: sum(flow_out[carriers=power], over=[techs, timesteps]) - sum(flow_in[carriers=power], over=[techs, timesteps]) + - expression: sum(flow_out[carriers=electricity], over=[techs, timesteps]) - sum(flow_in[carriers=electricity], over=[techs, timesteps]) slices: transmission_techs: - - expression: get_transmission_techs([ac_transmission, free_transmission]) + - expression: get_transmission_techs(test_transmission_elec) net_annual_import_share_max_node_group: - where: "[power] in carriers" + description: Limit upper bound on annual heat imports across two nodes in the model as a share of combined heat flows in both nodes. equations: - - expression: net_import_share * sum(flow_in[techs=$transmission_techs, carriers=power, nodes=$node_group], over=[nodes, techs, timesteps]) <= $total_energy_balance + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) <= $total_energy_balance sub_expressions: total_energy_balance: - - expression: sum(flow_out[carriers=power, nodes=$node_group], over=[nodes, techs, timesteps]) - sum(flow_in[carriers=power, nodes=$node_group], over=[nodes, techs, timesteps]) + - expression: sum(flow_out[nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) - sum(flow_in[nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) slices: transmission_techs: - - expression: get_transmission_techs(free_transmission) + - expression: get_transmission_techs(test_transmission_heat) node_group: - - expression: "[region1_1, region1_2, region1_3]" \ No newline at end of file + - expression: "[a, c]" + carrier: + - expression: heat \ No newline at end of file diff --git a/tests/common/lp_files/net_annual_import_share_max.lp b/tests/common/lp_files/net_annual_import_share_max.lp new file mode 100644 index 000000000..f1eb00e95 --- /dev/null +++ b/tests/common/lp_files/net_annual_import_share_max.lp @@ -0,0 +1,68 @@ +\* Source Pyomo model name=None *\ + +min +objectives(dummy_obj)(0): ++2.0 ONE_VAR_CONSTANT + +s.t. + +c_u_constraints(net_annual_import_share_max)(a)_: ++0.5 variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) ++0.5 variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) ++0.5 variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) ++0.5 variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) +-1 variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_00_00) +-1 variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) +<= 0.0 + +c_u_constraints(net_annual_import_share_max)(b)_: ++0.5 variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) ++0.5 variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) +-1 variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_00_00) +-1 variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) ++1 variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) +<= 0.0 + +c_u_constraints(net_annual_import_share_max)(c)_: ++0.5 variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) ++0.5 variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) ++1 variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) ++1 variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) +<= 0.0 + +bounds + 1 <= ONE_VAR_CONSTANT <= 1 + 0 <= variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf +end diff --git a/tests/common/lp_files/net_annual_import_share_max_node_group.lp b/tests/common/lp_files/net_annual_import_share_max_node_group.lp new file mode 100644 index 000000000..e4422b95c --- /dev/null +++ b/tests/common/lp_files/net_annual_import_share_max_node_group.lp @@ -0,0 +1,42 @@ +\* Source Pyomo model name=None *\ + +min +objectives(dummy_obj)(0): ++2.0 ONE_VAR_CONSTANT + +s.t. + +c_u_constraints(net_annual_import_share_max_node_group)_: ++0.5 variables(flow_out)(a__test_transmission_heat_b__heat__2005_01_01_00_00) ++0.5 variables(flow_out)(a__test_transmission_heat_b__heat__2005_01_01_01_00) ++0.5 variables(flow_out)(a__test_transmission_heat_c__heat__2005_01_01_00_00) ++0.5 variables(flow_out)(a__test_transmission_heat_c__heat__2005_01_01_01_00) ++0.5 variables(flow_out)(c__test_transmission_heat_a__heat__2005_01_01_00_00) ++0.5 variables(flow_out)(c__test_transmission_heat_a__heat__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_heat_b__heat__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_heat_b__heat__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_heat_c__heat__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_heat_c__heat__2005_01_01_01_00) ++1 variables(flow_in)(c__test_demand_heat__heat__2005_01_01_00_00) ++1 variables(flow_in)(c__test_demand_heat__heat__2005_01_01_01_00) ++1 variables(flow_in)(c__test_transmission_heat_a__heat__2005_01_01_00_00) ++1 variables(flow_in)(c__test_transmission_heat_a__heat__2005_01_01_01_00) +<= 0.0 + +bounds + 1 <= ONE_VAR_CONSTANT <= 1 + 0 <= variables(flow_out)(a__test_transmission_heat_b__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_heat_b__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_heat_c__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_heat_c__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_heat_a__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_heat_a__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_heat_b__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_heat_b__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_heat_c__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_heat_c__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(c__test_demand_heat__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(c__test_demand_heat__heat__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_heat_a__heat__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_heat_a__heat__2005_01_01_01_00) <= +inf +end diff --git a/tests/common/lp_files/net_import_share_max.lp b/tests/common/lp_files/net_import_share_max.lp new file mode 100644 index 000000000..5db71d391 --- /dev/null +++ b/tests/common/lp_files/net_import_share_max.lp @@ -0,0 +1,77 @@ +\* Source Pyomo model name=None *\ + +min +objectives(dummy_obj)(0): ++2.0 ONE_VAR_CONSTANT + +s.t. + +c_u_constraints(net_import_share_max)(a__2005_01_01_00_00)_: ++0.5 variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) ++0.5 variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) +-1 variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) ++1 variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) +<= 0.0 + +c_u_constraints(net_import_share_max)(a__2005_01_01_01_00)_: ++0.5 variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) ++0.5 variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) +-1 variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) ++1 variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) +<= 0.0 + +c_u_constraints(net_import_share_max)(b__2005_01_01_00_00)_: ++0.5 variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) +-1 variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_00_00) ++1 variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) +<= 0.0 + +c_u_constraints(net_import_share_max)(b__2005_01_01_01_00)_: ++0.5 variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) +-1 variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_01_00) ++1 variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) +<= 0.0 + +c_u_constraints(net_import_share_max)(c__2005_01_01_00_00)_: ++0.5 variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) ++1 variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) +<= 0.0 + +c_u_constraints(net_import_share_max)(c__2005_01_01_01_00)_: ++0.5 variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) ++1 variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) +<= 0.0 + +bounds + 1 <= ONE_VAR_CONSTANT <= 1 + 0 <= variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(a__test_supply_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_demand_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_b__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(a__test_transmission_elec_c__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(b__test_supply_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(b__test_demand_elec__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(b__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_00_00) <= +inf + 0 <= variables(flow_out)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf + 0 <= variables(flow_in)(c__test_transmission_elec_a__electricity__2005_01_01_01_00) <= +inf +end diff --git a/tests/test_math.py b/tests/test_math.py index cb1855339..72e347e80 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -689,3 +689,36 @@ def test_downtime_decision(self, build_and_compare): build_and_compare( "downtime_period_decision", "supply_milp,two_hours", overrides ) + + +class TestNetImportShare(CustomMathExamples): + YAML_FILEPATH = "net_import_share.yaml" + shared_overrides = { + "parameters.net_import_share": 1.5, + "nodes.c.techs": { + "test_demand_heat": {"constraints.sink_equals": "file=demand_heat.csv:a"} + }, + "links.a,c.techs": { + "test_transmission_heat": None, + "test_transmission_elec": None, + }, + } + + def test_net_import_share_max(self, build_and_compare): + build_and_compare( + "net_import_share_max", "simple_supply,two_hours", self.shared_overrides + ) + + def test_net_annual_import_share_max(self, build_and_compare): + build_and_compare( + "net_annual_import_share_max", + "simple_supply,two_hours", + self.shared_overrides, + ) + + def test_net_annual_import_share_max_node_group(self, build_and_compare): + build_and_compare( + "net_annual_import_share_max_node_group", + "simple_supply,two_hours", + self.shared_overrides, + )