From 684f7b58c3523fb010076c601b69e4c6512b2786 Mon Sep 17 00:00:00 2001 From: Ana Mileva Date: Thu, 26 Oct 2023 13:29:58 -0700 Subject: [PATCH] Relative capacity limits based on multiple projects (#1048) --- db/csvs_test_examples/csv_structure.csv | 1 + .../relative_capacity/1_base_rel_cap.csv | 4 +- .../mappings/Solar-1-base_map.csv | 2 + db/db_schema.sql | 22 ++- ...project_relative_capacity_requirements.tab | 4 +- ...ect_relative_capacity_requirements_map.tab | 2 + .../project/capacity/relative_capacity.py | 158 ++++++++++++------ .../capacity/test_relative_capacity.py | 71 ++++---- ...project_relative_capacity_requirements.tab | 6 +- ...ect_relative_capacity_requirements_map.tab | 4 + 10 files changed, 176 insertions(+), 98 deletions(-) create mode 100644 db/csvs_test_examples/project/relative_capacity/mappings/Solar-1-base_map.csv create mode 100644 examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements_map.tab create mode 100644 tests/test_data/inputs/project_relative_capacity_requirements_map.tab diff --git a/db/csvs_test_examples/csv_structure.csv b/db/csvs_test_examples/csv_structure.csv index c0ca96bbf..a8ec4eb18 100644 --- a/db/csvs_test_examples/csv_structure.csv +++ b/db/csvs_test_examples/csv_structure.csv @@ -19,6 +19,7 @@ project/project_new_binary_build_size,data_dependent,project_new_binary_build_si project/project_capacity_groups/requirements,data_dependent,project_capacity_group_requirement_scenario_id,project_capacity_group_requirements,simple,,0,0,,,, project/project_capacity_groups/projects,data_dependent,project_capacity_group_scenario_id,project_capacity_groups,simple,,0,0,,,, project/relative_capacity,data_dependent,project_relative_capacity_requirement_scenario_id,project_relative_capacity_requirements,simple,,0,0,,,, +project/relative_capacity/mappings,data_dependent,prj_for_lim_map_id,project_relative_capacity_requirements_map,simple,,1,0,,,inputs_project_relative_capacity_requirements,project_relative_capacity_requirement_scenario_id project/project_fuels,data_dependent,project_fuel_scenario_id,project_fuels,simple,,1,0,,,inputs_project_operational_chars,project_operational_chars_scenario_id project/project_heat_rate_curves,data_dependent,heat_rate_curves_scenario_id,project_heat_rate_curves,simple,,1,0,,,inputs_project_operational_chars,project_operational_chars_scenario_id project/project_variable_om_curves,data_dependent,variable_om_curves_scenario_id,project_variable_om_curves,simple,,1,0,,,inputs_project_operational_chars,project_operational_chars_scenario_id diff --git a/db/csvs_test_examples/project/relative_capacity/1_base_rel_cap.csv b/db/csvs_test_examples/project/relative_capacity/1_base_rel_cap.csv index 94f1345c9..3d436fae6 100644 --- a/db/csvs_test_examples/project/relative_capacity/1_base_rel_cap.csv +++ b/db/csvs_test_examples/project/relative_capacity/1_base_rel_cap.csv @@ -1,2 +1,2 @@ -project,project_for_limits,period,min_relative_capacity_limit_new,max_relative_capacity_limit_new,min_relative_capacity_limit_total,max_relative_capacity_limit_total -Solar,Wind,2020,,,,2 \ No newline at end of file +project,period,prj_for_lim_map_id,min_relative_capacity_limit_new,max_relative_capacity_limit_new,min_relative_capacity_limit_total,max_relative_capacity_limit_total +Solar,2020,1,,,,2 \ No newline at end of file diff --git a/db/csvs_test_examples/project/relative_capacity/mappings/Solar-1-base_map.csv b/db/csvs_test_examples/project/relative_capacity/mappings/Solar-1-base_map.csv new file mode 100644 index 000000000..6bb383b01 --- /dev/null +++ b/db/csvs_test_examples/project/relative_capacity/mappings/Solar-1-base_map.csv @@ -0,0 +1,2 @@ +project_for_limits +Wind \ No newline at end of file diff --git a/db/db_schema.sql b/db/db_schema.sql index 0d09ee058..98e08a91e 100644 --- a/db/db_schema.sql +++ b/db/db_schema.sql @@ -1163,19 +1163,37 @@ CREATE TABLE inputs_project_relative_capacity_requirements ( project_relative_capacity_requirement_scenario_id INTEGER, project VARCHAR(64), - project_for_limits VARCHAR(64), period INTEGER, + prj_for_lim_map_id INTEGER, min_relative_capacity_limit_new FLOAT, max_relative_capacity_limit_new FLOAT, min_relative_capacity_limit_total FLOAT, max_relative_capacity_limit_total FLOAT, PRIMARY KEY (project_relative_capacity_requirement_scenario_id, project, - project_for_limits, period), + period, prj_for_lim_map_id), FOREIGN KEY (project_relative_capacity_requirement_scenario_id) REFERENCES subscenarios_project_relative_capacity_requirements (project_relative_capacity_requirement_scenario_id) ); +DROP TABLE IF EXISTS subscenarios_project_relative_capacity_requirements_map; +CREATE TABLE subscenarios_project_relative_capacity_requirements_map +( + project VARCHAR(64), + prj_for_lim_map_id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR(32), + description VARCHAR(128) +); + +DROP TABLE IF EXISTS inputs_project_relative_capacity_requirements_map; +CREATE TABLE inputs_project_relative_capacity_requirements_map +( + project VARCHAR(64), + prj_for_lim_map_id INTEGER, + project_for_limits VARCHAR(64), + PRIMARY KEY (project, prj_for_lim_map_id, project_for_limits) +); + -- Group project mapping DROP TABLE IF EXISTS subscenarios_project_capacity_groups; diff --git a/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements.tab b/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements.tab index 01bfa5930..14a9fa392 100644 --- a/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements.tab +++ b/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements.tab @@ -1,2 +1,2 @@ -project project_for_limits period min_relative_capacity_limit_new max_relative_capacity_limit_new min_relative_capacity_limit_total max_relative_capacity_limit_total -Solar Wind 2020 . . . 2.0 +project period min_relative_capacity_limit_new max_relative_capacity_limit_new min_relative_capacity_limit_total max_relative_capacity_limit_total +Solar 2020 . . . 2.0 diff --git a/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements_map.tab b/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements_map.tab new file mode 100644 index 000000000..cd1806415 --- /dev/null +++ b/examples/test_new_solar_w_relative_capacity_instead_of_potential/inputs/project_relative_capacity_requirements_map.tab @@ -0,0 +1,2 @@ +project period project_for_limit +Solar 2020 Wind diff --git a/gridpath/project/capacity/relative_capacity.py b/gridpath/project/capacity/relative_capacity.py index 2af89196d..e74fce236 100644 --- a/gridpath/project/capacity/relative_capacity.py +++ b/gridpath/project/capacity/relative_capacity.py @@ -35,17 +35,23 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): +-------------------------------------------------------------------------+ | Sets | +=========================================================================+ - | | :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | :code:`REL_CAP_PRJ_PRD` | | | - | A 3-dimensional set of project-project-period combinations for which | - | there may be a relative capacity requirement. | + | A 2-dimensional set of project-period combinations for which there | + | may be a relative capacity requirement. | + +-------------------------------------------------------------------------+ + | | :code:`PRJS_FOR_REL_CAP_LIMIT` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | + | | + | List of projects who capacity counts toward the limit for each project- | + | period with a limit. | +-------------------------------------------------------------------------+ +-------------------------------------------------------------------------+ | Optional Input Params | +=========================================================================+ | | :code:`min_relative_capacity_limit_new` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | *Within*: :code:`NonNegativeReals` | | | *Default*: :code:`0` | | | @@ -53,7 +59,7 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): | parameter times the (new) capacity of project 2 in this period. | +-------------------------------------------------------------------------+ | | :code:`max_relative_capacity_limit_new` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | *Within*: :code:`NonNegativeReals` | | | *Default*: :code:`inf` | | | @@ -61,7 +67,7 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): | parameter times the (new) capacity of project 2 in this period. | +-------------------------------------------------------------------------+ | | :code:`min_relative_capacity_limit_total` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | *Within*: :code:`NonNegativeReals` | | | *Default*: :code:`0` | | | @@ -69,7 +75,7 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): | parameter times the (total) capacity of project 2 in this period. | +-------------------------------------------------------------------------+ | | :code:`max_relative_capacity_limit_total` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | *Within*: :code:`NonNegativeReals` | | | *Default*: :code:`inf` | | | @@ -83,25 +89,25 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): | Constraints | +=========================================================================+ | | :code:`Min_Relative_New_Capacity_Limit_in_Period_Constraint` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | | Provides a lower limit on the amount of new capacity for a based on the | | new capacity of another project. | +-------------------------------------------------------------------------+ | | :code:`Max_Relative_New_Capacity_Limit_in_Period_Constraint` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | | Provides an upper limit on the amount of new capacity for a based on | | the (new) capacity of another project. | +-------------------------------------------------------------------------+ | | :code:`Min_Relative_Total_Capacity_Limit_in_Period_Constraint` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | | Provides a lower limit on the amount of total capacity for a based on | | the total capacity of another project. | +-------------------------------------------------------------------------+ | | :code:`Max_Relative_New_Capacity_Limit_in_Period_Constraint` | - | | *Defined over*: :code:`RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS` | + | | *Defined over*: :code:`REL_CAP_PRJ_PRD` | | | | Provides a upper limit on the amount of total capacity for a based on | | the total capacity of another project. | @@ -109,23 +115,25 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): """ # Sets - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS = Set(dimen=3) + m.REL_CAP_PRJ_PRD = Set(dimen=2) + + m.PRJS_FOR_REL_CAP_LIMIT = Set(m.REL_CAP_PRJ_PRD, within=m.PROJECTS) # Params m.min_relative_capacity_limit_new = Param( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, within=NonNegativeReals, default=0 + m.REL_CAP_PRJ_PRD, within=NonNegativeReals, default=0 ) m.max_relative_capacity_limit_new = Param( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, + m.REL_CAP_PRJ_PRD, within=NonNegativeReals, default=float("inf"), ) m.min_relative_capacity_limit_total = Param( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, within=NonNegativeReals, default=0 + m.REL_CAP_PRJ_PRD, within=NonNegativeReals, default=0 ) m.max_relative_capacity_limit_total = Param( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, + m.REL_CAP_PRJ_PRD, within=NonNegativeReals, default=float("inf"), ) @@ -168,72 +176,66 @@ def project_total_capacity(mod, prj, prd): # Constraints # Limit the min and max amount of new and total capacity based on another # project in a given period - def new_capacity_min_rule(mod, prj, prj_for_limit, prd): - if mod.min_relative_capacity_limit_new[prj, prj_for_limit, prd] == 0: + def new_capacity_min_rule(mod, prj, prd): + if mod.min_relative_capacity_limit_new[prj, prd] == 0: return Constraint.Feasible else: return project_new_capacity( mod, prj, prd - ) >= mod.min_relative_capacity_limit_new[ - prj, prj_for_limit, prd - ] * project_new_capacity( - mod, prj_for_limit, prd + ) >= mod.min_relative_capacity_limit_new[prj, prd] * sum( + project_new_capacity(mod, prj_for_limit, prd) + for prj_for_limit in mod.PRJS_FOR_REL_CAP_LIMIT[prj, prd] ) m.Min_Relative_New_Capacity_Limit_in_Period_Constraint = Constraint( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, rule=new_capacity_min_rule + m.REL_CAP_PRJ_PRD, rule=new_capacity_min_rule ) - def new_capacity_max_rule(mod, prj, prj_for_limit, prd): - if mod.max_relative_capacity_limit_new[prj, prj_for_limit, prd] == float("inf"): + def new_capacity_max_rule(mod, prj, prd): + if mod.max_relative_capacity_limit_new[prj, prd] == float("inf"): return Constraint.Feasible else: return project_new_capacity( mod, prj, prd - ) <= mod.max_relative_capacity_limit_new[ - prj, prj_for_limit, prd - ] * project_new_capacity( - mod, prj_for_limit, prd + ) <= mod.max_relative_capacity_limit_new[prj, prd] * sum( + project_new_capacity(mod, prj_for_limit, prd) + for prj_for_limit in mod.PRJS_FOR_REL_CAP_LIMIT[prj, prd] ) m.Max_Relative_New_Capacity_Limit_in_Period_Constraint = Constraint( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, rule=new_capacity_max_rule + m.REL_CAP_PRJ_PRD, rule=new_capacity_max_rule ) # Limit the min and max amount of total capacity in a period based on # another project - def total_capacity_min_rule(mod, prj, prj_for_limit, prd): - if mod.min_relative_capacity_limit_total[prj, prj_for_limit, prd] == 0: + def total_capacity_min_rule(mod, prj, prd): + if mod.min_relative_capacity_limit_total[prj, prd] == 0: return Constraint.Feasible else: return project_total_capacity( mod, prj, prd - ) >= mod.min_relative_capacity_limit_total[ - prj, prj_for_limit, prd - ] * project_total_capacity( - mod, prj_for_limit, prd + ) >= mod.min_relative_capacity_limit_total[prj, prd] * sum( + project_total_capacity(mod, prj_for_limit, prd) + for prj_for_limit in mod.PRJS_FOR_REL_CAP_LIMIT[prj, prd] ) m.Min_Relative_Total_Capacity_Limit_in_Period_Constraint = Constraint( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, rule=total_capacity_min_rule + m.REL_CAP_PRJ_PRD, rule=total_capacity_min_rule ) - def total_capacity_max_rule(mod, prj, prj_for_limit, prd): - if mod.max_relative_capacity_limit_total[prj, prj_for_limit, prd] == float( - "inf" - ): + def total_capacity_max_rule(mod, prj, prd): + if mod.max_relative_capacity_limit_total[prj, prd] == float("inf"): return Constraint.Feasible else: return project_total_capacity( mod, prj, prd - ) <= mod.max_relative_capacity_limit_total[ - prj, prj_for_limit, prd - ] * project_total_capacity( - mod, prj_for_limit, prd + ) <= mod.max_relative_capacity_limit_total[prj, prd] * sum( + project_total_capacity(mod, prj_for_limit, prd) + for prj_for_limit in mod.PRJS_FOR_REL_CAP_LIMIT[prj, prd] ) m.Max_Relative_Total_Capacity_Limit_in_Period_Constraint = Constraint( - m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, rule=total_capacity_max_rule + m.REL_CAP_PRJ_PRD, rule=total_capacity_max_rule ) @@ -253,10 +255,19 @@ def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): "inputs", "project_relative_capacity_requirements.tab", ) + + map_file = os.path.join( + scenario_directory, + subproblem, + stage, + "inputs", + "project_relative_capacity_requirements_map.tab", + ) + if os.path.exists(req_file): data_portal.load( filename=req_file, - index=m.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS, + index=m.REL_CAP_PRJ_PRD, param=( m.min_relative_capacity_limit_new, m.max_relative_capacity_limit_new, @@ -265,6 +276,16 @@ def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): ), ) + if os.path.exists(map_file): + df = pd.read_csv(map_file, delimiter="\t") + mapping = ( + df.set_index(["project", "period"]) + .groupby(["project", "period"])["project_for_limit"] + .apply(list) + .to_dict() + ) + data_portal.data()["PRJS_FOR_REL_CAP_LIMIT"] = mapping + # Database ############################################################################### @@ -279,10 +300,10 @@ def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn) :return: """ - c = conn.cursor() - rel_cap = c.execute( + c1 = conn.cursor() + rel_cap = c1.execute( f""" - SELECT project, project_for_limits, period, + SELECT project, period, min_relative_capacity_limit_new, max_relative_capacity_limit_new, min_relative_capacity_limit_total, max_relative_capacity_limit_total FROM inputs_project_relative_capacity_requirements @@ -291,14 +312,26 @@ def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn) """ ) - return rel_cap + c2 = conn.cursor() + map = c2.execute( + f""" + SELECT project, period, project_for_limits + FROM inputs_project_relative_capacity_requirements + JOIN inputs_project_relative_capacity_requirements_map + USING (project, prj_for_lim_map_id) + WHERE project_relative_capacity_requirement_scenario_id = + {subscenarios.PROJECT_RELATIVE_CAPACITY_REQUIREMENT_SCENARIO_ID} + """ + ) + + return rel_cap, map def write_model_inputs( scenario_directory, scenario_id, subscenarios, subproblem, stage, conn ): """ """ - rel_cap = get_inputs_from_database( + rel_cap, map = get_inputs_from_database( scenario_id, subscenarios, subproblem, stage, conn ) @@ -321,7 +354,6 @@ def write_model_inputs( writer.writerow( [ "project", - "project_for_limits", "period", "min_relative_capacity_limit_new", "max_relative_capacity_limit_new", @@ -333,3 +365,23 @@ def write_model_inputs( for row in rel_cap: replace_nulls = ["." if i is None else i for i in row] writer.writerow(replace_nulls) + + with open( + os.path.join( + scenario_directory, + str(subproblem), + str(stage), + "inputs", + "project_relative_capacity_requirements_map.tab", + ), + "w", + newline="", + ) as map_file: + writer = csv.writer(map_file, delimiter="\t", lineterminator="\n") + + # Write header + writer.writerow(["project", "period", "project_for_limit"]) + + for row in map: + replace_nulls = ["." if i is None else i for i in row] + writer.writerow(replace_nulls) diff --git a/tests/project/capacity/test_relative_capacity.py b/tests/project/capacity/test_relative_capacity.py index 7fd5c5fe7..cd10b156e 100644 --- a/tests/project/capacity/test_relative_capacity.py +++ b/tests/project/capacity/test_relative_capacity.py @@ -1,4 +1,4 @@ -# Copyright 2016-2020 Blue Marble Analytics LLC. +# Copyright 2016-2023 Blue Marble Analytics LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -95,86 +95,85 @@ def test_initialized_components(self): ) instance = m.create_instance(data) - # Set: RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS - expected_prj_prd = sorted( - [("Battery", "Wind", 2020), ("Battery", "Wind", 2030)] - ) + # Set: REL_CAP_PRJ_PRD + expected_prj_prd = sorted([("Battery", 2020), ("Battery", 2030)]) actual_prj_prd = sorted( [ - (prj, prj_l, period) + (prj, period) for ( prj, - prj_l, period, - ) in instance.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS + ) in instance.REL_CAP_PRJ_PRD ] ) self.assertListEqual(expected_prj_prd, actual_prj_prd) + # Set: PRJS_FOR_REL_CAP_LIMIT + expected_prj_prd = { + ("Battery", 2020): ["Wind"], + ("Battery", 2030): ["Wind", "Battery_Binary"], + } + actual_prj_prd = { + (prj, period): [prj for prj in instance.PRJS_FOR_REL_CAP_LIMIT[prj, period]] + for ( + prj, + period, + ) in instance.REL_CAP_PRJ_PRD + } + self.assertDictEqual(expected_prj_prd, actual_prj_prd) + # Params: min_relative_capacity_limit_new expected_new_min = { - ("Battery", "Wind", 2020): 0, - ("Battery", "Wind", 2030): 1, + ("Battery", 2020): 0, + ("Battery", 2030): 1, } actual_new_min = { - (prj, prj_for_lim, prd): instance.min_relative_capacity_limit_new[ - prj, prj_for_lim, prd - ] + (prj, prd): instance.min_relative_capacity_limit_new[prj, prd] for ( prj, - prj_for_lim, prd, - ) in instance.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS + ) in instance.REL_CAP_PRJ_PRD } self.assertDictEqual(expected_new_min, actual_new_min) # # Params: max_relative_capacity_limit_new expected_new_max = { - ("Battery", "Wind", 2020): 2, - ("Battery", "Wind", 2030): float("inf"), + ("Battery", 2020): 2, + ("Battery", 2030): float("inf"), } actual_new_max = { - (prj, prj_for_lim, prd): instance.max_relative_capacity_limit_new[ - prj, prj_for_lim, prd - ] + (prj, prd): instance.max_relative_capacity_limit_new[prj, prd] for ( prj, - prj_for_lim, prd, - ) in instance.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS + ) in instance.REL_CAP_PRJ_PRD } self.assertDictEqual(expected_new_max, actual_new_max) # Params: min_relative_capacity_limit_total expected_total_min = { - ("Battery", "Wind", 2020): 3, - ("Battery", "Wind", 2030): 0, + ("Battery", 2020): 3, + ("Battery", 2030): 0, } actual_total_min = { - (prj, prj_for_lim, prd): instance.min_relative_capacity_limit_total[ - prj, prj_for_lim, prd - ] + (prj, prd): instance.min_relative_capacity_limit_total[prj, prd] for ( prj, - prj_for_lim, prd, - ) in instance.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS + ) in instance.REL_CAP_PRJ_PRD } self.assertDictEqual(expected_total_min, actual_total_min) # Params: max_relative_capacity_limit_total expected_total_max = { - ("Battery", "Wind", 2020): float("inf"), - ("Battery", "Wind", 2030): 4, + ("Battery", 2020): float("inf"), + ("Battery", 2030): 4, } actual_total_max = { - (prj, prj_for_lim, prd): instance.max_relative_capacity_limit_total[ - prj, prj_for_lim, prd - ] + (prj, prd): instance.max_relative_capacity_limit_total[prj, prd] for ( prj, - prj_for_lim, prd, - ) in instance.RELATIVE_CAPACITY_PROJECT_PAIR_PERIODS + ) in instance.REL_CAP_PRJ_PRD } self.assertDictEqual(expected_total_max, actual_total_max) diff --git a/tests/test_data/inputs/project_relative_capacity_requirements.tab b/tests/test_data/inputs/project_relative_capacity_requirements.tab index c87c39b33..8627037b2 100644 --- a/tests/test_data/inputs/project_relative_capacity_requirements.tab +++ b/tests/test_data/inputs/project_relative_capacity_requirements.tab @@ -1,3 +1,3 @@ -project project_for_limits period min_relative_capacity_limit_new max_relative_capacity_limit_new min_relative_capacity_limit_total max_relative_capacity_limit_total -Battery Wind 2020 . 2 3 . -Battery Wind 2030 1 . . 4 \ No newline at end of file +project period min_relative_capacity_limit_new max_relative_capacity_limit_new min_relative_capacity_limit_total max_relative_capacity_limit_total +Battery 2020 . 2 3 . +Battery 2030 1 . . 4 \ No newline at end of file diff --git a/tests/test_data/inputs/project_relative_capacity_requirements_map.tab b/tests/test_data/inputs/project_relative_capacity_requirements_map.tab new file mode 100644 index 000000000..c1639b1a1 --- /dev/null +++ b/tests/test_data/inputs/project_relative_capacity_requirements_map.tab @@ -0,0 +1,4 @@ +project period project_for_limit +Battery 2020 Wind +Battery 2030 Wind +Battery 2030 Battery_Binary \ No newline at end of file