From c16e6cda79f6cf861f17d4e1e83db1c85f05426c Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 17:20:11 -0500 Subject: [PATCH 01/40] Move days_per_period parameter to config --- data_files/my_configs/config_sample.toml | 5 +++++ data_files/my_configs/materials.toml | 5 +++++ data_files/my_configs/mga_utopia.toml | 5 +++++ data_files/my_configs/monte_carlo_utopia.toml | 5 +++++ data_files/my_configs/morris_utopia.toml | 5 +++++ data_files/my_configs/seasonal_storage.toml | 5 +++++ data_files/my_configs/stepped_demand.toml | 5 +++++ temoa/core/config.py | 3 +++ temoa/data_io/component_manifest.py | 9 --------- temoa/data_io/hybrid_loader.py | 16 +--------------- temoa/tutorial_assets/config_sample.toml | 5 +++++ .../config_annualised_demand.toml | 1 + tests/testing_configs/config_emissions.toml | 1 + tests/testing_configs/config_link_test.toml | 1 + tests/testing_configs/config_materials.toml | 1 + tests/testing_configs/config_mediumville.toml | 1 + .../testing_configs/config_seasonal_storage.toml | 1 + tests/testing_configs/config_storageville.toml | 1 + tests/testing_configs/config_survival_curve.toml | 1 + tests/testing_configs/config_test_system.toml | 1 + tests/testing_configs/config_utopia.toml | 1 + tests/testing_configs/config_utopia_gv.toml | 1 + tests/testing_configs/config_utopia_mc.toml | 1 + tests/testing_configs/config_utopia_myopic.toml | 1 + .../config_utopia_stochastic.toml | 1 + 25 files changed, 58 insertions(+), 24 deletions(-) diff --git a/data_files/my_configs/config_sample.toml b/data_files/my_configs/config_sample.toml index 0174f9ec5..3ba00adbf 100644 --- a/data_files/my_configs/config_sample.toml +++ b/data_files/my_configs/config_sample.toml @@ -108,6 +108,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/materials.toml b/data_files/my_configs/materials.toml index 9889c7af9..a925429e8 100644 --- a/data_files/my_configs/materials.toml +++ b/data_files/my_configs/materials.toml @@ -103,6 +103,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/mga_utopia.toml b/data_files/my_configs/mga_utopia.toml index 255c2febf..17529830c 100644 --- a/data_files/my_configs/mga_utopia.toml +++ b/data_files/my_configs/mga_utopia.toml @@ -97,6 +97,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/monte_carlo_utopia.toml b/data_files/my_configs/monte_carlo_utopia.toml index 7394fb291..e26032928 100644 --- a/data_files/my_configs/monte_carlo_utopia.toml +++ b/data_files/my_configs/monte_carlo_utopia.toml @@ -100,6 +100,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/morris_utopia.toml b/data_files/my_configs/morris_utopia.toml index f9a722bcd..f71182853 100644 --- a/data_files/my_configs/morris_utopia.toml +++ b/data_files/my_configs/morris_utopia.toml @@ -97,6 +97,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/seasonal_storage.toml b/data_files/my_configs/seasonal_storage.toml index ed8eafa33..d7208626a 100644 --- a/data_files/my_configs/seasonal_storage.toml +++ b/data_files/my_configs/seasonal_storage.toml @@ -103,6 +103,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'representative_periods' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/data_files/my_configs/stepped_demand.toml b/data_files/my_configs/stepped_demand.toml index 6df63a370..7092d31c1 100644 --- a/data_files/my_configs/stepped_demand.toml +++ b/data_files/my_configs/stepped_demand.toml @@ -97,6 +97,11 @@ save_lp_file = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/temoa/core/config.py b/temoa/core/config.py index d61ee04e4..c0abd642a 100644 --- a/temoa/core/config.py +++ b/temoa/core/config.py @@ -48,6 +48,7 @@ def __init__( save_storage_levels: bool = False, save_lp_file: bool = False, time_sequencing: str | None = None, + days_per_period: int = 365, reserve_margin: str | None = None, MGA: dict[str, object] | None = None, SVMGA: dict[str, object] | None = None, @@ -128,6 +129,7 @@ def __init__( self.save_storage_levels = save_storage_levels self.save_lp_file = save_lp_file self.time_sequencing = time_sequencing + self.days_per_period = days_per_period self.reserve_margin = reserve_margin self.mga_inputs = MGA @@ -295,6 +297,7 @@ def __repr__(self) -> str: msg += spacer msg += '{:>{}s}: {}\n'.format('Time sequencing', width, self.time_sequencing) + msg += '{:>{}s}: {}\n'.format('Days per period', width, self.days_per_period) msg += '{:>{}s}: {}\n'.format('Planning reserve margin', width, self.reserve_margin) if self.scenario_mode == TemoaMode.MYOPIC and self.myopic_inputs is not None: diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index bb6625545..f4b8f31a0 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -313,15 +313,6 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: # ========================================================================= # Singleton and Configuration-based Components # ========================================================================= - LoadItem( - component=model.days_per_period, - table='metadata', - columns=['value'], - where_clause="element == 'days_per_period'", - custom_loader_name='_load_days_per_period', - is_period_filtered=False, - is_table_required=False, - ), LoadItem( component=model.global_discount_rate, table='metadata_real', diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index de0c6c733..6492d78bd 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -263,6 +263,7 @@ def create_data_dict(self, myopic_index: MyopicIndex | None = None) -> dict[str, # --------------------------------------------------------------------- # Load simple config-based or myopic-specific values self._load_component_data(data, model.time_sequencing, [(self.config.time_sequencing,)]) + self._load_component_data(data, model.days_per_period, [(self.config.days_per_period,)]) self._load_component_data( data, model.reserve_margin_method, [(self.config.reserve_margin,)] ) @@ -674,21 +675,6 @@ def _load_loan_rate( self._load_component_data(data, model.loan_rate, data_to_load) # --- Singleton and Configuration-based Components --- - def _load_days_per_period( - self, - data: dict[str, object], - raw_data: Sequence[tuple[object, ...]], - filtered_data: Sequence[tuple[object, ...]], - ) -> None: - """Loads the singleton days_per_period, with a fallback.""" - model = TemoaModel() - days = 365 - if filtered_data: - days = cast('int', filtered_data[0][0]) - else: - logger.info('No value for days_per_period found. Assuming 365 days per period.') - data[model.days_per_period.name] = {None: days} - def _load_global_discount_rate( self, data: dict[str, object], diff --git a/temoa/tutorial_assets/config_sample.toml b/temoa/tutorial_assets/config_sample.toml index 4cf8d7675..0414ce797 100644 --- a/temoa/tutorial_assets/config_sample.toml +++ b/temoa/tutorial_assets/config_sample.toml @@ -118,6 +118,11 @@ graphviz_output = false # storage must be tagged and the TimeSeasonSequential table filled. time_sequencing = 'seasonal_timeslices' +# Number of days represented by each planning period. +# Used to adjust flow variables for number of days represented by each season. +# E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. +days_per_period = 365 + # How contributions to the planning reserve margin are calculated # Options: # 'static' diff --git a/tests/testing_configs/config_annualised_demand.toml b/tests/testing_configs/config_annualised_demand.toml index 3e6393fe5..198a7982f 100644 --- a/tests/testing_configs/config_annualised_demand.toml +++ b/tests/testing_configs/config_annualised_demand.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "representative_periods" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_emissions.toml b/tests/testing_configs/config_emissions.toml index f06f424da..a3ec86a4b 100644 --- a/tests/testing_configs/config_emissions.toml +++ b/tests/testing_configs/config_emissions.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_link_test.toml b/tests/testing_configs/config_link_test.toml index ff8bab418..88192e4f4 100644 --- a/tests/testing_configs/config_link_test.toml +++ b/tests/testing_configs/config_link_test.toml @@ -11,6 +11,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_materials.toml b/tests/testing_configs/config_materials.toml index 81bb00f00..3eae4926f 100644 --- a/tests/testing_configs/config_materials.toml +++ b/tests/testing_configs/config_materials.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_mediumville.toml b/tests/testing_configs/config_mediumville.toml index 53f1b935d..935abdbaa 100644 --- a/tests/testing_configs/config_mediumville.toml +++ b/tests/testing_configs/config_mediumville.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_seasonal_storage.toml b/tests/testing_configs/config_seasonal_storage.toml index 760a7b88e..927446558 100644 --- a/tests/testing_configs/config_seasonal_storage.toml +++ b/tests/testing_configs/config_seasonal_storage.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "representative_periods" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_storageville.toml b/tests/testing_configs/config_storageville.toml index df73dad14..79a2585d0 100644 --- a/tests/testing_configs/config_storageville.toml +++ b/tests/testing_configs/config_storageville.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_survival_curve.toml b/tests/testing_configs/config_survival_curve.toml index 2c1d051e2..fa28822a1 100644 --- a/tests/testing_configs/config_survival_curve.toml +++ b/tests/testing_configs/config_survival_curve.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_test_system.toml b/tests/testing_configs/config_test_system.toml index b776c317d..25acdfe59 100644 --- a/tests/testing_configs/config_test_system.toml +++ b/tests/testing_configs/config_test_system.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_utopia.toml b/tests/testing_configs/config_utopia.toml index e13262f29..1e7080c4a 100644 --- a/tests/testing_configs/config_utopia.toml +++ b/tests/testing_configs/config_utopia.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_utopia_gv.toml b/tests/testing_configs/config_utopia_gv.toml index 4112427de..cc5d93a5e 100644 --- a/tests/testing_configs/config_utopia_gv.toml +++ b/tests/testing_configs/config_utopia_gv.toml @@ -8,6 +8,7 @@ save_excel = false save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" graphviz_output = true diff --git a/tests/testing_configs/config_utopia_mc.toml b/tests/testing_configs/config_utopia_mc.toml index acd9cd0cc..40f8993dc 100644 --- a/tests/testing_configs/config_utopia_mc.toml +++ b/tests/testing_configs/config_utopia_mc.toml @@ -10,6 +10,7 @@ neos = false solver_name = "appsi_highs" time_sequencing = 'seasonal_timeslices' +days_per_period = 365 reserve_margin = 'static' [monte_carlo] diff --git a/tests/testing_configs/config_utopia_myopic.toml b/tests/testing_configs/config_utopia_myopic.toml index bbfff7863..6ac0103e8 100644 --- a/tests/testing_configs/config_utopia_myopic.toml +++ b/tests/testing_configs/config_utopia_myopic.toml @@ -8,6 +8,7 @@ save_excel = true save_duals = true save_lp_file = false time_sequencing = "seasonal_timeslices" +days_per_period = 365 reserve_margin = "static" [MGA] diff --git a/tests/testing_configs/config_utopia_stochastic.toml b/tests/testing_configs/config_utopia_stochastic.toml index 78fa81a9a..a1dcefc70 100644 --- a/tests/testing_configs/config_utopia_stochastic.toml +++ b/tests/testing_configs/config_utopia_stochastic.toml @@ -6,6 +6,7 @@ output_database = "tests/testing_outputs/utopia_stochastic.sqlite" output_path = "tests/testing_outputs/utopia_stochastic" solver_name = "appsi_highs" time_sequencing = "seasonal_timeslices" +days_per_period = 365 save_duals = false [stochastic] From dcae359d8558e6e2645050a2231833b8058dede6 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 17:35:58 -0500 Subject: [PATCH 02/40] Remove days_per_period from all sql files --- data_files/example_dbs/materials.sql | 1 - data_files/example_dbs/morris_utopia.sql | 1 - data_files/example_dbs/seasonal_storage.sql | 1 - data_files/example_dbs/stepped_demand.sql | 1 - data_files/example_dbs/survival_curve.sql | 1 - data_files/example_dbs/test_system.sql | 1 - data_files/example_dbs/utopia.sql | 1 - data_files/temoa_basics_1.sql | 2 -- data_files/temoa_basics_2.sql | 2 -- data_files/temoa_schema_v3_1.sql | 2 -- data_files/temoa_schema_v4.sql | 2 -- temoa/db_schema/temoa_schema_v3_1.sql | 2 -- temoa/db_schema/temoa_schema_v4.sql | 2 -- temoa/tutorial_assets/utopia.sql | 1 - tests/testing_data/annualised_demand.sql | 1 - tests/testing_data/emissions.sql | 1 - tests/testing_data/materials.sql | 1 - tests/testing_data/mediumville.sql | 1 - tests/testing_data/seasonal_storage.sql | 1 - tests/testing_data/simple_linked_tech.sql | 1 - tests/testing_data/storageville.sql | 1 - tests/testing_data/survival_curve.sql | 1 - tests/testing_data/test_system.sql | 1 - tests/testing_data/utopia_data.sql | 1 - 24 files changed, 30 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 19d8a03b5..5ce2f7286 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1122,7 +1122,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 0ec374ed2..aaf9bf7ba 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1115,7 +1115,6 @@ CREATE TABLE metadata PRIMARY KEY (element) ); INSERT INTO "metadata" VALUES('myopic_base_year',2000,'Base Year for Myopic Analysis'); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 5bd5b3710..a242a9be5 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -675,7 +675,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index fd176f069..80b18182e 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -9,7 +9,6 @@ CREATE TABLE MetaData ); INSERT INTO MetaData VALUES('DB_MAJOR',3,'DB major version number'); INSERT INTO MetaData VALUES('DB_MINOR',1,'DB minor version number'); -INSERT INTO MetaData VALUES('days_per_period', 365, 'count of days in each period'); CREATE TABLE MetaDataReal ( element TEXT, diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index ea6055117..9d77a8b72 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -775,7 +775,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 89b181fc9..7b2e616f9 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1102,7 +1102,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 72ab60a18..621c16453 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1112,7 +1112,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/data_files/temoa_basics_1.sql b/data_files/temoa_basics_1.sql index d951941e1..cdab9f8de 100644 --- a/data_files/temoa_basics_1.sql +++ b/data_files/temoa_basics_1.sql @@ -12,8 +12,6 @@ REPLACE INTO MetaData VALUES ('DB_MAJOR', 3, 'DB major version number'); REPLACE INTO MetaData VALUES ('DB_MINOR', 1, 'DB minor version number'); -REPLACE INTO MetaData -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS MetaDataReal ( element TEXT, diff --git a/data_files/temoa_basics_2.sql b/data_files/temoa_basics_2.sql index f65169e0b..717226eed 100644 --- a/data_files/temoa_basics_2.sql +++ b/data_files/temoa_basics_2.sql @@ -12,8 +12,6 @@ REPLACE INTO MetaData VALUES ('DB_MAJOR', 3, 'DB major version number'); REPLACE INTO MetaData VALUES ('DB_MINOR', 1, 'DB minor version number'); -REPLACE INTO MetaData -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS MetaDataReal ( element TEXT, diff --git a/data_files/temoa_schema_v3_1.sql b/data_files/temoa_schema_v3_1.sql index b91d03ce5..05015865c 100644 --- a/data_files/temoa_schema_v3_1.sql +++ b/data_files/temoa_schema_v3_1.sql @@ -12,8 +12,6 @@ REPLACE INTO MetaData VALUES ('DB_MAJOR', 3, 'DB major version number'); REPLACE INTO MetaData VALUES ('DB_MINOR', 1, 'DB minor version number'); -REPLACE INTO MetaData -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS MetaDataReal ( diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 8efedde67..5cf0581b4 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -12,8 +12,6 @@ REPLACE INTO metadata VALUES ('DB_MAJOR', 4, 'DB major version number'); REPLACE INTO metadata VALUES ('DB_MINOR', 0, 'DB minor version number'); -REPLACE INTO metadata -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS metadata_real ( diff --git a/temoa/db_schema/temoa_schema_v3_1.sql b/temoa/db_schema/temoa_schema_v3_1.sql index b91d03ce5..05015865c 100644 --- a/temoa/db_schema/temoa_schema_v3_1.sql +++ b/temoa/db_schema/temoa_schema_v3_1.sql @@ -12,8 +12,6 @@ REPLACE INTO MetaData VALUES ('DB_MAJOR', 3, 'DB major version number'); REPLACE INTO MetaData VALUES ('DB_MINOR', 1, 'DB minor version number'); -REPLACE INTO MetaData -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS MetaDataReal ( diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 8efedde67..5cf0581b4 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -12,8 +12,6 @@ REPLACE INTO metadata VALUES ('DB_MAJOR', 4, 'DB major version number'); REPLACE INTO metadata VALUES ('DB_MINOR', 0, 'DB minor version number'); -REPLACE INTO metadata -VALUES ('days_per_period', 365, 'count of days in each period'); CREATE TABLE IF NOT EXISTS metadata_real ( diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 24138883c..0394b5bbb 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1118,7 +1118,6 @@ CREATE TABLE metadata notes TEXT, PRIMARY KEY (element) ); -INSERT INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); INSERT INTO "metadata" VALUES('DB_MINOR',0,''); CREATE TABLE metadata_real diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index a69b0e57a..bf57681e4 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -31,7 +31,6 @@ REPLACE INTO "limit_activity" VALUES('region',2000,'annual','le',0.5,NULL,NULL); REPLACE INTO "limit_activity" VALUES('region',2000,'non_annual','le',0.5,NULL,NULL); REPLACE INTO "loan_lifetime_process" VALUES('region', 'annual', 2000, 1.0, NULL, NULL); REPLACE INTO "loan_lifetime_process" VALUES('region', 'non_annual', 2000, 1.0, NULL, NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 25faaf3e3..9210d4709 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -67,7 +67,6 @@ REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechOrdinary','ge',1.0,N REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechCurtailment','ge',1.0,NULL,NULL); REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechOrdinary','le',1.0,NULL,NULL); REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechCurtailment','le',1.0,NULL,NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index abf2c3c0f..3401ab8a8 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -393,7 +393,6 @@ REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2010,'electricity' REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2010,'diesel','CAR_PHEV','le',0.8,''); REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2020,'electricity','CAR_PHEV','le',0.2,''); REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2020,'diesel','CAR_PHEV','le',0.8,NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index dcd0f59bd..38eac086a 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -140,7 +140,6 @@ REPLACE INTO "loan_lifetime_process" VALUES('B', 'GeoHeater', 2025, 10.0, NULL, REPLACE INTO "loan_lifetime_process" VALUES('B', 'GeoThermal', 2025, 10.0, NULL, NULL); REPLACE INTO "loan_lifetime_process" VALUES('A-B', 'FGF_pipe', 2025, 10.0, NULL, NULL); REPLACE INTO "loan_lifetime_process" VALUES('B-A', 'FGF_pipe', 2025, 10.0, NULL, NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 70d88e5ac..f22dc32ae 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -42,7 +42,6 @@ REPLACE INTO "efficiency" VALUES('region', 'electricity', 'seas_stor', 2000, 'el REPLACE INTO "efficiency" VALUES('region', 'electricity', 'demand', 2000, 'demand', 1.0, NULL, NULL); REPLACE INTO "limit_storage_level_fraction" VALUES('region',2000,'winter','b','seas_stor',2000,'e',0.5,NULL); REPLACE INTO "limit_storage_level_fraction" VALUES('region',2000,'charge','b','dly_stor',2000,'e',0.5,NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index 359f62cea..c73297039 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -27,7 +27,6 @@ REPLACE INTO "emission_activity" VALUES('linkville','CO2','NGA','PLANT',2000,'EL REPLACE INTO "lifetime_tech" VALUES('linkville', 'CCS', 100.0, NULL, ''); REPLACE INTO "lifetime_tech" VALUES('linkville', 'PLANT', 100.0, NULL, ''); REPLACE INTO "linked_tech" VALUES('linkville','PLANT','CO2','CCS',NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 53e176bd9..3bf6ee5d4 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -41,7 +41,6 @@ REPLACE INTO "limit_capacity" VALUES('electricville',2025,'batt','ge',0.1,'','') REPLACE INTO "limit_capacity" VALUES('electricville',2025,'EH','le',200.0,'',''); REPLACE INTO "limit_capacity" VALUES('electricville',2025,'batt','le',100.0,'',''); REPLACE INTO "limit_storage_level_fraction" VALUES('electricville',2025,'s1','d1','batt',2025,'e',0.5,NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index de16ef19d..b8483c1f9 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -142,7 +142,6 @@ REPLACE INTO "lifetime_tech" VALUES('region', 'tech_ancient', 35.0, NULL, NULL); REPLACE INTO "lifetime_tech" VALUES('region', 'tech_old', 35.0, NULL, NULL); REPLACE INTO "lifetime_tech" VALUES('region', 'tech_current', 35.0, NULL, NULL); REPLACE INTO "lifetime_tech" VALUES('region', 'tech_future', 35.0, NULL, NULL); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 83a9237a5..6e0cd393a 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -469,7 +469,6 @@ REPLACE INTO "limit_tech_output_split" VALUES('R2',2025,'S_OILREF','GSL','ge',0. REPLACE INTO "limit_tech_output_split" VALUES('R2',2025,'S_OILREF','DSL','ge',0.08,''); REPLACE INTO "limit_tech_output_split" VALUES('R2',2030,'S_OILREF','GSL','ge',0.72,''); REPLACE INTO "limit_tech_output_split" VALUES('R2',2030,'S_OILREF','DSL','ge',0.08,''); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index 8e99da42a..1d1ab6dc8 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -479,7 +479,6 @@ REPLACE INTO "limit_tech_output_split" VALUES('utopia',2010,'SRE','DSL','ge',0.7 REPLACE INTO "limit_tech_output_split" VALUES('utopia',1990,'SRE','GSL','ge',0.3,''); REPLACE INTO "limit_tech_output_split" VALUES('utopia',2000,'SRE','GSL','ge',0.3,''); REPLACE INTO "limit_tech_output_split" VALUES('utopia',2010,'SRE','GSL','ge',0.3,''); -REPLACE INTO "metadata" VALUES('days_per_period',365,'count of days in each period'); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); From 5b2ddd3c00f926e34d480c25b3666551630c9e20 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 20:28:20 -0500 Subject: [PATCH 03/40] First pass at removing period index on seasons --- data_files/example_dbs/materials.sql | 92 ++------ data_files/example_dbs/morris_utopia.sql | 48 ++-- data_files/example_dbs/seasonal_storage.sql | 58 +++-- data_files/example_dbs/stepped_demand.sql | 6 +- data_files/example_dbs/survival_curve.sql | 26 +-- data_files/example_dbs/test_system.sql | 60 ++--- data_files/example_dbs/utopia.sql | 48 ++-- data_files/temoa_schema_v4.sql | 10 +- temoa/_internal/exchange_tech_cost_ledger.py | 4 +- temoa/_internal/table_data_puller.py | 26 +-- temoa/components/capacity.py | 16 +- temoa/components/commodities.py | 38 ++-- temoa/components/costs.py | 4 +- temoa/components/emissions.py | 6 +- temoa/components/flows.py | 10 +- temoa/components/limits.py | 32 +-- temoa/components/operations.py | 56 +++-- temoa/components/reserves.py | 12 +- temoa/components/storage.py | 24 +- temoa/components/technology.py | 2 +- temoa/components/time.py | 208 ++++++++---------- temoa/core/model.py | 24 +- temoa/data_io/component_manifest.py | 8 +- temoa/data_io/hybrid_loader.py | 37 +--- temoa/db_schema/temoa_schema_v4.sql | 10 +- .../single_vector_mga/sv_mga_sequencer.py | 2 +- temoa/model_checking/validators.py | 2 +- temoa/tutorial_assets/utopia.sql | 56 +---- temoa/utilities/unit_cost_explorer.py | 10 +- tests/test_exchange_cost_ledger.py | 2 +- tests/test_storage.py | 2 +- tests/testing_data/annualised_demand.sql | 4 +- tests/testing_data/emissions.sql | 9 +- tests/testing_data/materials.sql | 88 +++----- tests/testing_data/mediumville.sql | 12 +- tests/testing_data/seasonal_storage.sql | 48 ++-- tests/testing_data/simple_linked_tech.sql | 8 +- tests/testing_data/storageville.sql | 24 +- tests/testing_data/survival_curve.sql | 19 +- tests/testing_data/test_system.sql | 48 +--- tests/testing_data/utopia_data.sql | 36 +-- 41 files changed, 466 insertions(+), 769 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 5ce2f7286..433fd5b91 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1529,97 +1529,53 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(2000,1,'summer',NULL); -INSERT INTO "time_season" VALUES(2000,2,'autumn',NULL); -INSERT INTO "time_season" VALUES(2000,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2000,4,'spring',NULL); -INSERT INTO "time_season" VALUES(2010,5,'summer',NULL); -INSERT INTO "time_season" VALUES(2010,6,'autumn',NULL); -INSERT INTO "time_season" VALUES(2010,7,'winter',NULL); -INSERT INTO "time_season" VALUES(2010,8,'spring',NULL); -INSERT INTO "time_season" VALUES(2020,9,'summer',NULL); -INSERT INTO "time_season" VALUES(2020,10,'autumn',NULL); -INSERT INTO "time_season" VALUES(2020,11,'winter',NULL); -INSERT INTO "time_season" VALUES(2020,12,'spring',NULL); + PRIMARY KEY (sequence, season) +); +INSERT INTO "time_season" VALUES(0,'summer',NULL); +INSERT INTO "time_season" VALUES(1,'autumn',NULL); +INSERT INTO "time_season" VALUES(2,'winter',NULL); +INSERT INTO "time_season" VALUES(3,'spring',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'autumn','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'spring','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'autumn','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'spring','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'autumn','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'spring','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'autumn','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'spring','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'autumn','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'spring','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'autumn','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'spring','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'autumn','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'spring','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'autumn','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2010,'spring','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'autumn','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','morning',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'autumn','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','afternoon',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'autumn','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','evening',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'autumn','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','overnight',0.0625,NULL); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','overnight',0.0625,NULL); +INSERT INTO "time_segment_fraction" VALUES('summer', 'morning', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('autumn', 'morning', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('winter', 'morning', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('spring', 'morning', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('summer', 'afternoon', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('autumn', 'afternoon', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('winter', 'afternoon', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('spring', 'afternoon', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('summer', 'evening', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('autumn', 'evening', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('winter', 'evening', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('spring', 'evening', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('summer', 'overnight', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('autumn', 'overnight', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('winter', 'overnight', 0.0625, NULL); +INSERT INTO "time_segment_fraction" VALUES('spring', 'overnight', 0.0625, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index aaf9bf7ba..b69844db6 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1524,64 +1524,42 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(1990,2,'summer',NULL); -INSERT INTO "time_season" VALUES(1990,3,'winter',NULL); -INSERT INTO "time_season" VALUES(1990,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2000,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2000,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2000,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2010,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2010,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2010,1,'inter',NULL); + PRIMARY KEY (sequence, season) +); +INSERT INTO "time_season" VALUES(0,'summer',NULL); +INSERT INTO "time_season" VALUES(1,'winter',NULL); +INSERT INTO "time_season" VALUES(2,'inter',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','night',0.1667,'# W-N'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index a242a9be5..d3d37b34c 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1076,61 +1076,57 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) + PRIMARY KEY (sequence, season) ); -INSERT INTO "time_season" VALUES(2000,0,'charge',NULL); -INSERT INTO "time_season" VALUES(2000,1,'discharge',NULL); +INSERT INTO "time_season" VALUES(0,'charge',NULL); +INSERT INTO "time_season" VALUES(1,'discharge',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); -INSERT INTO "time_season_sequential" VALUES(2000,1,'summer','charge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,2,'sept_w1','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,3,'sept_w2','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,4,'sept_w3','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,5,'sept_w4','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,6,'sept_29th','discharge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,7,'sept_30th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,8,'winter','discharge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,9,'apr_w1','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,10,'apr_w2','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,11,'apr_w3','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,12,'apr_w4','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,13,'apr_29th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(2000,14,'apr_30th','discharge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES('summer','charge',152.5,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_w1','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_w2','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_w3','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_w4','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_29th','discharge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES('sept_30th','charge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES('winter','discharge',152.5,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_w1','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_w2','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_w3','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_w4','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_29th','charge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES('apr_30th','discharge',1.0,NULL); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(2000,'charge','a',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'charge','b',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'charge','c',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'charge','d',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'discharge','a',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'discharge','b',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'discharge','c',0.125,NULL); -INSERT INTO "time_segment_fraction" VALUES(2000,'discharge','d',0.125,NULL); +INSERT INTO "time_segment_fraction" VALUES('charge', 'a', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('charge', 'b', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('charge', 'c', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('charge', 'd', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('discharge', 'a', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('discharge', 'b', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('discharge', 'c', 0.125, NULL); +INSERT INTO "time_segment_fraction" VALUES('discharge', 'd', 0.125, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index 80b18182e..ad38d0c70 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1223,15 +1223,13 @@ INSERT INTO TimeSeason VALUES(2050,2,'summer',NULL); INSERT INTO TimeSeason VALUES(2050,3,'winter',NULL); CREATE TABLE time_season_sequential ( - period INTEGER - REFERENCES TimePeriod (period), - sequence INTEGER, + sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES SeasonLabel (season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE TimePeriodType diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 9d77a8b72..e7239164e 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1162,49 +1162,35 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(2025,0,'s',NULL); -INSERT INTO "time_season" VALUES(2030,1,'s',NULL); -INSERT INTO "time_season" VALUES(2035,2,'s',NULL); -INSERT INTO "time_season" VALUES(2040,3,'s',NULL); -INSERT INTO "time_season" VALUES(2045,4,'s',NULL); -INSERT INTO "time_season" VALUES(2050,5,'s',NULL); + PRIMARY KEY (sequence, season) +); +INSERT INTO "time_season" VALUES(0,'s',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(2025,'s','d',1.0,NULL); -INSERT INTO "time_segment_fraction" VALUES(2030,'s','d',1.0,NULL); -INSERT INTO "time_segment_fraction" VALUES(2035,'s','d',1.0,NULL); -INSERT INTO "time_segment_fraction" VALUES(2040,'s','d',1.0,NULL); -INSERT INTO "time_segment_fraction" VALUES(2045,'s','d',1.0,NULL); -INSERT INTO "time_segment_fraction" VALUES(2050,'s','d',1.0,NULL); +INSERT INTO "time_segment_fraction" VALUES('s', 'd', 1.0, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 7b2e616f9..56ccc2127 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1510,73 +1510,45 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(2020,1,'spring',NULL); -INSERT INTO "time_season" VALUES(2020,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2020,3,'fall',NULL); -INSERT INTO "time_season" VALUES(2020,4,'winter',NULL); -INSERT INTO "time_season" VALUES(2025,1,'spring',NULL); -INSERT INTO "time_season" VALUES(2025,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2025,3,'fall',NULL); -INSERT INTO "time_season" VALUES(2025,4,'winter',NULL); -INSERT INTO "time_season" VALUES(2030,1,'spring',NULL); -INSERT INTO "time_season" VALUES(2030,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2030,3,'fall',NULL); -INSERT INTO "time_season" VALUES(2030,4,'winter',NULL); + PRIMARY KEY (sequence, season) +); +INSERT INTO "time_season" VALUES(0,'spring',NULL); +INSERT INTO "time_season" VALUES(1,'summer',NULL); +INSERT INTO "time_season" VALUES(2,'fall',NULL); +INSERT INTO "time_season" VALUES(3,'winter',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','day',0.125,'Spring - Day'); -INSERT INTO "time_segment_fraction" VALUES(2020,'spring','night',0.125,'Spring - Night'); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','day',0.125,'Summer - Day'); -INSERT INTO "time_segment_fraction" VALUES(2020,'summer','night',0.125,'Summer - Night'); -INSERT INTO "time_segment_fraction" VALUES(2020,'fall','day',0.125,'Fall - Day'); -INSERT INTO "time_segment_fraction" VALUES(2020,'fall','night',0.125,'Fall - Night'); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','day',0.125,'Winter - Day'); -INSERT INTO "time_segment_fraction" VALUES(2020,'winter','night',0.125,'Winter - Night'); -INSERT INTO "time_segment_fraction" VALUES(2025,'spring','day',0.125,'Spring - Day'); -INSERT INTO "time_segment_fraction" VALUES(2025,'spring','night',0.125,'Spring - Night'); -INSERT INTO "time_segment_fraction" VALUES(2025,'summer','day',0.125,'Summer - Day'); -INSERT INTO "time_segment_fraction" VALUES(2025,'summer','night',0.125,'Summer - Night'); -INSERT INTO "time_segment_fraction" VALUES(2025,'fall','day',0.125,'Fall - Day'); -INSERT INTO "time_segment_fraction" VALUES(2025,'fall','night',0.125,'Fall - Night'); -INSERT INTO "time_segment_fraction" VALUES(2025,'winter','day',0.125,'Winter - Day'); -INSERT INTO "time_segment_fraction" VALUES(2025,'winter','night',0.125,'Winter - Night'); -INSERT INTO "time_segment_fraction" VALUES(2030,'spring','day',0.125,'Spring - Day'); -INSERT INTO "time_segment_fraction" VALUES(2030,'spring','night',0.125,'Spring - Night'); -INSERT INTO "time_segment_fraction" VALUES(2030,'summer','day',0.125,'Summer - Day'); -INSERT INTO "time_segment_fraction" VALUES(2030,'summer','night',0.125,'Summer - Night'); -INSERT INTO "time_segment_fraction" VALUES(2030,'fall','day',0.125,'Fall - Day'); -INSERT INTO "time_segment_fraction" VALUES(2030,'fall','night',0.125,'Fall - Night'); -INSERT INTO "time_segment_fraction" VALUES(2030,'winter','day',0.125,'Winter - Day'); -INSERT INTO "time_segment_fraction" VALUES(2030,'winter','night',0.125,'Winter - Night'); +INSERT INTO "time_segment_fraction" VALUES('spring', 'day', 0.125, 'Spring - Day'); +INSERT INTO "time_segment_fraction" VALUES('spring', 'night', 0.125, 'Spring - Night'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.125, 'Summer - Day'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.125, 'Summer - Night'); +INSERT INTO "time_segment_fraction" VALUES('fall', 'day', 0.125, 'Fall - Day'); +INSERT INTO "time_segment_fraction" VALUES('fall', 'night', 0.125, 'Fall - Night'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.125, 'Winter - Day'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.125, 'Winter - Night'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 621c16453..6b36306fe 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1521,64 +1521,42 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(1990,1,'inter',NULL); -INSERT INTO "time_season" VALUES(1990,2,'summer',NULL); -INSERT INTO "time_season" VALUES(1990,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2000,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2000,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2000,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2010,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2010,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2010,3,'winter',NULL); + PRIMARY KEY (sequence, season) +); +INSERT INTO "time_season" VALUES(0,'inter',NULL); +INSERT INTO "time_season" VALUES(1,'summer',NULL); +INSERT INTO "time_season" VALUES(2,'winter',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','night',0.1667,'# W-N'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 5cf0581b4..3494da570 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -885,15 +885,13 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate ); CREATE TABLE IF NOT EXISTS time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS storage_duration @@ -1046,22 +1044,20 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) + PRIMARY KEY (sequence, season) ); CREATE TABLE IF NOT EXISTS time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); diff --git a/temoa/_internal/exchange_tech_cost_ledger.py b/temoa/_internal/exchange_tech_cost_ledger.py index cf90257eb..12b170f5f 100644 --- a/temoa/_internal/exchange_tech_cost_ledger.py +++ b/temoa/_internal/exchange_tech_cost_ledger.py @@ -90,7 +90,7 @@ def get_use_ratio( act_dir1 = value( sum( model.v_flow_out[rr1, period, s, d, s_i, tech, vintage, s_o] - for s in model.time_season[period] + for s in model.time_season for d in model.time_of_day for s_i in model.process_inputs[rr1, period, tech, vintage] for s_o in model.process_outputs_by_input[rr1, period, tech, vintage, s_i] @@ -99,7 +99,7 @@ def get_use_ratio( act_dir2 = value( sum( model.v_flow_out[rr2, period, s, d, s_i, tech, vintage, s_o] - for s in model.time_season[period] + for s in model.time_season for d in model.time_of_day for s_i in model.process_inputs[rr2, period, tech, vintage] for s_o in model.process_outputs_by_input[rr2, period, tech, vintage, s_i] diff --git a/temoa/_internal/table_data_puller.py b/temoa/_internal/table_data_puller.py index afa06f9e1..0d87d2273 100644 --- a/temoa/_internal/table_data_puller.py +++ b/temoa/_internal/table_data_puller.py @@ -152,12 +152,12 @@ def poll_flow_results(model: TemoaModel, epsilon: float = 1e-5) -> dict[FI, dict # Make sure this isn't just a non-annual demand tech if t not in model.tech_annual: continue - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: if o in model.commodity_demand: distribution = value(model.demand_specific_distribution[r, p, s, d, o]) else: - distribution = value(model.segment_fraction[p, s, d]) + distribution = value(model.segment_fraction[s, d]) fi = FI(r, p, s, d, i, t, v, o) flow = value(model.v_flow_out_annual[r, p, i, t, v, o]) * distribution if abs(flow) < epsilon: @@ -170,11 +170,11 @@ def poll_flow_results(model: TemoaModel, epsilon: float = 1e-5) -> dict[FI, dict # flex annual for r, p, i, t, v, o in model.v_flex_annual.keys(): - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: fi = FI(r, p, s, d, i, t, v, o) flow = value(model.v_flex_annual[r, p, i, t, v, o]) * value( - model.segment_fraction[p, s, d] + model.segment_fraction[s, d] ) if abs(flow) < epsilon: continue @@ -188,10 +188,10 @@ def poll_flow_results(model: TemoaModel, epsilon: float = 1e-5) -> dict[FI, dict * value(model.v_new_capacity[r, t, v]) / value(model.period_length[v]) ) - for s in model.time_season[v]: + for s in model.time_season: for d in model.time_of_day: fi = FI(r, v, s, d, i, t, v, cast('Commodity', 'construction_input')) - flow = annual * value(model.segment_fraction[v, s, d]) + flow = annual * value(model.segment_fraction[s, d]) if abs(flow) < epsilon: continue res[fi][FlowType.IN] = flow @@ -204,10 +204,10 @@ def poll_flow_results(model: TemoaModel, epsilon: float = 1e-5) -> dict[FI, dict annual = value(model.end_of_life_output[r, t, v, o]) * value( model.v_annual_retirement[r, p, t, v] ) - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: fi = FI(r, p, s, d, cast('Commodity', 'end_of_life_output'), t, v, o) - flow = annual * value(model.segment_fraction[p, s, d]) + flow = annual * value(model.segment_fraction[s, d]) if abs(flow) < epsilon: continue res[fi][FlowType.OUT] = flow @@ -229,7 +229,7 @@ def poll_storage_level_results(model: TemoaModel, epsilon: float = 1e-5) -> dict if t in model.tech_seasonal_storage: continue state = value(model.v_storage_level[r, p, s, d, t, v]) / ( - value(model.segment_fraction_per_season[p, s]) * value(model.days_per_period) + value(model.segment_fraction_per_season[s]) * value(model.days_per_period) ) sli = SLI(r, p, s, d, t, v) if abs(state) < epsilon: @@ -241,8 +241,8 @@ def poll_storage_level_results(model: TemoaModel, epsilon: float = 1e-5) -> dict # Ratio of days in virtual storage season to days in actual season # Flows and StorageLevel are normalised to the number of days in the ACTUAL season, so must # be adjusted to the number of days in the virtual storage season - days_adjust = value(model.time_season_sequential[p, s_seq, s]) / ( - value(model.segment_fraction_per_season[p, s]) * value(model.days_per_period) + days_adjust = value(model.time_season_sequential[s_seq, s]) / ( + value(model.segment_fraction_per_season[s]) * value(model.days_per_period) ) for d in model.time_of_day: state = ( @@ -408,7 +408,7 @@ def poll_cost_results( value(model.v_flow_out[r, p, S_s, S_d, S_i, t, v, S_o]) for S_i in model.process_inputs[r, p, t, v] for S_o in model.process_outputs_by_input[r, p, t, v, S_i] - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day ) else: @@ -597,7 +597,7 @@ def poll_emissions( normal = [ (r, p, e, s, d, i, t, v, o) for (r, p, e, i, t, v, o) in base - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day if t not in model.tech_annual ] diff --git a/temoa/components/capacity.py b/temoa/components/capacity.py index 790bd4adf..688aaa885 100644 --- a/temoa/components/capacity.py +++ b/temoa/components/capacity.py @@ -60,7 +60,7 @@ def check_capacity_factor_process(model: TemoaModel) -> None: # Check if all possible values have been set by process # log a warning if some are missing (allowed but maybe accidental) for (r, p, t, v), count in count_rptv.items(): - num_seg = len(model.time_season[p]) * len(model.time_of_day) + num_seg = len(model.time_season) * len(model.time_of_day) if count > 0: model.is_capacity_factor_process[r, p, t, v] = True if count < num_seg: @@ -91,7 +91,7 @@ def create_capacity_factors(model: TemoaModel) -> None: (r, p, s, d, t, v) for (r, t, v) in processes for p in model.process_periods[r, t, v] - for s, d in cross_product(model.time_season[p], model.time_of_day) + for s, d in cross_product(model.time_season, model.time_of_day) } # Step 2 @@ -220,7 +220,7 @@ def capacity_constraint_indices( if t not in model.tech_annual or t in model.tech_demand: if t not in model.tech_uncap: if t not in model.tech_storage: - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: capacity_indices.add((r, p, s, d, t, v)) else: @@ -236,7 +236,7 @@ def capacity_factor_process_indices( indices: set[tuple[Region, Season, TimeOfDay, Technology, Vintage]] = set() for r, _i, t, v, _o in model.efficiency.sparse_iterkeys(): for p in model.time_optimize: - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: indices.add((r, s, d, t, v)) return indices @@ -248,7 +248,7 @@ def capacity_factor_tech_indices( all_cfs: set[tuple[Region, Period, Season, TimeOfDay, Technology]] = set() if model.active_capacity_available_rpt: for r, p, t in model.active_capacity_available_rpt: - for s in model.time_season[p]: + for s in model.time_season: for d in model.time_of_day: all_cfs.add((r, p, s, d, t)) else: @@ -447,7 +447,7 @@ def capacity_constraint( ( value(model.demand_specific_distribution[r, p, s, d, S_o]) if S_o in model.commodity_demand - else value(model.segment_fraction[p, s, d]) + else value(model.segment_fraction[s, d]) ) * model.v_flow_out_annual[r, p, S_i, t, v, S_o] for S_i in model.process_inputs[r, p, t, v] @@ -465,7 +465,7 @@ def capacity_constraint( # capacity must be available to cover both activity and curtailment. return get_capacity_factor(model, r, p, s, d, t, v) * value( model.capacity_to_activity[r, t] - ) * value(model.segment_fraction[p, s, d]) * model.v_capacity[ + ) * value(model.segment_fraction[s, d]) * model.v_capacity[ r, p, t, v ] == useful_activity + sum( model.v_curtailment[r, p, s, d, S_i, t, v, S_o] @@ -476,7 +476,7 @@ def capacity_constraint( return ( get_capacity_factor(model, r, p, s, d, t, v) * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) * model.v_capacity[r, p, t, v] >= useful_activity ) diff --git a/temoa/components/commodities.py b/temoa/components/commodities.py index 1ece9382f..de80b56ca 100644 --- a/temoa/components/commodities.py +++ b/temoa/components/commodities.py @@ -107,7 +107,7 @@ def demand_activity_constraint_indices( for r, p, dem in model.demand_constraint_rpc for t, v in model.commodity_up_stream_process[r, p, dem] if t not in model.tech_annual - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } return indices @@ -124,7 +124,7 @@ def commodity_balance_constraint_indices( # r in this line includes interregional transfer combinations (not needed). if r in model.regions # this line ensures only the regions are included. and c not in model.commodity_annual - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -388,7 +388,7 @@ def commodity_balance_constraint( ( value(model.demand_specific_distribution[r, p, s, d, s_o]) if s_o in model.commodity_demand - else value(model.segment_fraction[p, s, d]) + else value(model.segment_fraction[s, d]) ) * model.v_flow_out_annual[r, p, c, s_t, s_v, s_o] / get_variable_efficiency(model, r, p, s, d, c, s_t, s_v, s_o) @@ -401,7 +401,7 @@ def commodity_balance_constraint( # Consumed by building capacity # Assume evenly distributed over a year consumed += ( - value(model.segment_fraction[p, s, d]) + value(model.segment_fraction[s, d]) * sum( value(model.construction_input[r, c, s_t, p]) * model.v_new_capacity[r, s_t, p] for s_t in model.capacity_consumption_techs[r, p, c] @@ -419,7 +419,7 @@ def commodity_balance_constraint( ) # From annual flows - produced += value(model.segment_fraction[p, s, d]) * sum( + produced += value(model.segment_fraction[s, d]) * sum( model.v_flow_out_annual[r, p, s_i, s_t, s_v, c] for s_t, s_v in model.commodity_up_stream_process[r, p, c] if s_t in model.tech_annual @@ -435,7 +435,7 @@ def commodity_balance_constraint( for s_i in model.process_inputs_by_output[r, p, s_t, s_v, c] ) # Wasted by annual flex flows - consumed += value(model.segment_fraction[p, s, d]) * sum( + consumed += value(model.segment_fraction[s, d]) * sum( model.v_flex_annual[r, p, s_i, s_t, s_v, c] for s_t, s_v in model.commodity_up_stream_process[r, p, c] if s_t in model.tech_annual and s_t in model.tech_flex @@ -445,7 +445,7 @@ def commodity_balance_constraint( if (r, p, c) in model.retirement_production_processes: # Produced by retiring capacity # Assume evenly distributed over a year - produced += value(model.segment_fraction[p, s, d]) * sum( + produced += value(model.segment_fraction[s, d]) * sum( value(model.end_of_life_output[r, s_t, s_v, c]) * model.v_annual_retirement[r, p, s_t, s_v] for s_t, s_v in model.retirement_production_processes[r, p, c] @@ -462,7 +462,7 @@ def commodity_balance_constraint( if s_t not in model.tech_annual ) consumed += sum( - value(model.segment_fraction[p, s, d]) + value(model.segment_fraction[s, d]) * model.v_flow_out_annual[r + '-' + reg, p, c, s_t, s_v, S_o] / get_variable_efficiency( model, cast('Region', r + '-' + reg), p, s, d, c, s_t, s_v, S_o @@ -479,7 +479,7 @@ def commodity_balance_constraint( if s_t not in model.tech_annual ) produced += sum( - value(model.segment_fraction[p, s, d]) + value(model.segment_fraction[s, d]) * model.v_flow_out_annual[reg + '-' + r, p, s_i, s_t, s_v, c] for reg, s_t, s_v, s_i in model.import_regions[r, p, c] if s_t in model.tech_annual @@ -520,7 +520,7 @@ def annual_commodity_balance_constraint( # For other techs, it would be redundant as in = out / eff consumed += sum( model.v_flow_in[r, p, s_s, s_d, c, s_t, s_v, s_o] - for s_s in model.time_season[p] + for s_s in model.time_season for s_d in model.time_of_day for s_t, s_v in model.commodity_down_stream_process[r, p, c] if s_t in model.tech_storage @@ -530,7 +530,7 @@ def annual_commodity_balance_constraint( consumed += sum( model.v_flow_out[r, p, s_s, s_d, c, s_t, s_v, s_o] / get_variable_efficiency(model, r, p, s_s, s_d, c, s_t, s_v, s_o) - for s_s in model.time_season[p] + for s_s in model.time_season for s_d in model.time_of_day for s_t, s_v in model.commodity_down_stream_process[r, p, c] if s_t not in model.tech_storage and s_t not in model.tech_annual @@ -560,7 +560,7 @@ def annual_commodity_balance_constraint( # Includes output from storage produced += sum( model.v_flow_out[r, p, s_s, s_d, s_i, s_t, s_v, c] - for s_s in model.time_season[p] + for s_s in model.time_season for s_d in model.time_of_day for s_t, s_v in model.commodity_up_stream_process[r, p, c] if s_t not in model.tech_annual @@ -577,7 +577,7 @@ def annual_commodity_balance_constraint( if c in model.commodity_flex: consumed += sum( model.v_flex[r, p, s_s, s_d, s_i, s_t, s_v, c] - for s_s in model.time_season[p] + for s_s in model.time_season for s_d in model.time_of_day for s_t, s_v in model.commodity_up_stream_process[r, p, c] if s_t not in model.tech_annual and s_t in model.tech_flex @@ -606,7 +606,7 @@ def annual_commodity_balance_constraint( / get_variable_efficiency( model, cast('Region', r + '-' + s_r), p, s_s, s_d, c, s_t, s_v, s_o ) - for s_s in model.time_season[p] + for s_s in model.time_season for s_d in model.time_of_day for s_r, s_t, s_v, s_o in model.export_regions[r, p, c] if s_t not in model.tech_annual @@ -622,7 +622,7 @@ def annual_commodity_balance_constraint( if (r, p, c) in model.import_regions: produced += sum( model.v_flow_out[cast('Region', s_r + '-' + r), p, s_s, S_d, s_i, s_t, s_v, c] - for s_s in model.time_season[p] + for s_s in model.time_season for S_d in model.time_of_day for s_r, s_t, s_v, s_i in model.import_regions[r, p, c] if s_t not in model.tech_annual @@ -767,14 +767,14 @@ def create_demands(model: TemoaModel) -> None: cross_product( model.regions, (p,), - model.time_season[p], + model.time_season, model.time_of_day, unset_demand_distributions, ) ) for r, p, s, d, dem in unset_distributions: demand_specific_distribution[r, p, s, d, dem] = value( - model.segment_fraction[p, s, d] + model.segment_fraction[s, d] ) # DSD._constructed = True # Step 5: A final "sum to 1" check for all DSD members (which now should be everything) @@ -783,7 +783,7 @@ def create_demands(model: TemoaModel) -> None: # and we need to ensure even the zeros are passed in used_rp_dems = {(r, p, dem) for r, p, dem in model.demand.sparse_iterkeys()} for r, p, dem in used_rp_dems: - expected_key_length = len(model.time_season[p]) * len(model.time_of_day) + expected_key_length = len(model.time_season) * len(model.time_of_day) keys = [ k for k in demand_specific_distribution.sparse_iterkeys() @@ -795,7 +795,7 @@ def create_demands(model: TemoaModel) -> None: # this could be very slow but only calls when there's a problem missing = { (s, d) - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day if (r, p, s, d, dem) not in keys } diff --git a/temoa/components/costs.py b/temoa/components/costs.py index a4647e64c..568abd8bb 100644 --- a/temoa/components/costs.py +++ b/temoa/components/costs.py @@ -381,7 +381,7 @@ def period_cost_rule(model: TemoaModel, p: int) -> float | Expression: if S_p == p and S_t not in model.tech_annual for S_i in model.process_inputs[r, S_p, S_t, S_v] for S_o in model.process_outputs_by_input[r, S_p, S_t, S_v, S_i] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) @@ -425,7 +425,7 @@ def period_cost_rule(model: TemoaModel, p: int) -> float | Expression: normal = [ (r, p, e, s, d, i, t, v, o) for (r, p, e, i, t, v, o) in base - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day if t not in model.tech_annual ] diff --git a/temoa/components/emissions.py b/temoa/components/emissions.py index 03e9a9c45..982afcbb4 100644 --- a/temoa/components/emissions.py +++ b/temoa/components/emissions.py @@ -58,7 +58,7 @@ def linked_tech_constraint_indices( if (r, p, t) in model.process_vintages for v in model.process_vintages[r, p, t] if model.active_activity_rptv and (r, p, t, v) in model.active_activity_rptv - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -108,7 +108,7 @@ def linked_emissions_tech_constraint( ( value(model.demand_specific_distribution[r, p, s, d, S_o]) if S_o in model.commodity_demand - else value(model.segment_fraction[p, s, d]) + else value(model.segment_fraction[s, d]) ) * model.v_flow_out_annual[r, p, S_i, t, v, S_o] * value(model.emission_activity[r, e, S_i, t, v, S_o]) @@ -136,7 +136,7 @@ def linked_emissions_tech_constraint( ( value(model.demand_specific_distribution[r, p, s, d, S_o]) if S_o in model.commodity_demand - else value(model.segment_fraction[p, s, d]) + else value(model.segment_fraction[s, d]) ) * model.v_flow_out_annual[r, p, S_i, linked_t, v, S_o] for S_i in model.process_inputs[r, p, linked_t, v] diff --git a/temoa/components/flows.py b/temoa/components/flows.py index 4b1248c7b..ed183521f 100644 --- a/temoa/components/flows.py +++ b/temoa/components/flows.py @@ -136,7 +136,7 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: for v in model.process_vintages[r, p, t] for i in model.process_inputs.get((r, p, t, v), set()) for o in model.process_outputs_by_input.get((r, p, t, v, i), set()) - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -158,7 +158,7 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: for v in model.process_vintages[r, p, t] for i in model.process_inputs.get((r, p, t, v), set()) for o in model.process_outputs_by_input.get((r, p, t, v, i), set()) - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -178,7 +178,7 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: for v in model.storage_vintages[r, p, t] for i in model.process_inputs.get((r, p, t, v), set()) for o in model.process_outputs_by_input.get((r, p, t, v, i), set()) - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -188,7 +188,7 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: for v in model.curtailment_vintages[r, p, t] for i in model.process_inputs.get((r, p, t, v), set()) for o in model.process_outputs_by_input.get((r, p, t, v, i), set()) - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -202,7 +202,7 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: (r, p, s, d, t, v) for r, p, t in model.storage_vintages for v in model.storage_vintages[r, p, t] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } diff --git a/temoa/components/limits.py b/temoa/components/limits.py index baa4b0428..d1897efb7 100644 --- a/temoa/components/limits.py +++ b/temoa/components/limits.py @@ -42,7 +42,7 @@ def limit_tech_input_split_constraint_indices( for r, p, i, t, op in model.input_split_vintages if t not in model.tech_annual for v in model.input_split_vintages[r, p, i, t, op] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } ann_indices = { @@ -92,7 +92,7 @@ def limit_tech_output_split_constraint_indices( for r, p, t, o, op in model.output_split_vintages if t not in model.tech_annual for v in model.output_split_vintages[r, p, t, o, op] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } ann_indices = { @@ -219,7 +219,7 @@ def renewable_portfolio_standard_constraint( for t in model.tech_group_members[g] for (_t, v) in model.process_reserve_periods.get((r, p), []) if _t == t - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day for S_i in model.process_inputs[r, p, t, v] for S_o in model.process_outputs_by_input[r, p, t, v, S_i] @@ -228,7 +228,7 @@ def renewable_portfolio_standard_constraint( total_inp = quicksum( model.v_flow_out[r, p, s, d, S_i, t, v, S_o] for (t, v) in model.process_reserve_periods[r, p] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day for S_i in model.process_inputs[r, p, t, v] for S_o in model.process_outputs_by_input[r, p, t, v, S_i] @@ -284,7 +284,7 @@ def limit_resource_constraint(model: TemoaModel, r: Region, t: Technology, op: s for S_v in model.process_vintages[_r, p, _t] for S_i in model.process_inputs[_r, p, _t, S_v] for S_o in model.process_outputs_by_input[_r, p, _t, S_v, S_i] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) @@ -324,7 +324,7 @@ def limit_activity_share_constraint( for S_v in model.process_vintages.get((_r, p, S_t), []) for S_i in model.process_inputs[_r, p, S_t, S_v] for S_o in model.process_outputs_by_input[_r, p, S_t, S_v, S_i] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) sub_activity += quicksum( @@ -346,7 +346,7 @@ def limit_activity_share_constraint( for S_v in model.process_vintages.get((_r, p, S_t), []) for S_i in model.process_inputs[_r, p, S_t, S_v] for S_o in model.process_outputs_by_input[_r, p, S_t, S_v, S_i] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) super_activity += quicksum( @@ -479,7 +479,7 @@ def limit_annual_capacity_factor_constraint( for _r in regions for S_v in model.process_vintages.get((_r, p, t), []) for S_i in model.process_inputs[_r, p, t, S_v] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) else: @@ -548,7 +548,7 @@ def limit_seasonal_capacity_factor_constraint( else: activity_rpst = quicksum( model.v_flow_out_annual[_r, p, S_i, t, S_v, S_o] - * model.segment_fraction_per_season[p, s] + * model.segment_fraction_per_season[s] for _r in regions for S_v in model.process_vintages[_r, p, t] for S_i in model.process_inputs[_r, p, t, S_v] @@ -558,7 +558,7 @@ def limit_seasonal_capacity_factor_constraint( possible_activity_rpst = quicksum( model.v_capacity_available_by_period_and_tech[_r, p, t] * value(model.capacity_to_activity[_r, t]) - * value(model.segment_fraction_per_season[p, s]) + * value(model.segment_fraction_per_season[s]) for _r in regions ) seasonal_cf = value(model.limit_seasonal_capacity_factor[r, p, s, t, op]) @@ -645,14 +645,14 @@ def limit_tech_input_split_average_constraint( inp = quicksum( model.v_flow_out[r, p, S_s, S_d, i, t, v, S_o] / get_variable_efficiency(model, r, p, S_s, S_d, i, t, v, S_o) - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day for S_o in model.process_outputs_by_input[r, p, t, v, i] ) total_inp = quicksum( model.v_flow_out[r, p, S_s, S_d, S_i, t, v, S_o] / get_variable_efficiency(model, r, p, S_s, S_d, S_i, t, v, S_o) - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day for S_i in model.process_inputs[r, p, t, v] for S_o in model.process_outputs_by_input[r, p, t, v, S_i] @@ -775,7 +775,7 @@ def limit_tech_output_split_average_constraint( out = quicksum( model.v_flow_out[r, p, S_s, S_d, S_i, t, v, o] for S_i in model.process_inputs_by_output[r, p, t, v, o] - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day ) @@ -783,7 +783,7 @@ def limit_tech_output_split_average_constraint( model.v_flow_out[r, p, S_s, S_d, S_i, t, v, S_o] for S_i in model.process_inputs[r, p, t, v] for S_o in model.process_outputs_by_input[r, p, t, v, S_i] - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day ) @@ -847,7 +847,7 @@ def limit_emission_constraint( if tmp_e == e and tmp_r == reg and S_t not in model.tech_annual # EmissionsActivity not indexed by p, so make sure (r,p,t,v) combos valid if (reg, p, S_t, S_v) in model.process_inputs - for S_s in model.time_season[p] + for S_s in model.time_season for S_d in model.time_of_day ) @@ -1320,7 +1320,7 @@ def limit_activity_constraint( for S_v in model.process_vintages.get((_r, p, _t), []) for S_i in model.process_inputs[_r, p, _t, S_v] for S_o in model.process_outputs_by_input[_r, p, _t, S_v, S_i] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ) activity += quicksum( diff --git a/temoa/components/operations.py b/temoa/components/operations.py index ee11f26c8..347e4099e 100644 --- a/temoa/components/operations.py +++ b/temoa/components/operations.py @@ -36,7 +36,7 @@ def baseload_diurnal_constraint_indices( (r, p, s, d, t, v) for r, p, t in model.baseload_vintages for v in model.baseload_vintages[r, p, t] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -50,7 +50,7 @@ def ramp_up_day_constraint_indices( (r, p, s, d, t, v) for r, p, t in model.ramp_up_vintages for v in model.ramp_up_vintages[r, p, t] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -64,7 +64,7 @@ def ramp_down_day_constraint_indices( (r, p, s, d, t, v) for r, p, t in model.ramp_down_vintages for v in model.ramp_down_vintages[r, p, t] - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -82,8 +82,7 @@ def ramp_up_season_constraint_indices( (r, p, s, s_next, t, v) for r, p, t in model.ramp_up_vintages for v in model.ramp_up_vintages[r, p, t] - for _p, s_seq, s in model.ordered_season_sequential - if _p == p + for s_seq, s in model.ordered_season_sequential for s_next in (model.sequential_to_season[p, model.time_next_sequential[p, s_seq]],) if s_next != model.time_next[p, s, model.time_of_day.last()][0] } @@ -102,8 +101,7 @@ def ramp_down_season_constraint_indices( (r, p, s, s_next, t, v) for r, p, t in model.ramp_down_vintages for v in model.ramp_down_vintages[r, p, t] - for _p, s_seq, s in model.ordered_season_sequential - if _p == p + for s_seq, s in model.ordered_season_sequential for s_next in (model.sequential_to_season[p, model.time_next_sequential[p, s_seq]],) if s_next != model.time_next[p, s, model.time_of_day.last()][0] } @@ -188,8 +186,8 @@ def baseload_diurnal_constraint( for S_o in model.process_outputs_by_input[r, p, t, v, S_i] ) - expr = activity_sd * value(model.segment_fraction[p, s, d_0]) == activity_sd_0 * value( - model.segment_fraction[p, s, d] + expr = activity_sd * value(model.segment_fraction[s, d_0]) == activity_sd_0 * value( + model.segment_fraction[s, d] ) return expr @@ -300,9 +298,9 @@ def ramp_up_day_constraint( s_next, d_next = model.time_next[p, s, d] # How many hours does this time slice represent - hours_adjust = value(model.segment_fraction[p, s, d]) * value(model.days_per_period) * 24 + hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 hours_adjust_next = ( - value(model.segment_fraction[p, s_next, d_next]) * value(model.days_per_period) * 24 + value(model.segment_fraction[s_next, d_next]) * value(model.days_per_period) * 24 ) hourly_activity_sd = ( @@ -328,9 +326,9 @@ def ramp_up_day_constraint( 24 / 2 * ( - value(model.segment_fraction[p, s, d]) / value(model.segment_fraction_per_season[p, s]) - + value(model.segment_fraction[p, s_next, d_next]) - / value(model.segment_fraction_per_season[p, s_next]) + value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) + + value(model.segment_fraction[s_next, d_next]) + / value(model.segment_fraction_per_season[s_next]) ) ) ramp_fraction = hours_elapsed * value(model.ramp_up_hourly[r, t]) @@ -390,9 +388,9 @@ def ramp_down_day_constraint( s_next, d_next = model.time_next[p, s, d] # How many hours does this time slice represent - hours_adjust = value(model.segment_fraction[p, s, d]) * value(model.days_per_period) * 24 + hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 hours_adjust_next = ( - value(model.segment_fraction[p, s_next, d_next]) * value(model.days_per_period) * 24 + value(model.segment_fraction[s_next, d_next]) * value(model.days_per_period) * 24 ) hourly_activity_sd = ( @@ -418,9 +416,9 @@ def ramp_down_day_constraint( 24 / 2 * ( - value(model.segment_fraction[p, s, d]) / value(model.segment_fraction_per_season[p, s]) - + value(model.segment_fraction[p, s_next, d_next]) - / value(model.segment_fraction_per_season[p, s_next]) + value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) + + value(model.segment_fraction[s_next, d_next]) + / value(model.segment_fraction_per_season[s_next]) ) ) ramp_fraction = hours_elapsed * value(model.ramp_down_hourly[r, t]) @@ -465,9 +463,9 @@ def ramp_up_season_constraint( d_next = model.time_of_day.first() # How many hours does this time slice represent - hours_adjust = value(model.segment_fraction[p, s, d]) * value(model.days_per_period) * 24 + hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 hours_adjust_next = ( - value(model.segment_fraction[p, s_next, d_next]) * value(model.days_per_period) * 24 + value(model.segment_fraction[s_next, d_next]) * value(model.days_per_period) * 24 ) hourly_activity_sd = ( @@ -493,9 +491,9 @@ def ramp_up_season_constraint( 24 / 2 * ( - value(model.segment_fraction[p, s, d]) / value(model.segment_fraction_per_season[p, s]) - + value(model.segment_fraction[p, s_next, d_next]) - / value(model.segment_fraction_per_season[p, s_next]) + value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) + + value(model.segment_fraction[s_next, d_next]) + / value(model.segment_fraction_per_season[s_next]) ) ) ramp_fraction = hours_elapsed * value(model.ramp_up_hourly[r, t]) @@ -540,9 +538,9 @@ def ramp_down_season_constraint( d_next = model.time_of_day.first() # How many hours does this time slice represent - hours_adjust = value(model.segment_fraction[p, s, d]) * value(model.days_per_period) * 24 + hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 hours_adjust_next = ( - value(model.segment_fraction[p, s_next, d_next]) * value(model.days_per_period) * 24 + value(model.segment_fraction[s_next, d_next]) * value(model.days_per_period) * 24 ) hourly_activity_sd = ( @@ -568,9 +566,9 @@ def ramp_down_season_constraint( 24 / 2 * ( - value(model.segment_fraction[p, s, d]) / value(model.segment_fraction_per_season[p, s]) - + value(model.segment_fraction[p, s_next, d_next]) - / value(model.segment_fraction_per_season[p, s_next]) + value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) + + value(model.segment_fraction[s_next, d_next]) + / value(model.segment_fraction_per_season[s_next]) ) ) ramp_fraction = hours_elapsed * value(model.ramp_down_hourly[r, t]) diff --git a/temoa/components/reserves.py b/temoa/components/reserves.py index bc82625b7..fedcf070d 100644 --- a/temoa/components/reserves.py +++ b/temoa/components/reserves.py @@ -35,7 +35,7 @@ def reserve_margin_indices(model: TemoaModel) -> set[tuple[Region, Period, Seaso for r in model.planning_reserve_margin.sparse_iterkeys() for p in model.time_optimize if (r, p) in model.process_reserve_periods - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day } @@ -102,7 +102,7 @@ def reserve_margin_dynamic( * value(model.reserve_capacity_derate[r, p, s, t, v]) * value(model.capacity_factor_process[r, p, s, d, t, v]) * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r, p] if t not in model.tech_uncap and t not in model.tech_storage ) @@ -155,7 +155,7 @@ def reserve_margin_dynamic( * value(model.reserve_capacity_derate[r, p, s, t, v]) * value(model.capacity_factor_process[r, p, s, d, t, v]) * value(model.capacity_to_activity[r1r2, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r1r2, p] ) @@ -207,7 +207,7 @@ def reserve_margin_static( value(model.capacity_credit[r, p, t, v]) * model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r, p] if t not in model.tech_uncap ) @@ -240,7 +240,7 @@ def reserve_margin_static( value(model.capacity_credit[r1r2, p, t, v]) * model.v_capacity[r1r2, p, t, v] * value(model.capacity_to_activity[r1r2, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r1r2, p] ) @@ -286,7 +286,7 @@ def reserve_margin_constraint( ( value(model.demand_specific_distribution[r, p, s, d, S_o]) if S_o in model.commodity_demand - else value(model.segment_fraction[p, s, d]) + else value(model.segment_fraction[s, d]) ) * model.v_flow_out_annual[r, p, S_i, t, S_v, S_o] for (t, S_v) in model.process_reserve_periods[r, p] diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 6171db723..287e054d8 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -191,11 +191,11 @@ def seasonal_storage_energy_constraint( # Flows and StorageLevel are normalised to the number of days in the non-sequential season, # so must # be adjusted to the number of days in the sequential season - days_adjust = value(model.time_season_sequential[p, s_seq, s]) / ( - value(model.segment_fraction_per_season[p, s]) * value(model.days_per_period) + days_adjust = value(model.time_season_sequential[s_seq, s]) / ( + value(model.segment_fraction_per_season[s]) * value(model.days_per_period) ) - days_adjust_next = value(model.time_season_sequential[p, s_seq_next, s_next]) / ( - value(model.segment_fraction_per_season[p, s_next]) * value(model.days_per_period) + days_adjust_next = value(model.time_season_sequential[s_seq_next, s_next]) / ( + value(model.segment_fraction_per_season[s_next]) * value(model.days_per_period) ) stored_energy = (charge - discharge) * days_adjust @@ -264,7 +264,7 @@ def storage_energy_upper_bound_constraint( model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) * (value(model.storage_duration[r, t]) / (24 * value(model.days_per_period))) - * value(model.segment_fraction_per_season[p, s]) + * value(model.segment_fraction_per_season[s]) * model.days_per_period # adjust for days in season ) @@ -339,8 +339,8 @@ def seasonal_storage_energy_upper_bound_constraint( # Flows and StorageLevel are normalised to the number of days in the non-sequential season, # so must # be adjusted to the number of days in the sequential season - days_adjust = value(model.time_season_sequential[p, s_seq, s]) / ( - value(model.segment_fraction_per_season[p, s]) * value(model.days_per_period) + days_adjust = value(model.time_season_sequential[s_seq, s]) / ( + value(model.segment_fraction_per_season[s]) * value(model.days_per_period) ) # v_storage_level tracks the running cumulative delta in the non-sequential season, @@ -384,7 +384,7 @@ def storage_charge_rate_constraint( max_charge = ( model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) ) # Energy charge cannot exceed the power capacity of the storage unit @@ -422,7 +422,7 @@ def storage_discharge_rate_constraint( max_discharge = ( model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) ) # Energy discharge cannot exceed the capacity of the storage unit @@ -469,7 +469,7 @@ def storage_throughput_constraint( max_throughput = ( model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[p, s, d]) + * value(model.segment_fraction[s, d]) ) expr = throughput <= max_throughput return expr @@ -525,13 +525,13 @@ def limit_storage_fraction_constraint( # adjust the storage level to the individual-day level energy_level = model.v_storage_level[r, p, s, d, t, v] / ( - value(model.segment_fraction_per_season[p, s]) * value(model.days_per_period) + value(model.segment_fraction_per_season[s]) * value(model.days_per_period) ) if model.is_seasonal_storage[t]: # seasonal storage upper energy limit is absolute energy_level = model.v_seasonal_storage_level[r, p, s_seq, t, v] + energy_level * value( - model.time_season_sequential[p, s_seq, s] + model.time_season_sequential[s_seq, s] ) expr = operator_expression(energy_level, Operator(op), energy_limit) diff --git a/temoa/components/technology.py b/temoa/components/technology.py index ed866f764..735cad03d 100644 --- a/temoa/components/technology.py +++ b/temoa/components/technology.py @@ -419,7 +419,7 @@ def check_efficiency_variable(model: TemoaModel) -> None: # Check if all possible values have been set as variable # log a warning if some are missing (allowed but maybe accidental) - num_seg = len(model.time_season[p]) * len(model.time_of_day) + num_seg = len(model.time_season) * len(model.time_of_day) for (r, p, i, t, v, o), count in count_rpitvo.items(): if count > 0: model.is_efficiency_variable[r, p, i, t, v, o] = True diff --git a/temoa/components/time.py b/temoa/components/time.py index 6df7e5239..d263fa6e1 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -90,53 +90,49 @@ def validate_time(model: TemoaModel) -> None: def validate_segment_fraction(model: TemoaModel) -> None: """Ensure that the segment fractions adds up to 1""" - for p in model.time_optimize: - expected_keys: set[tuple[int, str, str]] = { - (p, s, d) for s in model.time_season[p] for d in model.time_of_day - } - keys: set[tuple[int, str, str]] = { - (_p, s, d) for _p, s, d in model.segment_fraction.sparse_iterkeys() if _p == p - } - - if expected_keys != keys: - extra: set[tuple[int, str, str]] = keys.difference(expected_keys) - missing: set[tuple[int, str, str]] = expected_keys.difference(keys) - msg: str = ( - f'time_segment_fraction elements for period {p} do not match time_season and ' - 'time_of_day.' - f'\n\nIndices missing from time_segment_fraction:\n{missing}' - f'\n\nIndices in time_segment_fraction missing from time_season/time_of_day:\n' - f'{extra}' - ) - logger.error(msg) - raise ValueError(msg) + expected_keys: set[tuple[str, str]] = { + (s, d) for s in model.time_season for d in model.time_of_day + } + keys: set[tuple[str, str]] = set(model.segment_fraction.sparse_iterkeys()) - total: float = sum(value(model.segment_fraction[k]) for k in keys) + if expected_keys != keys: + extra: set[tuple[str, str]] = keys.difference(expected_keys) + missing: set[tuple[str, str]] = expected_keys.difference(keys) + msg: str = ( + 'time_segment_fraction elements do not match time_season and time_of_day.' + f'\n\nIndices missing from time_segment_fraction:\n{missing}' + f'\n\nIndices in time_segment_fraction missing from time_season/time_of_day:\n' + f'{extra}' + ) + logger.error(msg) + raise ValueError(msg) - if abs(float(total) - 1.0) > 0.001: - # We can't explicitly test for "!= 1.0" because of incremental rounding - # errors associated with the specification of segment_fraction by time slice, - # but we check to make sure it is within the specified tolerance. + total: float = sum(value(model.segment_fraction[k]) for k in keys) - def get_str_padding(obj: object) -> int: - return len(str(obj)) + if abs(float(total) - 1.0) > 0.001: + # We can't explicitly test for "!= 1.0" because of incremental rounding + # errors associated with the specification of segment_fraction by time slice, + # but we check to make sure it is within the specified tolerance. - key_padding: int = max(map(get_str_padding, keys)) + def get_str_padding(obj: object) -> int: + return len(str(obj)) - # Works out to something like "%-25s = %s" + key_padding: int = max(map(get_str_padding, keys)) - items_list: list[tuple[tuple[object, object, object], object]] = sorted( - [(k, model.segment_fraction[k]) for k in keys] - ) - items: str = '\n '.join(f'{str(k):<{key_padding}} = {v}' for k, v in items_list) + # Works out to something like "%-25s = %s" - msg = ( - f'The values of time_segment_fraction do not sum to 1 for period {p}. ' - 'Each item in segment_fraction represents a fraction of a year, so they must ' - f'total to 1. Current values:\n {items}\n\tsum = {total}' - ) - logger.error(msg) - raise Exception(msg) + items_list: list[tuple[tuple[object, object], object]] = sorted( + [(k, model.segment_fraction[k]) for k in keys] + ) + items: str = '\n '.join(f'{str(k):<{key_padding}} = {v}' for k, v in items_list) + + msg = ( + 'The values of time_segment_fraction do not sum to 1. ' + 'Each item in segment_fraction represents a fraction of a year, so they must ' + f'total to 1. Current values:\n {items}\n\tsum = {total}' + ) + logger.error(msg) + raise Exception(msg) def validate_time_manual(model: TemoaModel) -> None: @@ -149,25 +145,23 @@ def validate_time_manual(model: TemoaModel) -> None: if model.time_sequencing.first() != 'manual': return - segment_fraction_psd: set[tuple[int, str, str]] = set(model.segment_fraction.sparse_iterkeys()) - time_manual_psd: set[tuple[int, str, str]] = { - (p, s, d) for p, s, d, s_next, d_next in model.time_manual + segment_fraction_sd: set[tuple[str, str]] = set(model.segment_fraction.sparse_iterkeys()) + time_manual_sd: set[tuple[str, str]] = { + (s, d) for p, s, d, s_next, d_next in model.time_manual } - time_manual_psd_next: set[tuple[int, str, str]] = { - (p, s_next, d_next) for p, s, d, s_next, d_next in model.time_manual + time_manual_sd_next: set[tuple[str, str]] = { + (s_next, d_next) for p, s, d, s_next, d_next in model.time_manual } - missing_psd: set[tuple[int, str, str]] = segment_fraction_psd.difference(time_manual_psd) - missing_psd_next: set[tuple[int, str, str]] = segment_fraction_psd.difference( - time_manual_psd_next - ) - if missing_psd or missing_psd_next: + missing_sd: set[tuple[str, str]] = segment_fraction_sd.difference(time_manual_sd) + missing_sd_next: set[tuple[str, str]] = segment_fraction_sd.difference(time_manual_sd_next) + if missing_sd or missing_sd_next: msg: str = ( 'Failed to build state sequence. ' f'\nThese states from time_segment_fraction were not given a next state:\n' - f'{missing_psd}\n' + f'{missing_sd}\n' f'\nThese states from time_segment_fraction do not follow any state:\n' - f'{missing_psd_next}' + f'{missing_sd_next}' ) logger.error(msg) raise ValueError(msg) @@ -193,12 +187,12 @@ def init_set_vintage_optimize(model: TemoaModel) -> list[int]: return sorted(model.time_optimize) -def segment_fraction_per_season_rule(model: TemoaModel, p: Period, s: Season) -> float: +def segment_fraction_per_season_rule(model: TemoaModel, s: Season) -> float: """Rule to calculate the total fraction of a period represented by a season.""" return sum( - value(model.segment_fraction[p, s, d]) + value(model.segment_fraction[s, d]) for d in model.time_of_day - if (p, s, d) in model.segment_fraction + if (s, d) in model.segment_fraction ) @@ -220,15 +214,15 @@ def loop_period_next_timeslice( # Final time slice of final season (end of period) # Loop state back to initial state of first season # Loop the period - if s == model.time_season[p].last() and d == model.time_of_day.last(): - s_next: Season = model.time_season[p].first() + if s == model.time_season.last() and d == model.time_of_day.last(): + s_next: Season = model.time_season.first() d_next: TimeOfDay = model.time_of_day.first() # Last time slice of any season that is NOT the last season # Carry state to initial state of next season # Carry state between seasons elif d == model.time_of_day.last(): - s_next = model.time_season[p].next(s) + s_next = model.time_season.next(s) d_next = model.time_of_day.first() # Any other time slice @@ -275,17 +269,17 @@ def create_time_sequence(model: TemoaModel) -> None: case 'consecutive_days': msg: str = 'Running a consecutive days database.' for p in model.time_optimize: - for s, d in model.time_season[p] * model.time_of_day: + for s, d in model.time_season * model.time_of_day: model.time_next[p, s, d] = loop_period_next_timeslice(model, p, s, d) case 'seasonal_timeslices': msg = 'Running a seasonal time slice database.' for p in model.time_optimize: - for s, d in model.time_season[p] * model.time_of_day: + for s, d in model.time_season * model.time_of_day: model.time_next[p, s, d] = loop_season_next_timeslice(model, p, s, d) case 'representative_periods': msg = 'Running a representative periods database.' for p in model.time_optimize: - for s, d in model.time_season[p] * model.time_of_day: + for s, d in model.time_season * model.time_of_day: model.time_next[p, s, d] = loop_season_next_timeslice(model, p, s, d) case 'manual': # Hidden feature. Define the sequence directly in the time_manual table @@ -306,11 +300,9 @@ def create_time_sequence(model: TemoaModel) -> None: logger.debug('Creating superimposed sequential seasons.') - # Superimposed sequential seasons + # Superimposed sequential seasons (global, applied to all periods) + seasons: list[tuple[Season, Season]] = list(model.ordered_season_sequential) for p in model.time_optimize: - seasons: list[tuple[Season, Season]] = [ - (s_seq, s) for _p, s_seq, s in model.ordered_season_sequential if _p == p - ] for i, (s_seq, s) in enumerate(seasons): model.sequential_to_season[p, s_seq] = s if (s_seq, s) == seasons[-1]: @@ -338,14 +330,12 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: 'No data in time_season_sequential. By default, assuming sequential seasons ' 'match time_season and time_segment_fraction.' ) - for s in model.time_season_all: + for s in model.time_season: model.time_season_to_sequential.add(s) - for p in model.time_season: - for s in model.time_season[p]: - model.ordered_season_sequential.add((p, s, s)) - model.time_season_sequential[p, s, s] = value( - model.segment_fraction_per_season[p, s] - ) * value(model.days_per_period) + model.ordered_season_sequential.add((s, s)) + model.time_season_sequential[s, s] = value( + model.segment_fraction_per_season[s] + ) * value(model.days_per_period) else: msg = ( @@ -359,10 +349,10 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: logger.error(msg) raise ValueError(msg) - sequential: dict[tuple[int, str], float] = {} + sequential: dict[str, float] = {} prev_n: float = 0 - for p, s_seq, s in model.time_season_sequential.sparse_iterkeys(): - num_days: float = value(model.time_season_sequential[p, s_seq, s]) + for s_seq, s in model.time_season_sequential.sparse_iterkeys(): + num_days: float = value(model.time_season_sequential[s_seq, s]) if ( model.time_sequencing.first() == 'consecutive_days' and prev_n @@ -371,7 +361,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: msg = ( 'time_sequencing set to consecutive_days but two consecutive seasons do not ' 'represent the same number of days. This discontinuity will lead to bad model ' - f'behaviour: {p, s}, days: {num_days}. ' + f'behaviour: {s}, days: {num_days}. ' f'Previous number of days: {prev_n}. Check the config file for more information.' ) logger.error(msg) @@ -379,54 +369,44 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: prev_n = num_days # for validating next in sequence # Regardless of their order, make sure the total number of days adds up - if (p, s) not in sequential: - sequential[p, s] = 0 - sequential[p, s] += num_days - - # Check that time_season_sequential num_days total to number of days in each period - count_total: dict[ - int, float - ] = {} # {p: n} total days per period according to time_season_sequential - for p in model.time_optimize: - count_total[p] = sum(sequential[p, s] for _p, s in sequential if _p == p) - if abs(count_total[p] - value(model.days_per_period)) >= 0.001: - logger.warning( - 'Sum of num_days in time_season_sequential (%s) ' - 'for period %s does not sum to days_per_period (%s) ' - 'from the MetaData table.', - count_total[p], - p, - value(model.days_per_period), - ) + sequential[s] = sequential.get(s, 0) + num_days + + # Check that time_season_sequential num_days total to number of days per period + count_total: float = sum(sequential.values()) + if abs(count_total - value(model.days_per_period)) >= 0.001: + logger.warning( + 'Sum of num_days in time_season_sequential (%s) ' + 'does not sum to days_per_period (%s) ' + 'from the MetaData table.', + count_total, + value(model.days_per_period), + ) - # Check that seasons using in storage seasons are actual seasons - for p, s in sequential: - if (p, s) not in model.segment_fraction_per_season: + # Check that seasons used in storage seasons are actual seasons + for s in sequential: + if s not in model.segment_fraction_per_season: msg = ( - f'Period-season index {(p, s)} that does not exist in ' - 'time_segment_fraction referenced in time_season_sequential .' + f'Season {s!r} that does not exist in ' + 'time_segment_fraction referenced in time_season_sequential.' ) logger.error(msg) raise ValueError(msg) - for p, s in model.segment_fraction_per_season.sparse_iterkeys(): - if s not in model.time_season[p]: - continue - + for s in model.segment_fraction_per_season.sparse_iterkeys(): # Check that all seasons are used in sequential seasons - if (p, s) not in sequential: - msg = f'Period-season index {(p, s)} absent from time_season_sequential' + if s not in sequential: + msg = f'Season {s!r} absent from time_season_sequential' logger.warning(msg) - # Check that the two tables agree on the total seasonal composition of each period - segment_fraction = value(model.segment_fraction_per_season[p, s]) - segment_fraction_seq = sequential[p, s] / count_total[p] + # Check that the two tables agree on the total seasonal composition + segment_fraction = value(model.segment_fraction_per_season[s]) + segment_fraction_seq = sequential[s] / count_total if abs(segment_fraction - segment_fraction_seq) >= 0.001: msg = ( - 'Discrepancy of total period-season composition between ' - 'time_segment_fraction and time_season_sequential. Total fraction of each ' - 'period assigned to each season should match: ' - f'time_segment_fraction: {(p, s, value(model.segment_fraction_per_season[p, s]))}' - f', time_season_sequential: {(p, s, segment_fraction_seq)}' + 'Discrepancy of total seasonal composition between ' + 'time_segment_fraction and time_season_sequential. Total fraction ' + 'assigned to each season should match: ' + f'time_segment_fraction: {(s, value(model.segment_fraction_per_season[s]))}' + f', time_season_sequential: {(s, segment_fraction_seq)}' ) logger.warning(msg) diff --git a/temoa/core/model.py b/temoa/core/model.py index 2a44e0fa9..dbc8481ce 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -216,16 +216,15 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.validate_time = BuildAction(rule=time.validate_time) # Define the model time slices - self.time_season_all = Set(ordered=True, validate=no_slash_or_pipe) + self.time_season = Set(ordered=True, validate=no_slash_or_pipe) self.time_season_to_sequential = Set(ordered=True, validate=no_slash_or_pipe) - self.time_season = Set(self.time_optimize, within=self.time_season_all, ordered=True) self.time_of_day = Set(ordered=True, validate=no_slash_or_pipe) # This is just to get the TimeStorageSeason table sequentially. # There must be a better way but this works for now self.ordered_season_sequential = Set( - dimen=3, - within=self.time_optimize * self.time_season_to_sequential * self.time_season_all, + dimen=2, + within=self.time_season_to_sequential * self.time_season, ordered=True, ) @@ -331,7 +330,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Define time-related parameters self.period_length = Param(self.time_optimize, initialize=time.param_period_length) - self.segment_fraction = Param(self.time_optimize, self.time_season_all, self.time_of_day) + self.segment_fraction = Param(self.time_season, self.time_of_day) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) self.time_sequencing = Set() # How do states carry between time segments? self.time_manual = Set( @@ -349,7 +348,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.demand_specific_distribution = Param( self.regions, self.time_optimize, - self.time_season_all, + self.time_season, self.time_of_day, self.commodity_demand, mutable=True, @@ -407,7 +406,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.efficiency_variable = Param( self.regional_indices, self.time_optimize, - self.time_season_all, + self.time_season, self.time_of_day, self.commodity_physical, self.tech_all, @@ -498,12 +497,11 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Set up representation of time self.days_per_period = Param() self.segment_fraction_per_season = Param( - self.time_optimize, - self.time_season_all, + self.time_season, initialize=time.segment_fraction_per_season_rule, ) self.time_season_sequential = Param( - self.time_optimize, self.time_season_to_sequential, self.time_season_all, mutable=True + self.time_season_to_sequential, self.time_season, mutable=True ) self.validate_season_sequential = BuildAction(rule=time.create_time_season_to_sequential) self.create_time_sequence = BuildAction(rule=time.create_time_sequence) @@ -524,7 +522,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.capacity_factor_process = Param( self.regional_indices, self.time_optimize, - self.time_season_all, + self.time_season, self.time_of_day, self.tech_with_capacity, self.vintage_all, @@ -605,7 +603,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.limit_seasonal_capacity_factor_constraint_rpst = Set( within=self.regional_global_indices * self.time_optimize - * self.time_season_all + * self.time_season * self.tech_all * self.operator ) @@ -713,7 +711,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.reserve_capacity_derate = Param( self.regional_indices, self.time_optimize, - self.time_season_all, + self.time_season, self.tech_reserve, self.vintage_all, default=1, diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index f4b8f31a0..6b2d65fe0 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -240,7 +240,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.time_season, table='time_season', - columns=['period', 'season'], + columns=['season'], custom_loader_name='_load_time_season', is_period_filtered=False, # Custom loader handles myopic filtering is_table_required=False, @@ -248,15 +248,17 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.time_season_sequential, table='time_season_sequential', - columns=['period', 'seas_seq', 'season', 'num_days'], + columns=['seas_seq', 'season', 'num_days'], custom_loader_name='_load_time_season_sequential', + is_period_filtered=False, is_table_required=False, ), LoadItem( component=model.segment_fraction, table='time_segment_fraction', - columns=['period', 'season', 'tod', 'segment_fraction'], + columns=['season', 'tod', 'segment_fraction'], custom_loader_name='_load_segment_fraction', + is_period_filtered=False, is_table_required=False, ), # ========================================================================= diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 6492d78bd..2f3813ce5 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -546,35 +546,15 @@ def _load_time_season( filtered_data: Sequence[tuple[object, ...]], ) -> None: """ - Loads time_season_all (simple set of all seasons) and time_season - (indexed set mapping periods to seasons), with a dynamic fallback - if the table is missing. + Loads time_season as a flat ordered set of season names. """ model = TemoaModel() - mi = self.myopic_index - time_optimize = cast('list[int]', data.get('time_optimize', [])) - - rows_to_load: list[tuple[object, ...]] = [] - if not raw_data: + if not filtered_data: logger.warning('No time_season table found. Loading a single filler season "S".') - rows_to_load = [(p, 'S') for p in time_optimize] - elif mi: - valid_periods = set(time_optimize) - rows_to_load = [row for row in raw_data if row[0] in valid_periods] + seasons_to_load: list[tuple[object, ...]] = [('S',)] else: - rows_to_load = list(raw_data) - - if not rows_to_load: - data.setdefault(model.time_season_all.name, []) - return - - unique_seasons = sorted({(row[1],) for row in rows_to_load}) - self._load_component_data(data, model.time_season_all, unique_seasons) - - for period, season in rows_to_load: - store = data.get(model.time_season.name, defaultdict(list)) - store[period].append(season) # type: ignore[index] - data[model.time_season.name] = store + seasons_to_load = list(filtered_data) + self._load_component_data(data, model.time_season, seasons_to_load) def _load_time_season_sequential( self, @@ -588,9 +568,9 @@ def _load_time_season_sequential( model = TemoaModel() self._load_component_data(data, model.time_season_sequential, filtered_data) if filtered_data: - ordered_data = [row[0:3] for row in filtered_data] + ordered_data = [row[0:2] for row in filtered_data] # (seas_seq, season) self._load_component_data(data, model.ordered_season_sequential, ordered_data) - seq_data = sorted({(row[1],) for row in filtered_data}) + seq_data = sorted({(row[0],) for row in filtered_data}) self._load_component_data(data, model.time_season_to_sequential, seq_data) def _load_segment_fraction( @@ -607,8 +587,7 @@ def _load_segment_fraction( logger.warning( 'No segment_fraction table found. Generating default segment_fraction values.' ) - time_optimize = data.get('time_optimize', []) - fallback = [(p, 'S', 'D', 1.0) for p in time_optimize] # type: ignore[attr-defined] + fallback: list[tuple[object, ...]] = [('S', 'D', 1.0)] self._load_component_data(data, model.segment_fraction, fallback) # --- Capacity and Cost Components --- diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 5cf0581b4..3494da570 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -885,15 +885,13 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate ); CREATE TABLE IF NOT EXISTS time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS storage_duration @@ -1046,22 +1044,20 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) + PRIMARY KEY (sequence, season) ); CREATE TABLE IF NOT EXISTS time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); diff --git a/temoa/extensions/single_vector_mga/sv_mga_sequencer.py b/temoa/extensions/single_vector_mga/sv_mga_sequencer.py index 1ca5ee123..9f06570e2 100644 --- a/temoa/extensions/single_vector_mga/sv_mga_sequencer.py +++ b/temoa/extensions/single_vector_mga/sv_mga_sequencer.py @@ -181,7 +181,7 @@ def flow_idxs_from_eac_idx(model: TemoaModel, reitvo: tuple) -> tuple[list[tuple psd_set = [ (p, s, d) for p in model.time_optimize - for s in model.time_season[p] + for s in model.time_season for d in model.time_of_day ] flow_idxs = [(r, *psd, i, t, v, o) for psd in psd_set] diff --git a/temoa/model_checking/validators.py b/temoa/model_checking/validators.py index d94406dd4..af3b95ea1 100644 --- a/temoa/model_checking/validators.py +++ b/temoa/model_checking/validators.py @@ -298,7 +298,7 @@ def validate_capacity_factor_process( ( r in model.regions, p in model.time_optimize, - s in model.time_season[p], + s in model.time_season, d in model.time_of_day, t in model.tech_with_capacity, v in model.vintage_all, diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 0394b5bbb..7b499daa6 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1536,40 +1536,22 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, season TEXT REFERENCES season_label(season), notes TEXT, - PRIMARY KEY (period, sequence, season) -); -INSERT INTO "time_season" VALUES(1990,1,'inter',NULL); -INSERT INTO "time_season" VALUES(1990,2,'summer',NULL); -INSERT INTO "time_season" VALUES(1990,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2000,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2000,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2000,3,'winter',NULL); -INSERT INTO "time_season" VALUES(2010,1,'inter',NULL); -INSERT INTO "time_season" VALUES(2010,2,'summer',NULL); -INSERT INTO "time_season" VALUES(2010,3,'winter',NULL); -CREATE TABLE time_season_all -( - period INTEGER - REFERENCES time_period (period), - sequence INTEGER, - season TEXT - REFERENCES season_label (season), - notes TEXT, - PRIMARY KEY (period, sequence, season) + PRIMARY KEY (sequence, season) ); +INSERT INTO "time_season" VALUES(0,'inter',NULL); +INSERT INTO "time_season" VALUES(1,'summer',NULL); +INSERT INTO "time_season" VALUES(2,'winter',NULL); CREATE TABLE time_season_sequential ( - period INTEGER REFERENCES time_period (period), sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES season_label(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), + PRIMARY KEY (sequence, seas_seq, season), CHECK (num_days > 0) ); CREATE TABLE time_season_to_sequential @@ -1587,34 +1569,20 @@ CREATE TABLE time_season_to_sequential ); CREATE TABLE time_segment_fraction ( - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, notes TEXT, - PRIMARY KEY (period, season, tod), + PRIMARY KEY (season, tod), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(1990,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2000,'winter','night',0.1667,'# W-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','day',0.1667,'# I-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'inter','night',0.0833,'# I-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','day',0.1667,'# S-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'summer','night',0.0833,'# S-N'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','day',0.3333,'# W-D'); -INSERT INTO "time_segment_fraction" VALUES(2010,'winter','night',0.1667,'# W-N'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); +INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); +INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); +INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/temoa/utilities/unit_cost_explorer.py b/temoa/utilities/unit_cost_explorer.py index 89cbabcb4..be9d0a336 100644 --- a/temoa/utilities/unit_cost_explorer.py +++ b/temoa/utilities/unit_cost_explorer.py @@ -95,8 +95,7 @@ print('building storage level constraint...') # More SETS -model.time_season_all.construct(['winter', 'summer']) -model.time_season.construct(data={2020: {'winter', 'summer'}, 2025: {'winter', 'summer'}}) +model.time_season.construct(['winter', 'summer']) model.days_per_period.construct(data={None: 365}) tod_slices = 2 model.time_of_day.construct(data=range(1, tod_slices + 1)) @@ -119,10 +118,9 @@ seasonal_fractions = {'winter': 0.4, 'summer': 0.6} model.segment_fraction.construct( data={ - (p, s, d): seasonal_fractions[s] / tod_slices + (s, d): seasonal_fractions[s] / tod_slices for d in model.time_of_day - for p in model.time_optimize - for s in model.time_season[p] + for s in model.time_season } ) # QA the total @@ -140,7 +138,7 @@ # cross-check the multiplier... mulitplier = ( storage_dur - * model.segment_fraction_per_season[2020, 'winter'] + * model.segment_fraction_per_season['winter'] * model.days_per_period * c2a * c diff --git a/tests/test_exchange_cost_ledger.py b/tests/test_exchange_cost_ledger.py index 1bee47806..8caa1a5ff 100644 --- a/tests/test_exchange_cost_ledger.py +++ b/tests/test_exchange_cost_ledger.py @@ -19,7 +19,7 @@ # these are the necessary Temoa elements to make the ledger work data = { - 'time_season': {2000: [1]}, + 'time_season': [1], 'time_of_day': {1}, 'tech_annual': set(), 'lifetime_process': {('A-B', 't1', 2000): 30, ('B-A', 't1', 2000): 30}, diff --git a/tests/test_storage.py b/tests/test_storage.py index 7704e3353..b49fef3bf 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -41,7 +41,7 @@ def test_storage_fraction(system_test_run: tuple[str, Any, TemoaModel, Any]) -> * model.v_capacity[r, p, t, v].value # type: ignore [attr-defined] # I can't figure out how to get mypy to see value through the pyomo stubs * model.capacity_to_activity[r, t] * (model.storage_duration[r, t] / 8760) - * model.segment_fraction_per_season[p, s] + * model.segment_fraction_per_season[s] * model.days_per_period * model.process_life_frac[r, p, t, v] ) diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index bf57681e4..1f37dd211 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -50,5 +50,5 @@ REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2001,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2000,0,'S1',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'S1','D1',1.0,NULL); +REPLACE INTO "time_season" VALUES(0,'S1',NULL); +REPLACE INTO "time_segment_fraction" VALUES('S1', 'D1', 1.0, NULL); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 9210d4709..b66d1a0b3 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -95,9 +95,6 @@ REPLACE INTO "time_period" VALUES(3,2005,'f'); REPLACE INTO "time_period" VALUES(4,2010,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2000,1,'S1',NULL); -REPLACE INTO "time_season" VALUES(2005,1,'S1',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'S1','TOD1',0.5,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'S1','TOD2',0.5,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2005,'S1','TOD1',0.5,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2005,'S1','TOD2',0.5,NULL); +REPLACE INTO "time_season" VALUES(1,'S1',NULL); +REPLACE INTO "time_segment_fraction" VALUES('S1', 'TOD1', 0.5, NULL); +REPLACE INTO "time_segment_fraction" VALUES('S1', 'TOD2', 0.5, NULL); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index 3401ab8a8..79ced1aaf 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -441,63 +441,31 @@ REPLACE INTO "time_period" VALUES(4,2020,'f'); REPLACE INTO "time_period" VALUES(5,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2000,1,'summer',NULL); -REPLACE INTO "time_season" VALUES(2000,2,'autumn',NULL); -REPLACE INTO "time_season" VALUES(2000,3,'winter',NULL); -REPLACE INTO "time_season" VALUES(2000,4,'spring',NULL); -REPLACE INTO "time_season" VALUES(2010,5,'summer',NULL); -REPLACE INTO "time_season" VALUES(2010,6,'autumn',NULL); -REPLACE INTO "time_season" VALUES(2010,7,'winter',NULL); -REPLACE INTO "time_season" VALUES(2010,8,'spring',NULL); -REPLACE INTO "time_season" VALUES(2020,9,'summer',NULL); -REPLACE INTO "time_season" VALUES(2020,10,'autumn',NULL); -REPLACE INTO "time_season" VALUES(2020,11,'winter',NULL); -REPLACE INTO "time_season" VALUES(2020,12,'spring',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'autumn','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'spring','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'autumn','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'spring','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'autumn','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'spring','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'autumn','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'spring','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'autumn','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'spring','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'autumn','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'spring','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'autumn','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'spring','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'autumn','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2010,'spring','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'autumn','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','morning',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'autumn','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','afternoon',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'autumn','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','evening',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'autumn','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','overnight',0.0625,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','overnight',0.0625,NULL); +REPLACE INTO "time_season" VALUES(1,'summer',NULL); +REPLACE INTO "time_season" VALUES(2,'autumn',NULL); +REPLACE INTO "time_season" VALUES(3,'winter',NULL); +REPLACE INTO "time_season" VALUES(4,'spring',NULL); +REPLACE INTO "time_season" VALUES(5,'summer',NULL); +REPLACE INTO "time_season" VALUES(6,'autumn',NULL); +REPLACE INTO "time_season" VALUES(7,'winter',NULL); +REPLACE INTO "time_season" VALUES(8,'spring',NULL); +REPLACE INTO "time_season" VALUES(9,'summer',NULL); +REPLACE INTO "time_season" VALUES(10,'autumn',NULL); +REPLACE INTO "time_season" VALUES(11,'winter',NULL); +REPLACE INTO "time_season" VALUES(12,'spring',NULL); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'morning', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('autumn', 'morning', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'morning', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'morning', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'afternoon', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('autumn', 'afternoon', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'afternoon', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'afternoon', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'evening', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('autumn', 'evening', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'evening', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'evening', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'overnight', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('autumn', 'overnight', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'overnight', 0.0625, NULL); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'overnight', 0.0625, NULL); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 38eac086a..33f405faa 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -189,9 +189,9 @@ REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2025,1,'s1',NULL); -REPLACE INTO "time_season" VALUES(2025,2,'s2',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d1',0.25,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d2',0.25,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d1',0.25,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d2',0.25,NULL); +REPLACE INTO "time_season" VALUES(1,'s1',NULL); +REPLACE INTO "time_season" VALUES(2,'s2',NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd1', 0.25, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd2', 0.25, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd1', 0.25, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd2', 0.25, NULL); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index f22dc32ae..efe99dea9 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -84,27 +84,27 @@ REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2000,0,'charge',NULL); -REPLACE INTO "time_season" VALUES(2000,1,'discharge',NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,1,'summer','charge',152.5,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,2,'sept_w1','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,3,'sept_w2','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,4,'sept_w3','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,5,'sept_w4','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,6,'sept_29th','discharge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,7,'sept_30th','charge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,8,'winter','discharge',152.5,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,9,'apr_w1','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,10,'apr_w2','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,11,'apr_w3','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,12,'apr_w4','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,13,'apr_29th','charge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(2000,14,'apr_30th','discharge',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'charge','a',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'charge','b',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'charge','c',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'charge','d',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'discharge','a',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'discharge','b',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'discharge','c',0.125,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'discharge','d',0.125,NULL); +REPLACE INTO "time_season" VALUES(0,'charge',NULL); +REPLACE INTO "time_season" VALUES(1,'discharge',NULL); +REPLACE INTO "time_season_sequential" VALUES(1,'summer','charge',152.5,NULL); +REPLACE INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(3,'sept_w2','charge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(5,'sept_w4','charge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',1.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(7,'sept_30th','charge',1.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(8,'winter','discharge',152.5,NULL); +REPLACE INTO "time_season_sequential" VALUES(9,'apr_w1','charge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(11,'apr_w3','charge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',7.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(13,'apr_29th','charge',1.0,NULL); +REPLACE INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',1.0,NULL); +REPLACE INTO "time_segment_fraction" VALUES('charge', 'a', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('charge', 'b', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('charge', 'c', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('charge', 'd', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('discharge', 'a', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('discharge', 'b', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('discharge', 'c', 0.125, NULL); +REPLACE INTO "time_segment_fraction" VALUES('discharge', 'd', 0.125, NULL); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index c73297039..fac6239c3 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -56,7 +56,7 @@ REPLACE INTO "time_period" VALUES(1,2000,'f'); REPLACE INTO "time_period" VALUES(2,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2000,1,'summer',NULL); -REPLACE INTO "time_season" VALUES(2000,2,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','day',0.5,'# S-D'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','day',0.5,'# W-D'); +REPLACE INTO "time_season" VALUES(1,'summer',NULL); +REPLACE INTO "time_season" VALUES(2,'winter',NULL); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.5, '# S-D'); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.5, '# W-D'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 3bf6ee5d4..6f3bc10df 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -75,15 +75,15 @@ REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2025,1,'s1',NULL); -REPLACE INTO "time_season" VALUES(2025,2,'s2',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d3',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d1',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d2',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d3',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d1',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d2',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d4',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s1','d5',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d4',0.1,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s2','d5',0.1,NULL); +REPLACE INTO "time_season" VALUES(1,'s1',NULL); +REPLACE INTO "time_season" VALUES(2,'s2',NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd3', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd1', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd2', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd3', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd1', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd2', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd4', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s1', 'd5', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd4', 0.1, NULL); +REPLACE INTO "time_segment_fraction" VALUES('s2', 'd5', 0.1, NULL); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index b8483c1f9..36e81024d 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -170,15 +170,10 @@ REPLACE INTO "time_period" VALUES(5,2050,'f'); REPLACE INTO "time_period" VALUES(6,2055,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2025,0,'s',NULL); -REPLACE INTO "time_season" VALUES(2030,1,'s',NULL); -REPLACE INTO "time_season" VALUES(2035,2,'s',NULL); -REPLACE INTO "time_season" VALUES(2040,3,'s',NULL); -REPLACE INTO "time_season" VALUES(2045,4,'s',NULL); -REPLACE INTO "time_season" VALUES(2050,5,'s',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2025,'s','d',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2030,'s','d',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2035,'s','d',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2040,'s','d',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2045,'s','d',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES(2050,'s','d',1.0,NULL); +REPLACE INTO "time_season" VALUES(0,'s',NULL); +REPLACE INTO "time_season" VALUES(1,'s',NULL); +REPLACE INTO "time_season" VALUES(2,'s',NULL); +REPLACE INTO "time_season" VALUES(3,'s',NULL); +REPLACE INTO "time_season" VALUES(4,'s',NULL); +REPLACE INTO "time_season" VALUES(5,'s',NULL); +REPLACE INTO "time_segment_fraction" VALUES('s', 'd', 1.0, NULL); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 6e0cd393a..6c5787321 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -518,39 +518,15 @@ REPLACE INTO "time_period" VALUES(4,2030,'f'); REPLACE INTO "time_period" VALUES(5,2035,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(2020,1,'spring',NULL); -REPLACE INTO "time_season" VALUES(2020,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(2020,3,'fall',NULL); -REPLACE INTO "time_season" VALUES(2020,4,'winter',NULL); -REPLACE INTO "time_season" VALUES(2025,1,'spring',NULL); -REPLACE INTO "time_season" VALUES(2025,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(2025,3,'fall',NULL); -REPLACE INTO "time_season" VALUES(2025,4,'winter',NULL); -REPLACE INTO "time_season" VALUES(2030,1,'spring',NULL); -REPLACE INTO "time_season" VALUES(2030,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(2030,3,'fall',NULL); -REPLACE INTO "time_season" VALUES(2030,4,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','day',0.125,'Spring - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'spring','night',0.125,'Spring - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','day',0.125,'Summer - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'summer','night',0.125,'Summer - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'fall','day',0.125,'Fall - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'fall','night',0.125,'Fall - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','day',0.125,'Winter - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2020,'winter','night',0.125,'Winter - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'spring','day',0.125,'Spring - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'spring','night',0.125,'Spring - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'summer','day',0.125,'Summer - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'summer','night',0.125,'Summer - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'fall','day',0.125,'Fall - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'fall','night',0.125,'Fall - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'winter','day',0.125,'Winter - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2025,'winter','night',0.125,'Winter - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'spring','day',0.125,'Spring - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'spring','night',0.125,'Spring - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'summer','day',0.125,'Summer - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'summer','night',0.125,'Summer - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'fall','day',0.125,'Fall - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'fall','night',0.125,'Fall - Night'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'winter','day',0.125,'Winter - Day'); -REPLACE INTO "time_segment_fraction" VALUES(2030,'winter','night',0.125,'Winter - Night'); +REPLACE INTO "time_season" VALUES(1,'spring',NULL); +REPLACE INTO "time_season" VALUES(2,'summer',NULL); +REPLACE INTO "time_season" VALUES(3,'fall',NULL); +REPLACE INTO "time_season" VALUES(4,'winter',NULL); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'day', 0.125, 'Spring - Day'); +REPLACE INTO "time_segment_fraction" VALUES('spring', 'night', 0.125, 'Spring - Night'); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.125, 'Summer - Day'); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'night', 0.125, 'Summer - Night'); +REPLACE INTO "time_segment_fraction" VALUES('fall', 'day', 0.125, 'Fall - Day'); +REPLACE INTO "time_segment_fraction" VALUES('fall', 'night', 0.125, 'Fall - Night'); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.125, 'Winter - Day'); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'night', 0.125, 'Winter - Night'); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index 1d1ab6dc8..17467e5f7 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -529,30 +529,12 @@ REPLACE INTO "time_period" VALUES(6,2010,'f'); REPLACE INTO "time_period" VALUES(7,2020,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1990,1,'inter',NULL); -REPLACE INTO "time_season" VALUES(1990,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(1990,3,'winter',NULL); -REPLACE INTO "time_season" VALUES(2000,1,'inter',NULL); -REPLACE INTO "time_season" VALUES(2000,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(2000,3,'winter',NULL); -REPLACE INTO "time_season" VALUES(2010,1,'inter',NULL); -REPLACE INTO "time_season" VALUES(2010,2,'summer',NULL); -REPLACE INTO "time_season" VALUES(2010,3,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES(1990,'inter','day',0.1667,'# I-D'); -REPLACE INTO "time_segment_fraction" VALUES(1990,'inter','night',0.0833,'# I-N'); -REPLACE INTO "time_segment_fraction" VALUES(1990,'summer','day',0.1667,'# S-D'); -REPLACE INTO "time_segment_fraction" VALUES(1990,'summer','night',0.0833,'# S-N'); -REPLACE INTO "time_segment_fraction" VALUES(1990,'winter','day',0.3333,'# W-D'); -REPLACE INTO "time_segment_fraction" VALUES(1990,'winter','night',0.1667,'# W-N'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'inter','day',0.1667,'# I-D'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'inter','night',0.0833,'# I-N'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','day',0.1667,'# S-D'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'summer','night',0.0833,'# S-N'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','day',0.3333,'# W-D'); -REPLACE INTO "time_segment_fraction" VALUES(2000,'winter','night',0.1667,'# W-N'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'inter','day',0.1667,'# I-D'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'inter','night',0.0833,'# I-N'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','day',0.1667,'# S-D'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'summer','night',0.0833,'# S-N'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','day',0.3333,'# W-D'); -REPLACE INTO "time_segment_fraction" VALUES(2010,'winter','night',0.1667,'# W-N'); +REPLACE INTO "time_season" VALUES(1,'inter',NULL); +REPLACE INTO "time_season" VALUES(2,'summer',NULL); +REPLACE INTO "time_season" VALUES(3,'winter',NULL); +REPLACE INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); +REPLACE INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); +REPLACE INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); +REPLACE INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); From fc3b8c1a1259567e470c01decaa6d058488f862b Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 20:35:54 -0500 Subject: [PATCH 04/40] Update test sets for removal of period indexed seasons --- tests/testing_data/mediumville_sets.json | 5 ----- tests/testing_data/test_system_sets.json | 5 ----- tests/testing_data/utopia_sets.json | 5 ----- 3 files changed, 15 deletions(-) diff --git a/tests/testing_data/mediumville_sets.json b/tests/testing_data/mediumville_sets.json index ba8a86132..c174d5ca4 100644 --- a/tests/testing_data/mediumville_sets.json +++ b/tests/testing_data/mediumville_sets.json @@ -4172,12 +4172,10 @@ ], "ordered_season_sequential": [ [ - 2025, "s1", "s1" ], [ - 2025, "s2", "s2" ] @@ -4310,9 +4308,6 @@ 2025 ], "time_season": [ - 2025 - ], - "time_season_all": [ "s1", "s2" ], diff --git a/tests/testing_data/test_system_sets.json b/tests/testing_data/test_system_sets.json index f06bf0c90..d5d02b8d4 100644 --- a/tests/testing_data/test_system_sets.json +++ b/tests/testing_data/test_system_sets.json @@ -45327,11 +45327,6 @@ 2030 ], "time_season": [ - 2025, - 2020, - 2030 - ], - "time_season_all": [ "summer", "fall", "spring", diff --git a/tests/testing_data/utopia_sets.json b/tests/testing_data/utopia_sets.json index 2c66a4186..51b9b5830 100644 --- a/tests/testing_data/utopia_sets.json +++ b/tests/testing_data/utopia_sets.json @@ -25216,11 +25216,6 @@ 1990 ], "time_season": [ - 2000, - 2010, - 1990 - ], - "time_season_all": [ "summer", "inter", "winter" From 49d9095e4fa1fcca0a30e78e1e8c8c7817cf45ea Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 20:52:26 -0500 Subject: [PATCH 05/40] Remove period index from time_next dicts --- temoa/_internal/table_data_puller.py | 2 +- temoa/components/flows.py | 5 ++-- temoa/components/operations.py | 12 +++++----- temoa/components/storage.py | 12 +++++----- temoa/components/time.py | 36 +++++++++++++--------------- temoa/core/model.py | 6 ++--- temoa/types/dict_types.py | 6 ++--- tests/test_storage.py | 2 +- 8 files changed, 38 insertions(+), 43 deletions(-) diff --git a/temoa/_internal/table_data_puller.py b/temoa/_internal/table_data_puller.py index 0d87d2273..186e88482 100644 --- a/temoa/_internal/table_data_puller.py +++ b/temoa/_internal/table_data_puller.py @@ -237,7 +237,7 @@ def poll_storage_level_results(model: TemoaModel, epsilon: float = 1e-5) -> dict res[sli] = state for r, p, s_seq, t, v in model.seasonal_storage_level_rpstv: - s = model.sequential_to_season[p, s_seq] + s = model.sequential_to_season[s_seq] # Ratio of days in virtual storage season to days in actual season # Flows and StorageLevel are normalised to the number of days in the ACTUAL season, so must # be adjusted to the number of days in the virtual storage season diff --git a/temoa/components/flows.py b/temoa/components/flows.py index ed183521f..83e50f48e 100644 --- a/temoa/components/flows.py +++ b/temoa/components/flows.py @@ -207,10 +207,9 @@ def create_commodity_balance_and_flow_sets(model: TemoaModel) -> None: } model.seasonal_storage_level_indices_rpstv = { - (r, p, s_stor, t, v) + (r, p, s_seq, t, v) for r, p, t in model.storage_vintages if t in model.tech_seasonal_storage for v in model.storage_vintages[r, p, t] - for _p, s_stor in model.sequential_to_season - if _p == p + for s_seq in model.sequential_to_season } diff --git a/temoa/components/operations.py b/temoa/components/operations.py index 347e4099e..fc6cac36e 100644 --- a/temoa/components/operations.py +++ b/temoa/components/operations.py @@ -83,8 +83,8 @@ def ramp_up_season_constraint_indices( for r, p, t in model.ramp_up_vintages for v in model.ramp_up_vintages[r, p, t] for s_seq, s in model.ordered_season_sequential - for s_next in (model.sequential_to_season[p, model.time_next_sequential[p, s_seq]],) - if s_next != model.time_next[p, s, model.time_of_day.last()][0] + for s_next in (model.sequential_to_season[model.time_next_sequential[s_seq]],) + if s_next != model.time_next[s, model.time_of_day.last()][0] } return indices @@ -102,8 +102,8 @@ def ramp_down_season_constraint_indices( for r, p, t in model.ramp_down_vintages for v in model.ramp_down_vintages[r, p, t] for s_seq, s in model.ordered_season_sequential - for s_next in (model.sequential_to_season[p, model.time_next_sequential[p, s_seq]],) - if s_next != model.time_next[p, s, model.time_of_day.last()][0] + for s_next in (model.sequential_to_season[model.time_next_sequential[s_seq]],) + if s_next != model.time_next[s, model.time_of_day.last()][0] } return indices @@ -295,7 +295,7 @@ def ramp_up_day_constraint( - :math:`CAP \cdot C2A` gives the maximum hourly change in activity """ - s_next, d_next = model.time_next[p, s, d] + s_next, d_next = model.time_next[s, d] # How many hours does this time slice represent hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 @@ -385,7 +385,7 @@ def ramp_down_day_constraint( \forall \{r, p, s, d, t, v\} \in \Theta_{\text{ramp\_down\_day}} """ - s_next, d_next = model.time_next[p, s, d] + s_next, d_next = model.time_next[s, d] # How many hours does this time slice represent hours_adjust = value(model.segment_fraction[s, d]) * value(model.days_per_period) * 24 diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 287e054d8..73a0ca36d 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -114,7 +114,7 @@ def storage_energy_constraint( s_next: Season d_next: TimeOfDay - s_next, d_next = model.time_next[p, s, d] + s_next, d_next = model.time_next[s, d] expr = ( model.v_storage_level[r, p, s, d, t, v] + stored_energy @@ -166,7 +166,7 @@ def seasonal_storage_energy_constraint( are each one day. """ - s: Season = model.sequential_to_season[p, s_seq] + s: Season = model.sequential_to_season[s_seq] # This is the sum of all input=i sent TO storage tech t of vintage v with # output=o in p,s @@ -185,8 +185,8 @@ def seasonal_storage_energy_constraint( for S_i in model.process_inputs_by_output[r, p, t, v, S_o] ) - s_seq_next: Season = model.time_next_sequential[p, s_seq] - s_next: Season = model.sequential_to_season[p, s_seq_next] + s_seq_next: Season = model.time_next_sequential[s_seq] + s_next: Season = model.sequential_to_season[s_seq_next] # Flows and StorageLevel are normalised to the number of days in the non-sequential season, # so must @@ -328,7 +328,7 @@ def seasonal_storage_energy_upper_bound_constraint( Unadjusted energy upper bound constraint for seasonal storage. """ - s: Season = model.sequential_to_season[p, s_seq] + s: Season = model.sequential_to_season[s_seq] energy_capacity = ( model.v_capacity[r, p, t, v] @@ -521,7 +521,7 @@ def limit_storage_fraction_constraint( if model.is_seasonal_storage[t]: s_seq: Season = s # sequential season - s = model.sequential_to_season[p, s_seq] # non-sequential season + s = model.sequential_to_season[s_seq] # non-sequential season # adjust the storage level to the individual-day level energy_level = model.v_storage_level[r, p, s, d, t, v] / ( diff --git a/temoa/components/time.py b/temoa/components/time.py index d263fa6e1..ce9c9c6f3 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -209,7 +209,7 @@ def param_period_length(model: TemoaModel, p: Period) -> int: def loop_period_next_timeslice( - model: TemoaModel, p: Period, s: Season, d: TimeOfDay + model: TemoaModel, s: Season, d: TimeOfDay ) -> tuple[Season, TimeOfDay]: # Final time slice of final season (end of period) # Loop state back to initial state of first season @@ -236,7 +236,7 @@ def loop_period_next_timeslice( def loop_season_next_timeslice( - model: TemoaModel, p: Period, s: Season, d: TimeOfDay + model: TemoaModel, s: Season, d: TimeOfDay ) -> tuple[Season, TimeOfDay]: # We loop each season so never carrying state between seasons s_next: Season = s @@ -268,24 +268,21 @@ def create_time_sequence(model: TemoaModel) -> None: match model.time_sequencing.first(): case 'consecutive_days': msg: str = 'Running a consecutive days database.' - for p in model.time_optimize: - for s, d in model.time_season * model.time_of_day: - model.time_next[p, s, d] = loop_period_next_timeslice(model, p, s, d) + for s, d in model.time_season * model.time_of_day: + model.time_next[s, d] = loop_period_next_timeslice(model, s, d) case 'seasonal_timeslices': msg = 'Running a seasonal time slice database.' - for p in model.time_optimize: - for s, d in model.time_season * model.time_of_day: - model.time_next[p, s, d] = loop_season_next_timeslice(model, p, s, d) + for s, d in model.time_season * model.time_of_day: + model.time_next[s, d] = loop_season_next_timeslice(model, s, d) case 'representative_periods': msg = 'Running a representative periods database.' - for p in model.time_optimize: - for s, d in model.time_season * model.time_of_day: - model.time_next[p, s, d] = loop_season_next_timeslice(model, p, s, d) + for s, d in model.time_season * model.time_of_day: + model.time_next[s, d] = loop_season_next_timeslice(model, s, d) case 'manual': # Hidden feature. Define the sequence directly in the time_manual table msg = 'Pulling time sequence from time_manual table.' for p, s, d, s_next, d_next in model.time_manual: - model.time_next[p, s, d] = s_next, d_next + model.time_next[s, d] = s_next, d_next case _: # This should have been caught in hybrid_loader msg = ( @@ -300,15 +297,14 @@ def create_time_sequence(model: TemoaModel) -> None: logger.debug('Creating superimposed sequential seasons.') - # Superimposed sequential seasons (global, applied to all periods) + # Superimposed sequential seasons (global, period-independent) seasons: list[tuple[Season, Season]] = list(model.ordered_season_sequential) - for p in model.time_optimize: - for i, (s_seq, s) in enumerate(seasons): - model.sequential_to_season[p, s_seq] = s - if (s_seq, s) == seasons[-1]: - model.time_next_sequential[p, s_seq] = seasons[0][0] - else: - model.time_next_sequential[p, s_seq] = seasons[i + 1][0] + for i, (s_seq, s) in enumerate(seasons): + model.sequential_to_season[s_seq] = s + if (s_seq, s) == seasons[-1]: + model.time_next_sequential[s_seq] = seasons[0][0] + else: + model.time_next_sequential[s_seq] = seasons[i + 1][0] logger.debug('Created time sequence.') diff --git a/temoa/core/model.py b/temoa/core/model.py index dbc8481ce..e683d4dd0 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -172,11 +172,11 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.import_regions: t.ImportRegionsDict = {} # These establish time sequencing - # {(p, s, d): (s_next, d_next)} sequence of following time slices + # {(s, d): (s_next, d_next)} sequence of following time slices self.time_next: t.TimeNextDict = {} - # {(p, s_seq): (s_seq_next)} next virtual storage season + # {s_seq: s_seq_next} next virtual storage season self.time_next_sequential: t.TimeNextSequentialDict = {} - # {(p, s_seq): (s)} season matching this virtual storage season + # {s_seq: s} season matching this virtual storage season self.sequential_to_season: t.SequentialToSeasonDict = {} ################################################ diff --git a/temoa/types/dict_types.py b/temoa/types/dict_types.py index 8fb2fb3da..e68176bfa 100644 --- a/temoa/types/dict_types.py +++ b/temoa/types/dict_types.py @@ -48,9 +48,9 @@ # Time sequencing dictionary types -TimeNextDict = dict[tuple[Period, Season, TimeOfDay], tuple[Season, TimeOfDay]] -TimeNextSequentialDict = dict[tuple[Period, Season], Season] -SequentialToSeasonDict = dict[tuple[Period, Season], Season] +TimeNextDict = dict[tuple[Season, TimeOfDay], tuple[Season, TimeOfDay]] +TimeNextSequentialDict = dict[Season, Season] +SequentialToSeasonDict = dict[Season, Season] # Geography/exchange dictionary types diff --git a/tests/test_storage.py b/tests/test_storage.py index b49fef3bf..c62be9b8b 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -80,7 +80,7 @@ def test_state_sequencing(system_test_run: tuple[str, Any, TemoaModel, Any]) -> for S_i in model.process_inputs_by_output[r, p, t, v, S_o] ) - s_next, d_next = model.time_next[p, s, d] + s_next, d_next = model.time_next[s, d] state = model.v_storage_level[r, p, s, d, t, v].value # type: ignore [attr-defined] # I can't figure out how to get mypy to see value through the pyomo stubs next_state = model.v_storage_level[r, p, s_next, d_next, t, v].value # type: ignore [attr-defined] # I can't figure out how to get mypy to see value through the pyomo stubs From bb54662385c7822058b3d28a4c98b5b9e886bcc8 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Tue, 3 Mar 2026 21:09:02 -0500 Subject: [PATCH 06/40] Update time_manual to remove period index --- data_files/temoa_schema_v4.sql | 4 +--- temoa/components/time.py | 6 +++--- temoa/data_io/component_manifest.py | 7 +++++++ temoa/db_schema/temoa_schema_v4.sql | 4 +--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 3494da570..937bdbc36 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -928,8 +928,6 @@ REPLACE INTO technology_type VALUES ('ps', 'storage production technology'); -- CREATE TABLE IF NOT EXISTS time_manual -- ( --- period INTEGER --- REFERENCES time_period (period), -- season TEXT -- REFERENCES season_label (season), -- tod TEXT @@ -939,7 +937,7 @@ VALUES ('ps', 'storage production technology'); -- tod_next TEXT -- REFERENCES time_of_day (tod), -- notes TEXT, --- PRIMARY KEY (period, season, tod) +-- PRIMARY KEY (season, tod) -- ); CREATE TABLE IF NOT EXISTS time_of_day ( diff --git a/temoa/components/time.py b/temoa/components/time.py index ce9c9c6f3..efe0b44a0 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -147,10 +147,10 @@ def validate_time_manual(model: TemoaModel) -> None: segment_fraction_sd: set[tuple[str, str]] = set(model.segment_fraction.sparse_iterkeys()) time_manual_sd: set[tuple[str, str]] = { - (s, d) for p, s, d, s_next, d_next in model.time_manual + (s, d) for s, d, s_next, d_next in model.time_manual } time_manual_sd_next: set[tuple[str, str]] = { - (s_next, d_next) for p, s, d, s_next, d_next in model.time_manual + (s_next, d_next) for s, d, s_next, d_next in model.time_manual } missing_sd: set[tuple[str, str]] = segment_fraction_sd.difference(time_manual_sd) @@ -281,7 +281,7 @@ def create_time_sequence(model: TemoaModel) -> None: case 'manual': # Hidden feature. Define the sequence directly in the time_manual table msg = 'Pulling time sequence from time_manual table.' - for p, s, d, s_next, d_next in model.time_manual: + for s, d, s_next, d_next in model.time_manual: model.time_next[s, d] = s_next, d_next case _: # This should have been caught in hybrid_loader diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index 6b2d65fe0..cb9138aae 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -261,6 +261,13 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_period_filtered=False, is_table_required=False, ), + LoadItem( + component=model.time_manual, + table='time_manual', + columns=['season', 'tod', 'season_next', 'tod_next'], + is_period_filtered=False, + is_table_required=False, + ), # ========================================================================= # Capacity and Cost Components # ========================================================================= diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 3494da570..937bdbc36 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -928,8 +928,6 @@ REPLACE INTO technology_type VALUES ('ps', 'storage production technology'); -- CREATE TABLE IF NOT EXISTS time_manual -- ( --- period INTEGER --- REFERENCES time_period (period), -- season TEXT -- REFERENCES season_label (season), -- tod TEXT @@ -939,7 +937,7 @@ VALUES ('ps', 'storage production technology'); -- tod_next TEXT -- REFERENCES time_of_day (tod), -- notes TEXT, --- PRIMARY KEY (period, season, tod) +-- PRIMARY KEY (season, tod) -- ); CREATE TABLE IF NOT EXISTS time_of_day ( From d73a664dc166d8dca91c63ac2af3836f3d82af5b Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Wed, 4 Mar 2026 17:47:20 -0500 Subject: [PATCH 07/40] Remove period index from several tables --- data_files/example_dbs/materials.sql | 286 +- data_files/example_dbs/morris_utopia.sql | 220 +- data_files/example_dbs/seasonal_storage.sql | 66 +- data_files/example_dbs/stepped_demand.sql | 138 +- data_files/example_dbs/survival_curve.sql | 30 +- data_files/example_dbs/test_system.sql | 162 +- data_files/example_dbs/utopia.sql | 220 +- temoa/_internal/table_data_puller.py | 2 +- temoa/components/capacity.py | 68 +- temoa/components/commodities.py | 48 +- temoa/components/emissions.py | 4 +- temoa/components/limits.py | 13 +- temoa/components/reserves.py | 14 +- temoa/components/storage.py | 18 +- temoa/components/technology.py | 23 +- temoa/components/utils.py | 6 +- temoa/core/model.py | 33 +- temoa/data_io/component_manifest.py | 34 +- temoa/data_io/hybrid_loader.py | 4 +- temoa/db_schema/temoa_schema_v4.sql | 30 +- temoa/tutorial_assets/utopia.sql | 220 +- temoa/types/dict_types.py | 4 +- tests/test_storage.py | 2 +- tests/testing_data/emissions.sql | 8 +- tests/testing_data/materials.sql | 128 +- tests/testing_data/mediumville.sql | 40 +- tests/testing_data/mediumville_sets.json | 76 +- tests/testing_data/seasonal_storage.sql | 36 +- tests/testing_data/storageville.sql | 22 +- tests/testing_data/test_system.sql | 132 +- tests/testing_data/test_system_sets.json | 3367 ++----------------- tests/testing_data/utopia_data.sql | 190 +- tests/testing_data/utopia_sets.json | 1162 +------ 33 files changed, 1007 insertions(+), 5799 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 433fd5b91..915f31886 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,14 +24,12 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -42,105 +38,41 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2000,'spring','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2010,'spring','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionA',2020,'spring','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2000,'spring','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2010,'spring','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'summer','morning','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'autumn','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'winter','morning','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'spring','morning','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'summer','afternoon','SOL_PV',0.3,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'autumn','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'winter','afternoon','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'spring','afternoon','SOL_PV',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'summer','evening','SOL_PV',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'autumn','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'winter','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'spring','evening','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'summer','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'autumn','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'winter','overnight','SOL_PV',0.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('RegionB',2020,'spring','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','summer','morning','SOL_PV',0.3,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','autumn','morning','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','winter','morning','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','spring','morning','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','summer','afternoon','SOL_PV',0.3,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','autumn','afternoon','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','winter','afternoon','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','spring','afternoon','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','summer','evening','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','autumn','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','winter','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','spring','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','summer','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','autumn','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','winter','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionA','spring','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','summer','morning','SOL_PV',0.3,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','autumn','morning','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','winter','morning','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','spring','morning','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','summer','afternoon','SOL_PV',0.3,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','autumn','afternoon','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','winter','afternoon','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','spring','afternoon','SOL_PV',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','summer','evening','SOL_PV',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','autumn','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','winter','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','spring','evening','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','summer','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','autumn','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','winter','overnight','SOL_PV',0.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('RegionB','spring','overnight','SOL_PV',0.0,NULL); CREATE TABLE capacity_to_activity ( region TEXT, @@ -368,8 +300,6 @@ INSERT INTO "demand" VALUES('RegionB',2020,'heating',1.0,NULL,NULL); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -378,105 +308,41 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2000,'spring','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2010,'spring','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionA',2020,'spring','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2000,'spring','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2010,'spring','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'summer','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'autumn','morning','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'winter','morning','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'spring','morning','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'summer','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'autumn','afternoon','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'winter','afternoon','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'spring','afternoon','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'summer','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'autumn','evening','heating',0.08,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'winter','evening','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'spring','evening','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'summer','overnight','heating',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'autumn','overnight','heating',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'winter','overnight','heating',0.16,NULL); -INSERT INTO "demand_specific_distribution" VALUES('RegionB',2020,'spring','overnight','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','summer','morning','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','autumn','morning','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','winter','morning','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','spring','morning','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','summer','afternoon','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','autumn','afternoon','heating',0.08,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','winter','afternoon','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','spring','afternoon','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','summer','evening','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','autumn','evening','heating',0.08,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','winter','evening','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','spring','evening','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','summer','overnight','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','autumn','overnight','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','winter','overnight','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionA','spring','overnight','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','summer','morning','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','autumn','morning','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','winter','morning','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','spring','morning','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','summer','afternoon','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','autumn','afternoon','heating',0.08,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','winter','afternoon','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','spring','afternoon','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','summer','evening','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','autumn','evening','heating',0.08,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','winter','evening','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','spring','evening','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','summer','overnight','heating',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','autumn','overnight','heating',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','winter','overnight','heating',0.16,NULL); +INSERT INTO "demand_specific_distribution" VALUES('RegionB','spring','overnight','heating',0.0,NULL); CREATE TABLE efficiency ( region TEXT, @@ -574,8 +440,6 @@ INSERT INTO "efficiency" VALUES('RegionB-RegionA','electricity','ELEC_INTERTIE', CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -590,7 +454,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -936,8 +800,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -946,26 +808,22 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1389,8 +1247,6 @@ INSERT INTO "region" VALUES('RegionB',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1398,7 +1254,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index b69844db6..479eac354 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,32 +24,24 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2010,0.2756,''); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -60,99 +50,39 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E70',0.8,''); CREATE TABLE capacity_to_activity ( region TEXT, @@ -468,8 +398,6 @@ INSERT INTO "demand" VALUES('utopia',2010,'TX',11.69,'',''); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -478,39 +406,19 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RH',2.73299999999999931e-01,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RH',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RH',2.73299999999999931e-01,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RH',0.12,NULL); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RH',2.73299999999999931e-01,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RH',0.12,NULL); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RH',0.06,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RH',0.5467,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RH',2.73299999999999931e-01,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RL',0.5,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RL',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RH',0.12,NULL); CREATE TABLE efficiency ( region TEXT, @@ -594,8 +502,6 @@ INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',2010,'TX',0.231,'# direct t CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -610,7 +516,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -976,8 +882,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -986,26 +890,22 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1381,8 +1281,6 @@ INSERT INTO "region" VALUES('utopia',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1390,7 +1288,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index d3d37b34c..e82b099f9 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,14 +24,12 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -42,17 +38,17 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'charge','a','generator',1.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'charge','b','generator',1.0,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'charge','c','generator',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'charge','d','generator',0.2,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'discharge','a','generator',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'discharge','b','generator',0.1,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'discharge','c','generator',0.01,NULL); -INSERT INTO "capacity_factor_tech" VALUES('region',2000,'discharge','d','generator',0.01,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','charge','a','generator',1.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','charge','b','generator',1.0,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','charge','c','generator',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','charge','d','generator',0.2,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','discharge','a','generator',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','discharge','b','generator',0.1,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','discharge','c','generator',0.01,NULL); +INSERT INTO "capacity_factor_tech" VALUES('region','discharge','d','generator',0.01,NULL); CREATE TABLE capacity_to_activity ( region TEXT, @@ -179,8 +175,6 @@ INSERT INTO "demand" VALUES('region',2000,'demand',8760.0,'MWh',NULL); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -189,17 +183,17 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'charge','a','demand',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'charge','b','demand',0.05,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'charge','c','demand',0.05,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'charge','d','demand',0.1,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'discharge','a','demand',0.0,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'discharge','b','demand',0.2,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'discharge','c','demand',0.2,NULL); -INSERT INTO "demand_specific_distribution" VALUES('region',2000,'discharge','d','demand',0.4,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','charge','a','demand',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','charge','b','demand',0.05,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','charge','c','demand',0.05,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','charge','d','demand',0.1,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','discharge','a','demand',0.0,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','discharge','b','demand',0.2,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','discharge','c','demand',0.2,NULL); +INSERT INTO "demand_specific_distribution" VALUES('region','discharge','d','demand',0.4,NULL); CREATE TABLE efficiency ( region TEXT, @@ -223,8 +217,6 @@ INSERT INTO "efficiency" VALUES('region','electricity','demand',2000,'demand',1. CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -239,7 +231,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -541,8 +533,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -551,29 +541,25 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); -INSERT INTO "limit_storage_level_fraction" VALUES('region',2000,'winter','b','seas_stor',2000,'e',0.5,NULL); -INSERT INTO "limit_storage_level_fraction" VALUES('region',2000,'charge','b','dly_stor',2000,'e',0.5,NULL); +INSERT INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor',2000,0.5,NULL); +INSERT INTO "limit_storage_level_fraction" VALUES('region','charge','b','dly_stor',2000,0.5,NULL); CREATE TABLE limit_tech_input_split ( region TEXT, @@ -941,8 +927,6 @@ INSERT INTO "region" VALUES('region',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -950,7 +934,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index ad38d0c70..dc5c62d16 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -67,8 +67,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tod TEXT @@ -78,14 +76,12 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tod TEXT @@ -94,75 +90,15 @@ CREATE TABLE capacity_factor_tech REFERENCES Technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2000,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2005,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2010,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2015,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2020,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2025,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2030,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2035,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2040,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2045,'summer','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'inter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'winter','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'summer','day','EF',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'inter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'winter','day','EH',1.0,''); -INSERT INTO capacity_factor_tech VALUES('electricville',2050,'summer','day','EH',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','inter','day','EF',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','winter','day','EF',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','summer','day','EF',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','inter','day','EH',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','winter','day','EH',1.0,''); +INSERT INTO "capacity_factor_tech" VALUES('electricville','summer','day','EH',1.0,''); CREATE TABLE CapacityToActivity ( region TEXT, @@ -357,8 +293,6 @@ INSERT INTO Demand VALUES('electricville',2050,'RL',2.0,NULL,NULL); CREATE TABLE DemandSpecificDistribution ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tod TEXT @@ -367,42 +301,12 @@ CREATE TABLE DemandSpecificDistribution REFERENCES Commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2000,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2000,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2000,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2005,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2005,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2005,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2010,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2010,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2010,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2015,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2015,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2015,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2020,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2020,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2020,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2025,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2025,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2025,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2030,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2030,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2030,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2035,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2035,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2035,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2040,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2040,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2040,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2045,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2045,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2045,'winter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2050,'inter','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2050,'summer','day','RL',0.3332999999999999852,''); -INSERT INTO DemandSpecificDistribution VALUES('electricville',2050,'winter','day','RL',0.3332999999999999852,''); +INSERT INTO DemandSpecificDistribution VALUES('electricville','inter','day','RL',0.3332999999999999852,''); +INSERT INTO DemandSpecificDistribution VALUES('electricville','summer','day','RL',0.3332999999999999852,''); +INSERT INTO DemandSpecificDistribution VALUES('electricville','winter','day','RL',0.3332999999999999852,''); CREATE TABLE end_of_life_output ( region TEXT, @@ -442,8 +346,6 @@ INSERT INTO efficiency VALUES('electricville','HYD','EH',2020,'ELC',1.0,NULL); CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tod TEXT @@ -458,7 +360,7 @@ CREATE TABLE efficiency_variable REFERENCES Commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -662,21 +564,17 @@ CREATE TABLE limit_degrowth_new_capacity_delta CREATE TABLE LimitStorageLevelFraction ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tod TEXT REFERENCES TimeOfDay (tod), tech TEXT REFERENCES Technology (tech), - vintage INTEGER - REFERENCES TimePeriod (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES Operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_activity ( @@ -798,8 +696,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES Region (region), - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tech TEXT @@ -808,7 +704,7 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES Operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1063,8 +959,6 @@ INSERT INTO Region VALUES('electricville',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES TimePeriod (period), season TEXT REFERENCES SeasonLabel (season), tech TEXT @@ -1072,7 +966,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE TimeSegmentFraction diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index e7239164e..b833a702f 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,14 +24,12 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -42,7 +38,7 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_to_activity @@ -223,8 +219,6 @@ INSERT INTO "demand" VALUES('region',2050,'demand',1.0,NULL,NULL); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -233,7 +227,7 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); CREATE TABLE efficiency @@ -263,8 +257,6 @@ INSERT INTO "efficiency" VALUES('region','source','tech_future',2050,'demand',1. CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -279,7 +271,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -643,8 +635,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -653,26 +643,22 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1041,8 +1027,6 @@ INSERT INTO "region" VALUES('region',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1050,7 +1034,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 56ccc2127..9b8c47841 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,14 +24,12 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -42,57 +38,25 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'spring','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'summer','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'fall','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'winter','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2020,'winter','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'spring','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'summer','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'fall','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'winter','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2020,'winter','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'spring','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'summer','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'fall','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'winter','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2025,'winter','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'spring','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'summer','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'fall','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'winter','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2025,'winter','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'spring','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'summer','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'fall','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'winter','day','E_SOLPV',0.6,''); -INSERT INTO "capacity_factor_tech" VALUES('R1',2030,'winter','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'spring','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'spring','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'summer','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'summer','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'fall','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'fall','night','E_SOLPV',0.0,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'winter','day','E_SOLPV',0.48,''); -INSERT INTO "capacity_factor_tech" VALUES('R2',2030,'winter','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','spring','day','E_SOLPV',0.6,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','spring','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','summer','day','E_SOLPV',0.6,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','summer','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','fall','day','E_SOLPV',0.6,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','fall','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','winter','day','E_SOLPV',0.6,''); +INSERT INTO "capacity_factor_tech" VALUES('R1','winter','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','spring','day','E_SOLPV',0.48,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','spring','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','summer','day','E_SOLPV',0.48,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','summer','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','fall','day','E_SOLPV',0.48,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','fall','night','E_SOLPV',0.0,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','winter','day','E_SOLPV',0.48,''); +INSERT INTO "capacity_factor_tech" VALUES('R2','winter','night','E_SOLPV',0.0,''); CREATE TABLE capacity_to_activity ( region TEXT, @@ -418,8 +382,6 @@ INSERT INTO "demand" VALUES('R2',2030,'VMT',42.0,'',''); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -428,57 +390,25 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2020,'winter','night','RH',0.4,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2020,'winter','night','RH',0.4,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2025,'winter','night','RH',0.4,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2025,'winter','night','RH',0.4,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R1',2030,'winter','night','RH',0.4,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'spring','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'spring','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'summer','day','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'summer','night','RH',0.0,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'fall','day','RH',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'fall','night','RH',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'winter','day','RH',0.3,''); -INSERT INTO "demand_specific_distribution" VALUES('R2',2030,'winter','night','RH',0.4,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','spring','day','RH',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','spring','night','RH',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','summer','day','RH',0.0,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','summer','night','RH',0.0,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','fall','day','RH',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','fall','night','RH',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','winter','day','RH',0.3,''); +INSERT INTO "demand_specific_distribution" VALUES('R1','winter','night','RH',0.4,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','spring','day','RH',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','spring','night','RH',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','summer','day','RH',0.0,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','summer','night','RH',0.0,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','fall','day','RH',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','fall','night','RH',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','winter','day','RH',0.3,''); +INSERT INTO "demand_specific_distribution" VALUES('R2','winter','night','RH',0.4,''); CREATE TABLE efficiency ( region TEXT, @@ -572,8 +502,6 @@ INSERT INTO "efficiency" VALUES('R2-R1','ELC','E_TRANS',2015,'ELC',0.9,''); CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -588,7 +516,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -944,8 +872,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -954,29 +880,25 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); -INSERT INTO "limit_storage_level_fraction" VALUES('R1',2025,'winter','day','E_BATT',2025,'e',0.5,''); -INSERT INTO "limit_storage_level_fraction" VALUES('R2',2020,'summer','day','E_BATT',2020,'e',0.5,''); +INSERT INTO "limit_storage_level_fraction" VALUES('R1','winter','day','E_BATT',2025,0.5,''); +INSERT INTO "limit_storage_level_fraction" VALUES('R2','summer','day','E_BATT',2020,0.5,''); CREATE TABLE limit_tech_input_split ( region TEXT, @@ -1369,8 +1291,6 @@ INSERT INTO "region" VALUES('R2',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1378,7 +1298,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 6b36306fe..f04eab310 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,32 +24,24 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2010,0.2756,''); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -60,99 +50,39 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E70',0.8,''); CREATE TABLE capacity_to_activity ( region TEXT, @@ -466,8 +396,6 @@ INSERT INTO "demand" VALUES('utopia',2010,'TX',11.69,'',''); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -476,39 +404,19 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RL',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RH',0.12,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RH',0.06,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RH',0.5467,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RH',0.2733,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RL',0.5,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RL',0.1,''); CREATE TABLE efficiency ( region TEXT, @@ -592,8 +500,6 @@ INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',2010,'TX',0.231,'# direct t CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -608,7 +514,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -974,8 +880,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -984,26 +888,22 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1378,8 +1278,6 @@ INSERT INTO "region" VALUES('utopia',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1387,7 +1285,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/temoa/_internal/table_data_puller.py b/temoa/_internal/table_data_puller.py index 186e88482..f936dd0bb 100644 --- a/temoa/_internal/table_data_puller.py +++ b/temoa/_internal/table_data_puller.py @@ -155,7 +155,7 @@ def poll_flow_results(model: TemoaModel, epsilon: float = 1e-5) -> dict[FI, dict for s in model.time_season: for d in model.time_of_day: if o in model.commodity_demand: - distribution = value(model.demand_specific_distribution[r, p, s, d, o]) + distribution = value(model.demand_specific_distribution[r, s, d, o]) else: distribution = value(model.segment_fraction[s, d]) fi = FI(r, p, s, d, i, t, v, o) diff --git a/temoa/components/capacity.py b/temoa/components/capacity.py index 688aaa885..447832461 100644 --- a/temoa/components/capacity.py +++ b/temoa/components/capacity.py @@ -40,29 +40,36 @@ def check_capacity_factor_process(model: TemoaModel) -> None: - count_rptv: dict[tuple[Region, Period, Technology, Vintage], int] = {} + + # Count of capacity factor process entries for this process in this region + count_rtv: dict[tuple[Region, Technology, Vintage], int] = {} + # Pull capacity_factor_tech by default - for r, p, _s, _d, t in model.capacity_factor_rpsdt: - for v in model.process_vintages[r, p, t]: - model.is_capacity_factor_process[r, p, t, v] = False - count_rptv[r, p, t, v] = 0 + unique_rt = set((r, t) for r, _s, _d, t in model.capacity_factor_rsdt) + for r, t in unique_rt: + for p in model.time_optimize: + for v in model.process_vintages.get((r, p, t), []): + if (r, t, v) not in count_rtv: + model.is_capacity_factor_process[r, t, v] = False + count_rtv[r, t, v] = 0 # Check for bad values and count up the good ones - for r, p, _s, _d, t, v in model.capacity_factor_process.sparse_iterkeys(): - if v not in model.process_vintages[r, p, t]: - msg = f'Invalid process {p, v} for {r, t} in capacity_factor_process table' + for r, _s, _d, t, v in model.capacity_factor_process.sparse_iterkeys(): + # Validate that vintage is active for some period + if not model.process_periods.get((r, t, v)): + msg = f'Invalid vintage {v} for {r, t} in capacity_factor_process table' logger.error(msg) raise ValueError(msg) # Good value, pull from capacity_factor_process table - count_rptv[r, p, t, v] += 1 + count_rtv[r, t, v] += 1 # Check if all possible values have been set by process # log a warning if some are missing (allowed but maybe accidental) - for (r, p, t, v), count in count_rptv.items(): + for (r, t, v), count in count_rtv.items(): num_seg = len(model.time_season) * len(model.time_of_day) if count > 0: - model.is_capacity_factor_process[r, p, t, v] = True + model.is_capacity_factor_process[r, t, v] = True if count < num_seg: logger.info( 'Some but not all processes were set in capacity_factor_process (%i out of a ' @@ -70,7 +77,7 @@ def check_capacity_factor_process(model: TemoaModel) -> None: 'value or 1 if that is not set either.', count, num_seg, - (r, p, t, v), + (r, t, v), ) @@ -85,12 +92,11 @@ def create_capacity_factors(model: TemoaModel) -> None: capacity_factor_process = model.capacity_factor_process # Step 1 - processes = {(r, t, v) for r, i, t, v, o in model.efficiency.sparse_iterkeys()} + processes = {(r, t, v) for r, _i, t, v, _o in model.efficiency.sparse_iterkeys()} all_cfs = { - (r, p, s, d, t, v) + (r, s, d, t, v) for (r, t, v) in processes - for p in model.process_periods[r, t, v] for s, d in cross_product(model.time_season, model.time_of_day) } @@ -106,8 +112,8 @@ def create_capacity_factors(model: TemoaModel) -> None: if unspecified_cfs: # CFP._constructed = False - for r, p, s, d, t, v in unspecified_cfs: - capacity_factor_process[r, p, s, d, t, v] = model.capacity_factor_tech[r, p, s, d, t] + for r, s, d, t, v in unspecified_cfs: + capacity_factor_process[r, s, d, t, v] = model.capacity_factor_tech[r, s, d, t] logger.debug( 'Created Capacity Factors for %d processes without an explicit specification', len(unspecified_cfs), @@ -116,7 +122,7 @@ def create_capacity_factors(model: TemoaModel) -> None: def get_default_capacity_factor( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay, t: Technology, v: Vintage + model: TemoaModel, r: Region, s: Season, d: TimeOfDay, t: Technology, v: Vintage ) -> float: """ This initializer is used to fill the capacity_factor_process from the capacity_factor_tech @@ -134,16 +140,16 @@ def get_default_capacity_factor( :param v: vintage :return: the capacity factor """ - return value(model.capacity_factor_tech[r, p, s, d, t]) + return value(model.capacity_factor_tech[r, s, d, t]) def get_capacity_factor( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay, t: Technology, v: Vintage + model: TemoaModel, r: Region, s: Season, d: TimeOfDay, t: Technology, v: Vintage ) -> float: - if model.is_capacity_factor_process[r, p, t, v]: - return value(model.capacity_factor_process[r, p, s, d, t, v]) + if model.is_capacity_factor_process[r, t, v]: + return value(model.capacity_factor_process[r, s, d, t, v]) else: - return value(model.capacity_factor_tech[r, p, s, d, t]) + return value(model.capacity_factor_tech[r, s, d, t]) # ============================================================================ @@ -244,13 +250,13 @@ def capacity_factor_process_indices( def capacity_factor_tech_indices( model: TemoaModel, -) -> set[tuple[Region, Period, Season, TimeOfDay, Technology]]: - all_cfs: set[tuple[Region, Period, Season, TimeOfDay, Technology]] = set() - if model.active_capacity_available_rpt: - for r, p, t in model.active_capacity_available_rpt: +) -> set[tuple[Region, Season, TimeOfDay, Technology]]: + all_cfs: set[tuple[Region, Season, TimeOfDay, Technology]] = set() + if model.active_capacity_available_rpt: # in case every tech in the model is unlim_cap + for r, _p, t in model.active_capacity_available_rpt: for s in model.time_season: for d in model.time_of_day: - all_cfs.add((r, p, s, d, t)) + all_cfs.add((r, s, d, t)) else: return set() return all_cfs @@ -445,7 +451,7 @@ def capacity_constraint( # Annual demand technology useful_activity = sum( ( - value(model.demand_specific_distribution[r, p, s, d, S_o]) + value(model.demand_specific_distribution[r, s, d, S_o]) if S_o in model.commodity_demand else value(model.segment_fraction[s, d]) ) @@ -463,7 +469,7 @@ def capacity_constraint( if t in model.tech_curtailment: # If technologies are present in the curtailment set, then enough # capacity must be available to cover both activity and curtailment. - return get_capacity_factor(model, r, p, s, d, t, v) * value( + return get_capacity_factor(model, r, s, d, t, v) * value( model.capacity_to_activity[r, t] ) * value(model.segment_fraction[s, d]) * model.v_capacity[ r, p, t, v @@ -474,7 +480,7 @@ def capacity_constraint( ) else: return ( - get_capacity_factor(model, r, p, s, d, t, v) + get_capacity_factor(model, r, s, d, t, v) * value(model.capacity_to_activity[r, t]) * value(model.segment_fraction[s, d]) * model.v_capacity[r, p, t, v] diff --git a/temoa/components/commodities.py b/temoa/components/commodities.py index de80b56ca..94a86ed9b 100644 --- a/temoa/components/commodities.py +++ b/temoa/components/commodities.py @@ -249,7 +249,7 @@ def demand_activity_constraint( for s_i in model.process_inputs_by_output[r, p, t, v, dem] ) - expr = annual_activity * value(model.demand_specific_distribution[r, p, s, d, dem]) == activity + expr = annual_activity * value(model.demand_specific_distribution[r, s, d, dem]) == activity return expr @@ -386,7 +386,7 @@ def commodity_balance_constraint( # Into annual flows consumed += sum( ( - value(model.demand_specific_distribution[r, p, s, d, s_o]) + value(model.demand_specific_distribution[r, s, d, s_o]) if s_o in model.commodity_demand else value(model.segment_fraction[s, d]) ) @@ -692,14 +692,13 @@ def create_demands(model: TemoaModel) -> None: logger.debug('Started creating demand distributions in CreateDemands()') # Step 0: some setup for a couple of reusable items - # Get the nth element from the tuple (r, p, s, d, dem) + # Get the nth element from the tuple (r, s, d, dem) # So we only have to update these indices in one place if they change demand_specific_distribution_region = iget(0) - demand_specific_distribution_period = iget(1) - demand_specific_distributon_dem = iget(4) + demand_specific_distributon_dem = iget(3) # Step 1: Check if any demand commodities are going unused - used_dems = {dem for r, p, dem in model.demand.sparse_iterkeys()} + used_dems = {dem for _r, _p, dem in model.demand.sparse_iterkeys()} unused_dems = sorted(model.commodity_demand.difference(used_dems)) if unused_dems: for dem in unused_dems: @@ -762,33 +761,30 @@ def create_demands(model: TemoaModel) -> None: ) # the demands not mentioned in DSD *at all* if unset_demand_distributions: - for p in model.time_optimize: - unset_distributions = set( - cross_product( - model.regions, - (p,), - model.time_season, - model.time_of_day, - unset_demand_distributions, - ) + unset_distributions = set( + cross_product( + model.regions, + model.time_season, + model.time_of_day, + unset_demand_distributions, ) - for r, p, s, d, dem in unset_distributions: - demand_specific_distribution[r, p, s, d, dem] = value( - model.segment_fraction[s, d] - ) # DSD._constructed = True + ) + for r, s, d, dem in unset_distributions: + demand_specific_distribution[r, s, d, dem] = value( + model.segment_fraction[s, d] + ) # DSD._constructed = True # Step 5: A final "sum to 1" check for all DSD members (which now should be everything) # Also check that all keys are made... The demand distro should be supported # by the full set of (r, p, dem) keys because it is an equality constraint # and we need to ensure even the zeros are passed in - used_rp_dems = {(r, p, dem) for r, p, dem in model.demand.sparse_iterkeys()} - for r, p, dem in used_rp_dems: + used_r_dems = {(r, dem) for r, p, dem in model.demand.sparse_iterkeys()} + for r, dem in used_r_dems: expected_key_length = len(model.time_season) * len(model.time_of_day) keys = [ k for k in demand_specific_distribution.sparse_iterkeys() if demand_specific_distribution_region(k) == r - and demand_specific_distribution_period(k) == p and demand_specific_distributon_dem(k) == dem ] if len(keys) != expected_key_length: @@ -797,11 +793,11 @@ def create_demands(model: TemoaModel) -> None: (s, d) for s in model.time_season for d in model.time_of_day - if (r, p, s, d, dem) not in keys + if (r, s, d, dem) not in keys } logger.info( 'Missing some time slices for Demand Specific Distribution %s: %s', - (r, p, dem), + (r, dem), missing, ) total = sum(value(demand_specific_distribution[i]) for i in keys) @@ -829,7 +825,7 @@ def get_str_padding(obj: Any) -> int: 'must total to 1.\n\n Demand-specific distribution in error: ' ' \n {}\n\tsum = {}' ) - logger.error(msg.format((r, p, dem), items, total)) - raise ValueError(msg.format((r, p, dem), items, total)) + logger.error(msg.format((r, dem), items, total)) + raise ValueError(msg.format((r, dem), items, total)) logger.debug('Finished creating demand distributions') diff --git a/temoa/components/emissions.py b/temoa/components/emissions.py index 982afcbb4..05cae02f3 100644 --- a/temoa/components/emissions.py +++ b/temoa/components/emissions.py @@ -106,7 +106,7 @@ def linked_emissions_tech_constraint( if t in model.tech_annual: primary_flow = quicksum( ( - value(model.demand_specific_distribution[r, p, s, d, S_o]) + value(model.demand_specific_distribution[r, s, d, S_o]) if S_o in model.commodity_demand else value(model.segment_fraction[s, d]) ) @@ -134,7 +134,7 @@ def linked_emissions_tech_constraint( if linked_t in model.tech_annual: linked_flow = quicksum( ( - value(model.demand_specific_distribution[r, p, s, d, S_o]) + value(model.demand_specific_distribution[r, s, d, S_o]) if S_o in model.commodity_demand else value(model.segment_fraction[s, d]) ) diff --git a/temoa/components/limits.py b/temoa/components/limits.py index d1897efb7..9b853f45b 100644 --- a/temoa/components/limits.py +++ b/temoa/components/limits.py @@ -197,6 +197,17 @@ def limit_degrowth_new_capacity_delta_indices( return indices +def limit_seasonal_capacity_factor_constraint_indices( + model: TemoaModel, +) -> set[tuple[Region, Period, Season, Technology, str]]: + """Expand the period-free param set to include all time_optimize periods.""" + return { + (r, p, s, t, op) + for r, s, t, op in model.limit_seasonal_capacity_factor_constraint_rst + for p in model.time_optimize + } + + # ============================================================================ # PYOMO CONSTRAINT RULES # ============================================================================ @@ -561,7 +572,7 @@ def limit_seasonal_capacity_factor_constraint( * value(model.segment_fraction_per_season[s]) for _r in regions ) - seasonal_cf = value(model.limit_seasonal_capacity_factor[r, p, s, t, op]) + seasonal_cf = value(model.limit_seasonal_capacity_factor[r, s, t, op]) expr = operator_expression(activity_rpst, Operator(op), seasonal_cf * possible_activity_rpst) # in the case that there is nothing to sum, skip if isinstance(expr, bool): # an empty list was generated diff --git a/temoa/components/reserves.py b/temoa/components/reserves.py index fedcf070d..df795f91f 100644 --- a/temoa/components/reserves.py +++ b/temoa/components/reserves.py @@ -99,8 +99,8 @@ def reserve_margin_dynamic( # Derated available generation available = sum( model.v_capacity[r, p, t, v] - * value(model.reserve_capacity_derate[r, p, s, t, v]) - * value(model.capacity_factor_process[r, p, s, d, t, v]) + * value(model.reserve_capacity_derate[r, s, t, v]) + * value(model.capacity_factor_process[r, s, d, t, v]) * value(model.capacity_to_activity[r, t]) * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r, p] @@ -111,7 +111,7 @@ def reserve_margin_dynamic( # Derated net output flow available += sum( model.v_flow_out[r, p, s, d, i, t, v, o] - * value(model.reserve_capacity_derate[r, p, s, t, v]) + * value(model.reserve_capacity_derate[r, s, t, v]) for (t, v) in model.process_reserve_periods[r, p] if t in model.tech_storage for i in model.process_inputs[r, p, t, v] @@ -119,7 +119,7 @@ def reserve_margin_dynamic( ) available -= sum( model.v_flow_in[r, p, s, d, i, t, v, o] - * value(model.reserve_capacity_derate[r, p, s, t, v]) + * value(model.reserve_capacity_derate[r, s, t, v]) for (t, v) in model.process_reserve_periods[r, p] if t in model.tech_storage for i in model.process_inputs[r, p, t, v] @@ -152,8 +152,8 @@ def reserve_margin_dynamic( # add the available output of the exchange tech. available += sum( model.v_capacity[r1r2, p, t, v] - * value(model.reserve_capacity_derate[r, p, s, t, v]) - * value(model.capacity_factor_process[r, p, s, d, t, v]) + * value(model.reserve_capacity_derate[r, s, t, v]) + * value(model.capacity_factor_process[r, s, d, t, v]) * value(model.capacity_to_activity[r1r2, t]) * value(model.segment_fraction[s, d]) for (t, v) in model.process_reserve_periods[r1r2, p] @@ -284,7 +284,7 @@ def reserve_margin_constraint( # Annual generation total_generation += sum( ( - value(model.demand_specific_distribution[r, p, s, d, S_o]) + value(model.demand_specific_distribution[r, s, d, S_o]) if S_o in model.commodity_demand else value(model.segment_fraction[s, d]) ) diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 73a0ca36d..8bcc46405 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -61,6 +61,22 @@ def storage_constraint_indices( return model.storage_level_indices_rpsdtv +def limit_storage_fraction_constraint_indices( + model: TemoaModel, +) -> set[tuple[Region, Period, Season, TimeOfDay, Technology, Vintage, str]]: + """Expand the period-free param set to include all valid process (period, vintage) combos.""" + param_keys = set(model.limit_storage_fraction_param_rsdt) + all_storage = set(model.storage_constraints_rpsdtv) | set( + model.seasonal_storage_constraints_rpsdtv + ) + result: set[tuple] = set() + for r, p, s, d, t, v in all_storage: + for op in model.operator: + if (r, s, d, t, op) in param_keys: + result.add((r, p, s, d, t, v, op)) + return result + + # ============================================================================ # PYOMO CONSTRAINT RULES # ============================================================================ @@ -516,7 +532,7 @@ def limit_storage_fraction_constraint( model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) * (value(model.storage_duration[r, t]) / (24 * value(model.days_per_period))) - * value(model.limit_storage_fraction[r, p, s, d, t, v, op]) + * value(model.limit_storage_fraction[r, s, d, t, op]) ) if model.is_seasonal_storage[t]: diff --git a/temoa/components/technology.py b/temoa/components/technology.py index 735cad03d..6764bacc3 100644 --- a/temoa/components/technology.py +++ b/temoa/components/technology.py @@ -384,30 +384,25 @@ def check_efficiency_indices(model: TemoaModel) -> None: def check_efficiency_variable(model: TemoaModel) -> None: - count_rpitvo = {} + count_ritvo = {} # Pull non-variable efficiency by default for r, i, t, v, o in model.efficiency.sparse_iterkeys(): if (r, t, v) not in model.process_periods: # Probably an existing vintage that retires in p0 # Still want it for end of life flows continue - for p in model.process_periods[r, t, v]: - model.is_efficiency_variable[r, p, i, t, v, o] = False - count_rpitvo[r, p, i, t, v, o] = 0 + model.is_efficiency_variable[r, i, t, v, o] = False + count_ritvo[r, i, t, v, o] = 0 annual = set() # Check for bad values and count up the good ones - for r, p, _s, _d, i, t, v, o in model.efficiency_variable.sparse_iterkeys(): - if p not in model.process_periods[r, t, v]: - msg = f'Invalid period {p} for process {r, t, v} in efficiency_variable table' - logger.error(msg) - raise ValueError(msg) - + for r, _s, _d, i, t, v, o in model.efficiency_variable.sparse_iterkeys(): if t in model.tech_annual: annual.add(t) # Good value, pull from efficiency_variable table - count_rpitvo[r, p, i, t, v, o] += 1 + if (r, i, t, v, o) in count_ritvo: + count_ritvo[r, i, t, v, o] += 1 for t in annual: msg = ( @@ -420,14 +415,14 @@ def check_efficiency_variable(model: TemoaModel) -> None: # Check if all possible values have been set as variable # log a warning if some are missing (allowed but maybe accidental) num_seg = len(model.time_season) * len(model.time_of_day) - for (r, p, i, t, v, o), count in count_rpitvo.items(): + for (r, i, t, v, o), count in count_ritvo.items(): if count > 0: - model.is_efficiency_variable[r, p, i, t, v, o] = True + model.is_efficiency_variable[r, i, t, v, o] = True if count < num_seg: logger.info( 'Some but not all efficiency_variable values were set (%i out of a possible ' '%i) for: %s Missing values will default to value set in efficiency table.', count, num_seg, - (r, p, i, t, v, o), + (r, i, t, v, o), ) diff --git a/temoa/components/utils.py b/temoa/components/utils.py index c558bf23b..c26ccbafa 100644 --- a/temoa/components/utils.py +++ b/temoa/components/utils.py @@ -53,7 +53,7 @@ def operator_expression(lhs: Expression, operator: Operator, rhs: Expression) -> def get_variable_efficiency( model: TemoaModel, r: Region, - p: Period, + _p: Period, s: Season, d: TimeOfDay, i: Commodity, @@ -74,9 +74,9 @@ def get_variable_efficiency( This dictionary-lookup approach is used for performance, as it is much faster than repeatedly checking the indices of a large Pyomo parameter during model build. """ - if model.is_efficiency_variable.get((r, p, i, t, v, o), False): + if model.is_efficiency_variable[r, i, t, v, o]: return value(model.efficiency[r, i, t, v, o]) * value( - model.efficiency_variable[r, p, s, d, i, t, v, o] + model.efficiency_variable[r, s, d, i, t, v, o] ) else: return value(model.efficiency[r, i, t, v, o]) diff --git a/temoa/core/model.py b/temoa/core/model.py index e683d4dd0..fe9d7f9b2 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -148,7 +148,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.retirement_production_processes: t.RetirementProductionProcessesDict = {} self.process_inputs_by_output: t.ProcessInputsByOutputDict = {} self.process_outputs_by_input: t.ProcessOutputsByInputDict = {} - self.process_techs: t.ProcessTechsDict = {} self.process_reserve_periods: t.ProcessReservePeriodsDict = {} self.process_periods: t.ProcessPeriodsDict = {} # {(r, t, v): set(p)} # {(r, t, v): set(p)} periods in which a process can economically or naturally retire @@ -184,9 +183,9 @@ def __init__(self, *args: object, **kwargs: object) -> None: # (to avoid slow searches in initialisation) # ################################################ - # {(r, p, i, t, v, o): bool} which efficiencies have variable indexing + # {(r, i, t, v, o): bool} which efficiencies have variable indexing self.is_efficiency_variable: t.EfficiencyVariableDict = {} - # {(r, p, t, v): bool} which capacity factors have have period-vintage indexing + # {(r, t, v): bool} which processes use capacity_factor_process table (instead of capacity_factor_tech) self.is_capacity_factor_process: t.CapacityFactorProcessDict = {} # {t: bool} whether a storage tech is seasonal storage self.is_seasonal_storage: t.SeasonalStorageDict = {} @@ -347,7 +346,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: # ) self.demand_specific_distribution = Param( self.regions, - self.time_optimize, self.time_season, self.time_of_day, self.commodity_demand, @@ -405,7 +403,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.efficiency_variable = Param( self.regional_indices, - self.time_optimize, self.time_season, self.time_of_day, self.commodity_physical, @@ -512,16 +509,15 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.create_sparse_dicts = BuildAction(rule=create_sparse_dicts) self.initialize_demands = BuildAction(rule=commodities.create_demands) - self.capacity_factor_rpsdt = Set(dimen=5, initialize=capacity.capacity_factor_tech_indices) + self.capacity_factor_rsdt = Set(dimen=4, initialize=capacity.capacity_factor_tech_indices) self.capacity_factor_tech = Param( - self.capacity_factor_rpsdt, default=1, validate=validate_0to1 + self.capacity_factor_rsdt, default=1, validate=validate_0to1 ) # Dev note: using a default function below alleviates need to make this set. # M.CapacityFactor_rsdtv = Set(dimen=5, initialize=capacity_factor_processIndices) self.capacity_factor_process = Param( self.regional_indices, - self.time_optimize, self.time_season, self.time_of_day, self.tech_with_capacity, @@ -600,15 +596,17 @@ def __init__(self, *args: object, **kwargs: object) -> None: ) self.limit_activity = Param(self.limit_activity_constraint_rpt) + self.limit_seasonal_capacity_factor_constraint_rst = Set() + self.limit_seasonal_capacity_factor = Param( + self.limit_seasonal_capacity_factor_constraint_rst, validate=validate_0to1 + ) self.limit_seasonal_capacity_factor_constraint_rpst = Set( within=self.regional_global_indices * self.time_optimize * self.time_season * self.tech_all - * self.operator - ) - self.limit_seasonal_capacity_factor = Param( - self.limit_seasonal_capacity_factor_constraint_rpst, validate=validate_0to1 + * self.operator, + initialize=limits.limit_seasonal_capacity_factor_constraint_indices, ) self.limit_annual_capacity_factor_constraint_rpto = Set( @@ -685,12 +683,14 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.seasonal_storage_constraints_rpsdtv = Set( dimen=6, initialize=storage.seasonal_storage_constraint_indices ) + self.limit_storage_fraction_param_rsdt = Set() # populated by hybrid_loader with (r, s, d, t, op) keys + self.limit_storage_fraction = Param( + self.limit_storage_fraction_param_rsdt, validate=validate_0to1 + ) self.limit_storage_fraction_constraint_rpsdtv = Set( within=(self.storage_constraints_rpsdtv | self.seasonal_storage_constraints_rpsdtv) - * self.operator - ) - self.limit_storage_fraction = Param( - self.limit_storage_fraction_constraint_rpsdtv, validate=validate_0to1 + * self.operator, + initialize=storage.limit_storage_fraction_constraint_indices, ) # Storage duration is expressed in hours @@ -710,7 +710,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: ) self.reserve_capacity_derate = Param( self.regional_indices, - self.time_optimize, self.time_season, self.tech_reserve, self.vintage_all, diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index cb9138aae..b796a9dc5 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -356,7 +356,6 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: table='efficiency_variable', columns=[ 'region', - 'period', 'season', 'tod', 'input_comm', @@ -366,7 +365,8 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: 'efficiency', ], validator_name='viable_ritvo', - validation_map=(0, 4, 5, 6, 7), + validation_map=(0, 3, 4, 5, 6), + is_period_filtered=False, is_table_required=False, ), LoadItem( @@ -377,7 +377,8 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.demand_specific_distribution, table='demand_specific_distribution', - columns=['region', 'period', 'season', 'tod', 'demand_name', 'dsd'], + columns=['region', 'season', 'tod', 'demand_name', 'dsd'], + is_period_filtered=False, is_table_required=False, ), LoadItem( @@ -392,17 +393,19 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.capacity_factor_tech, table='capacity_factor_tech', - columns=['region', 'period', 'season', 'tod', 'tech', 'factor'], + columns=['region', 'season', 'tod', 'tech', 'factor'], validator_name='viable_rt', - validation_map=(0, 4), + validation_map=(0, 3), + is_period_filtered=False, is_table_required=False, ), LoadItem( component=model.capacity_factor_process, table='capacity_factor_process', - columns=['region', 'period', 'season', 'tod', 'tech', 'vintage', 'factor'], + columns=['region', 'season', 'tod', 'tech', 'vintage', 'factor'], validator_name='viable_rtv', - validation_map=(0, 4, 5), + validation_map=(0, 3, 4), + is_period_filtered=False, is_table_required=False, ), LoadItem( @@ -495,9 +498,10 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.reserve_capacity_derate, table='reserve_capacity_derate', - columns=['region', 'period', 'season', 'tech', 'vintage', 'factor'], + columns=['region', 'season', 'tech', 'vintage', 'factor'], validator_name='viable_rtv', - validation_map=(0, 3, 4), + validation_map=(0, 2, 3), + is_period_filtered=False, is_table_required=False, ), LoadItem( @@ -521,16 +525,15 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: table='limit_storage_level_fraction', columns=[ 'region', - 'period', 'season', 'tod', 'tech', - 'vintage', 'operator', 'fraction', ], - validator_name='viable_rtv', - validation_map=(0, 4, 5), + validator_name='viable_rt', + validation_map=(0, 3), + is_period_filtered=False, is_table_required=False, ), LoadItem( @@ -635,9 +638,10 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: LoadItem( component=model.limit_seasonal_capacity_factor, table='limit_seasonal_capacity_factor', - columns=['region', 'period', 'season', 'tech', 'operator', 'factor'], + columns=['region', 'season', 'tech', 'operator', 'factor'], validator_name='viable_rt', - validation_map=(0, 3), + validation_map=(0, 2), + is_period_filtered=False, is_table_required=False, ), LoadItem( diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 2f3813ce5..6c6107e92 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -868,7 +868,7 @@ def load_param_idx_sets(self, data: dict[str, object]) -> dict[str, object]: model.limit_emission.name: model.limit_emission_constraint_rpe.name, model.limit_activity.name: model.limit_activity_constraint_rpt.name, model.limit_seasonal_capacity_factor.name: ( - model.limit_seasonal_capacity_factor_constraint_rpst.name + model.limit_seasonal_capacity_factor_constraint_rst.name ), model.limit_activity_share.name: model.limit_activity_share_constraint_rpgg.name, model.limit_annual_capacity_factor.name: ( @@ -881,7 +881,7 @@ def load_param_idx_sets(self, data: dict[str, object]) -> dict[str, object]: model.limit_new_capacity_share_constraint_rpgg.name ), model.limit_resource.name: model.limit_resource_constraint_rt.name, - model.limit_storage_fraction.name: model.limit_storage_fraction_constraint_rpsdtv.name, + model.limit_storage_fraction.name: model.limit_storage_fraction_param_rsdt.name, model.renewable_portfolio_standard.name: ( model.renewable_portfolio_standard_constraint_rpg.name ), diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 937bdbc36..66328d8ad 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -65,8 +65,6 @@ CREATE TABLE IF NOT EXISTS capacity_credit CREATE TABLE IF NOT EXISTS capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -76,14 +74,12 @@ CREATE TABLE IF NOT EXISTS capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -92,7 +88,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS capacity_to_activity @@ -217,8 +213,6 @@ CREATE TABLE IF NOT EXISTS demand CREATE TABLE IF NOT EXISTS demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -227,7 +221,7 @@ CREATE TABLE IF NOT EXISTS demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); CREATE TABLE IF NOT EXISTS end_of_life_output @@ -264,8 +258,6 @@ CREATE TABLE IF NOT EXISTS efficiency CREATE TABLE IF NOT EXISTS efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -280,7 +272,7 @@ CREATE TABLE IF NOT EXISTS efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE IF NOT EXISTS emission_activity @@ -475,21 +467,17 @@ CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity_delta CREATE TABLE IF NOT EXISTS limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE IF NOT EXISTS limit_activity ( @@ -600,8 +588,6 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -610,7 +596,7 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE IF NOT EXISTS limit_tech_input_split ( @@ -871,8 +857,6 @@ CREATE TABLE IF NOT EXISTS region CREATE TABLE IF NOT EXISTS reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -880,7 +864,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS time_segment_fraction diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 7b499daa6..b3c7f039a 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -15,8 +15,6 @@ CREATE TABLE capacity_credit CREATE TABLE capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -26,32 +24,24 @@ CREATE TABLE capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2000,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2000,0.2753,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2010,0.2756,''); -INSERT INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2000,0.2753,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2010,0.2756,''); +INSERT INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2010,0.2756,''); CREATE TABLE capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -60,99 +50,39 @@ CREATE TABLE capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E01',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E21',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E31',0.275,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E51',0.17,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E70',0.8,''); -INSERT INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E01',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E21',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E31',0.275,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E51',0.17,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','inter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','winter','night','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','day','E70',0.8,''); +INSERT INTO "capacity_factor_tech" VALUES('utopia','summer','night','E70',0.8,''); CREATE TABLE capacity_to_activity ( region TEXT, @@ -468,8 +398,6 @@ INSERT INTO "demand" VALUES('utopia',2010,'TX',11.69,'PJ',''); CREATE TABLE demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -478,39 +406,19 @@ CREATE TABLE demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RL',0.1,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RH',0.12,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RH',0.06,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RH',0.5467,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RH',0.2733,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','day','RL',0.15,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','night','RL',0.05,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RL',0.5,''); -INSERT INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RL',0.1,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RH',0.12,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RH',0.06,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RH',0.5467,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RH',0.2733,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','inter','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','day','RL',0.15,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','summer','night','RL',0.05,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','day','RL',0.5,''); +INSERT INTO "demand_specific_distribution" VALUES('utopia','winter','night','RL',0.1,''); CREATE TABLE efficiency ( region TEXT, @@ -595,8 +503,6 @@ INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',2010,'TX',0.231,'PJ / (PJ)' CREATE TABLE efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT @@ -611,7 +517,7 @@ CREATE TABLE efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE emission_activity @@ -979,8 +885,6 @@ CREATE TABLE limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -989,26 +893,22 @@ CREATE TABLE limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split ( @@ -1393,8 +1293,6 @@ INSERT INTO "region" VALUES('utopia',NULL); CREATE TABLE reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES season_label (season), tech TEXT @@ -1402,7 +1300,7 @@ CREATE TABLE reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE rps_requirement diff --git a/temoa/types/dict_types.py b/temoa/types/dict_types.py index e68176bfa..ba288ea98 100644 --- a/temoa/types/dict_types.py +++ b/temoa/types/dict_types.py @@ -65,8 +65,8 @@ # Switching/boolean flag dictionary types EfficiencyVariableDict = dict[ - tuple[Region, Period, Commodity, Technology, Vintage, Commodity], bool + tuple[Region, Commodity, Technology, Vintage, Commodity], bool ] -CapacityFactorProcessDict = dict[tuple[Region, Period, Technology, Vintage], bool] +CapacityFactorProcessDict = dict[tuple[Region, Technology, Vintage], bool] SeasonalStorageDict = dict[Technology, bool] SurvivalCurveProcessDict = dict[tuple[Region, Technology, Vintage], bool] diff --git a/tests/test_storage.py b/tests/test_storage.py index c62be9b8b..8449691a0 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -37,7 +37,7 @@ def test_storage_fraction(system_test_run: tuple[str, Any, TemoaModel, Any]) -> for r, p, s, d, t, v, op in model.limit_storage_fraction_constraint_rpsdtv: energy = ( - model.limit_storage_fraction[r, p, s, d, t, v, op] + model.limit_storage_fraction[r, s, d, t, op] * model.v_capacity[r, p, t, v].value # type: ignore [attr-defined] # I can't figure out how to get mypy to see value through the pyomo stubs * model.capacity_to_activity[r, t] * (model.storage_duration[r, t] / 8760) diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index b66d1a0b3..cbfdaa8b2 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -1,7 +1,7 @@ -REPLACE INTO "capacity_factor_tech" VALUES('Testregion',2000,'S1','TOD1','TechCurtailment',1.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('Testregion',2000,'S1','TOD2','TechCurtailment',0.5,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('Testregion',2000,'S1','TOD1','TechOrdinary',1.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('Testregion',2000,'S1','TOD2','TechOrdinary',0.5,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('Testregion','S1','TOD1','TechCurtailment',1.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('Testregion','S1','TOD2','TechCurtailment',0.5,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('Testregion','S1','TOD1','TechOrdinary',1.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('Testregion','S1','TOD2','TechOrdinary',0.5,NULL); REPLACE INTO "commodity" VALUES('annual_in', 's', NULL, NULL); REPLACE INTO "commodity" VALUES('flex_in', 's', NULL, NULL); REPLACE INTO "commodity" VALUES('ordinary_in', 's', NULL, NULL); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index 79ced1aaf..c7ac6f363 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -1,99 +1,35 @@ -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2000,'spring','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2010,'spring','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionA',2020,'spring','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2000,'spring','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2010,'spring','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'summer','morning','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'autumn','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'winter','morning','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'spring','morning','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'summer','afternoon','SOL_PV',0.3,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'autumn','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'winter','afternoon','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'spring','afternoon','SOL_PV',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'summer','evening','SOL_PV',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'autumn','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'winter','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'spring','evening','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'summer','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'autumn','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'winter','overnight','SOL_PV',0.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('regionB',2020,'spring','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','summer','morning','SOL_PV',0.3,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','autumn','morning','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','winter','morning','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','spring','morning','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','summer','afternoon','SOL_PV',0.3,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','autumn','afternoon','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','winter','afternoon','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','spring','afternoon','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','summer','evening','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','autumn','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','winter','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','spring','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','summer','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','autumn','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','winter','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionA','spring','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','summer','morning','SOL_PV',0.3,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','autumn','morning','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','winter','morning','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','spring','morning','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','summer','afternoon','SOL_PV',0.3,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','autumn','afternoon','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','winter','afternoon','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','spring','afternoon','SOL_PV',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','summer','evening','SOL_PV',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','autumn','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','winter','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','spring','evening','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','summer','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','autumn','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','winter','overnight','SOL_PV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('regionB','spring','overnight','SOL_PV',0.0,NULL); REPLACE INTO "commodity" VALUES('ethos', 's', 'import dummy source', NULL); REPLACE INTO "commodity" VALUES('electricity', 'p', 'grid electricity', NULL); REPLACE INTO "commodity" VALUES('passenger_km', 'd', 'demand for passenger km', NULL); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 33f405faa..7c7b80127 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -1,8 +1,8 @@ REPLACE INTO "capacity_credit" VALUES('A',2025,'EF',2025,0.6,NULL); -REPLACE INTO "capacity_factor_process" VALUES('A',2025,'s2','d1','EFL',2025,0.8,NULL); -REPLACE INTO "capacity_factor_process" VALUES('A',2025,'s1','d2','EFL',2025,0.9,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('A',2025,'s1','d1','EF',0.8,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('B',2025,'s2','d2','bulbs',0.75,NULL); +REPLACE INTO "capacity_factor_process" VALUES('A','s2','d1','EFL',2025,0.8,NULL); +REPLACE INTO "capacity_factor_process" VALUES('A','s1','d2','EFL',2025,0.9,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('A','s1','d1','EF',0.8,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('B','s2','d2','bulbs',0.75,NULL); REPLACE INTO "capacity_to_activity" VALUES('A', 'bulbs', 1.0, NULL, ''); REPLACE INTO "capacity_to_activity" VALUES('B', 'bulbs', 1.0, NULL, NULL); REPLACE INTO "commodity" VALUES('ELC', 'p', 'electricity', NULL); @@ -64,22 +64,22 @@ REPLACE INTO "demand" VALUES('A',2025,'RL',100.0,'',''); REPLACE INTO "demand" VALUES('B',2025,'RL',100.0,NULL,NULL); REPLACE INTO "demand" VALUES('A',2025,'RH',50.0,NULL,NULL); REPLACE INTO "demand" VALUES('B',2025,'RH',50.0,NULL,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s1','d1','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s1','d2','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s2','d1','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s2','d2','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s1','d1','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s1','d2','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s2','d1','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s2','d2','RL',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s1','d1','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s2','d1','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s1','d1','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s2','d1','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s1','d2','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('A',2025,'s2','d2','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s1','d2','RH',0.25,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('B',2025,'s2','d2','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s1','d1','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s1','d2','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s2','d1','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s2','d2','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s1','d1','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s1','d2','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s2','d1','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s2','d2','RL',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s1','d1','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s2','d1','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s1','d1','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s2','d1','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s1','d2','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('A','s2','d2','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s1','d2','RH',0.25,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('B','s2','d2','RH',0.25,NULL); REPLACE INTO "efficiency" VALUES('A', 'ELC', 'bulbs', 2025, 'RL', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('A', 'HYD', 'EH', 2025, 'ELC', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('A', 'HYD', 'EF', 2025, 'ELC', 1.0, NULL, NULL); diff --git a/tests/testing_data/mediumville_sets.json b/tests/testing_data/mediumville_sets.json index c174d5ca4..362dbc72b 100644 --- a/tests/testing_data/mediumville_sets.json +++ b/tests/testing_data/mediumville_sets.json @@ -655,507 +655,435 @@ 2025 ] ], - "capacity_factor_rpsdt": [ + "capacity_factor_rsdt": [ [ "A", - 2025, "s2", "d2", "bulbs" ], [ "B", - 2025, "s1", "d1", "well" ], [ "B", - 2025, "s2", "d1", "heater" ], [ "B", - 2025, "s2", "d1", "EH" ], [ "A", - 2025, "s1", "d2", "bulbs" ], [ "B", - 2025, "s1", "d2", "well" ], [ "B", - 2025, "s2", "d1", "EF" ], [ "B", - 2025, "s2", "d2", "EH" ], [ "B", - 2025, "s2", "d2", "EF" ], [ "B", - 2025, "s2", "d2", "heater" ], [ "A", - 2025, "s2", "d1", "well" ], [ "B", - 2025, "s1", "d1", "EH" ], [ "B", - 2025, "s1", "d1", "EF" ], [ "B", - 2025, "s1", "d1", "heater" ], [ "A", - 2025, "s1", "d1", "well" ], [ "B", - 2025, "s1", "d2", "heater" ], [ "B", - 2025, "s1", "d2", "EH" ], [ "A", - 2025, "s2", "d1", "heater" ], [ "B", - 2025, "s1", "d2", "EF" ], [ "A", - 2025, "s2", "d1", "EH" ], [ "A", - 2025, "s2", "d1", "EF" ], [ "B", - 2025, "s2", "d1", "GeoHeater" ], [ "B-A", - 2025, "s2", "d1", "FGF_pipe" ], [ "A", - 2025, "s1", "d1", "EH" ], [ "B", - 2025, "s2", "d2", "GeoHeater" ], [ "B-A", - 2025, "s2", "d2", "FGF_pipe" ], [ "A", - 2025, "s2", "d2", "well" ], [ "A", - 2025, "s1", "d1", "EF" ], [ "A", - 2025, "s1", "d1", "heater" ], [ "B", - 2025, "s1", "d1", "GeoHeater" ], [ "B-A", - 2025, "s1", "d1", "FGF_pipe" ], [ "B", - 2025, "s2", "d1", "GeoThermal" ], [ "A", - 2025, "s1", "d2", "well" ], [ "B-A", - 2025, "s1", "d2", "FGF_pipe" ], [ "A", - 2025, "s2", "d2", "heater" ], [ "B", - 2025, "s1", "d2", "GeoHeater" ], [ "A", - 2025, "s2", "d2", "EH" ], [ "B", - 2025, "s2", "d2", "GeoThermal" ], [ "A", - 2025, "s2", "d1", "GeoHeater" ], [ "A", - 2025, "s2", "d2", "EF" ], [ "A", - 2025, "s2", "d1", "EFL" ], [ "B", - 2025, "s1", "d1", "GeoThermal" ], [ "A", - 2025, "s1", "d2", "EH" ], [ "B", - 2025, "s1", "d2", "GeoThermal" ], [ "A", - 2025, "s1", "d1", "GeoHeater" ], [ "A", - 2025, "s1", "d2", "EF" ], [ "A", - 2025, "s2", "d1", "GeoThermal" ], [ "A", - 2025, "s1", "d1", "EFL" ], [ "A", - 2025, "s1", "d2", "heater" ], [ "B", - 2025, "s2", "d1", "bulbs" ], [ "B", - 2025, "s2", "d2", "bulbs" ], [ "B", - 2025, "s1", "d1", "bulbs" ], [ "A", - 2025, "s2", "d2", "GeoHeater" ], [ "A", - 2025, "s1", "d1", "GeoThermal" ], [ "A", - 2025, "s2", "d2", "EFL" ], [ "B", - 2025, "s2", "d1", "batt" ], [ "A-B", - 2025, "s2", "d2", "FGF_pipe" ], [ "B", - 2025, "s1", "d2", "bulbs" ], [ "A", - 2025, "s1", "d2", "GeoHeater" ], [ "A", - 2025, "s2", "d1", "bulbs" ], [ "A", - 2025, "s2", "d2", "GeoThermal" ], [ "A", - 2025, "s1", "d2", "EFL" ], [ "B", - 2025, "s1", "d1", "batt" ], [ "A-B", - 2025, "s1", "d2", "FGF_pipe" ], [ "B", - 2025, "s2", "d2", "batt" ], [ "A", - 2025, "s1", "d1", "bulbs" ], [ "A-B", - 2025, "s2", "d1", "FGF_pipe" ], [ "B", - 2025, "s1", "d2", "batt" ], [ "B", - 2025, "s2", "d1", "well" ], [ "A", - 2025, "s1", "d2", "GeoThermal" ], [ "A-B", - 2025, "s1", "d1", "FGF_pipe" ], [ "B", - 2025, "s2", "d2", "well" @@ -3373,7 +3301,9 @@ ] ], "limit_seasonal_capacity_factor_constraint_rpst": [], + "limit_seasonal_capacity_factor_constraint_rst": [], "limit_storage_fraction_constraint_rpsdtv": [], + "limit_storage_fraction_param_rsdt": [], "limit_tech_input_split_annual_constraint_rpitv": [], "limit_tech_input_split_average_constraint_rpitv": [], "limit_tech_input_split_constraint_rpsditv": [ diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index efe99dea9..0a61c71aa 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -1,11 +1,11 @@ -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'charge','a','generator',1.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'charge','b','generator',1.0,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'charge','c','generator',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'charge','d','generator',0.2,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'discharge','a','generator',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'discharge','b','generator',0.1,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'discharge','c','generator',0.01,NULL); -REPLACE INTO "capacity_factor_tech" VALUES('region',2000,'discharge','d','generator',0.01,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','charge','a','generator',1.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','charge','b','generator',1.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','charge','c','generator',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','charge','d','generator',0.2,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','discharge','a','generator',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','discharge','b','generator',0.1,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','discharge','c','generator',0.01,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('region','discharge','d','generator',0.01,NULL); REPLACE INTO "capacity_to_activity" VALUES('region', 'generator', 8760.0, NULL, 'MWh/MWy'); REPLACE INTO "capacity_to_activity" VALUES('region', 'dly_stor', 8760.0, NULL, 'MWh/MWy'); REPLACE INTO "capacity_to_activity" VALUES('region', 'seas_stor', 8760.0, NULL, 'MWh/MWy'); @@ -28,20 +28,20 @@ REPLACE INTO "cost_invest" VALUES('region','demand',2000,1.0,'',NULL); REPLACE INTO "cost_variable" VALUES('region',2000,'generator',2000,1.0,NULL,NULL); REPLACE INTO "cost_variable" VALUES('region',2000,'demand',2000,1.0,NULL,NULL); REPLACE INTO "demand" VALUES('region',2000,'demand',8760.0,'MWh',NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'charge','a','demand',0.0,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'charge','b','demand',0.05,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'charge','c','demand',0.05,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'charge','d','demand',0.1,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'discharge','a','demand',0.0,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'discharge','b','demand',0.2,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'discharge','c','demand',0.2,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('region',2000,'discharge','d','demand',0.4,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','charge','a','demand',0.0,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','charge','b','demand',0.05,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','charge','c','demand',0.05,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','charge','d','demand',0.1,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','discharge','a','demand',0.0,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','discharge','b','demand',0.2,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','discharge','c','demand',0.2,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('region','discharge','d','demand',0.4,NULL); REPLACE INTO "efficiency" VALUES('region', 'ethos', 'generator', 2000, 'electricity', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('region', 'electricity', 'dly_stor', 2000, 'electricity', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('region', 'electricity', 'seas_stor', 2000, 'electricity', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('region', 'electricity', 'demand', 2000, 'demand', 1.0, NULL, NULL); -REPLACE INTO "limit_storage_level_fraction" VALUES('region',2000,'winter','b','seas_stor',2000,'e',0.5,NULL); -REPLACE INTO "limit_storage_level_fraction" VALUES('region',2000,'charge','b','dly_stor',2000,'e',0.5,NULL); +REPLACE INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor','e',0.5,NULL); +REPLACE INTO "limit_storage_level_fraction" VALUES('region','charge','b','dly_stor','e',0.5,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 6f3bc10df..e98bf3966 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -19,16 +19,16 @@ REPLACE INTO "cost_invest" VALUES('electricville','batt',2025,1.0,NULL,NULL); REPLACE INTO "cost_variable" VALUES('electricville',2025,'EH',2025,1000.0,'',''); REPLACE INTO "cost_variable" VALUES('electricville',2025,'batt',2025,1.0,'',''); REPLACE INTO "demand" VALUES('electricville',2025,'RL',100.0,'',''); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s1','d1','RL',0.075,''); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s1','d2','RL',0.075,''); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s1','d3','RL',0.075,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s2','d1','RL',0.075,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s2','d2','RL',0.075,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s2','d3','RL',0.075,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s1','d4','RL',0.075,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s1','d5','RL',0.2,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s2','d4','RL',0.2,NULL); -REPLACE INTO "demand_specific_distribution" VALUES('electricville',2025,'s2','d5','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s1','d1','RL',0.075,''); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s1','d2','RL',0.075,''); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s1','d3','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s2','d1','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s2','d2','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s2','d3','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s1','d4','RL',0.075,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s1','d5','RL',0.2,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s2','d4','RL',0.2,NULL); +REPLACE INTO "demand_specific_distribution" VALUES('electricville','s2','d5','RL',0.075,NULL); REPLACE INTO "efficiency" VALUES('electricville', 'HYD', 'EH', 2025, 'ELC', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('electricville', 'ELC', 'bulbs', 2025, 'RL', 1.0, NULL, NULL); REPLACE INTO "efficiency" VALUES('electricville', 'earth', 'well', 2025, 'HYD', 1.0, NULL, 'water source'); @@ -40,7 +40,7 @@ REPLACE INTO "limit_capacity" VALUES('electricville',2025,'EH','ge',0.1,'',''); REPLACE INTO "limit_capacity" VALUES('electricville',2025,'batt','ge',0.1,'',''); REPLACE INTO "limit_capacity" VALUES('electricville',2025,'EH','le',200.0,'',''); REPLACE INTO "limit_capacity" VALUES('electricville',2025,'batt','le',100.0,'',''); -REPLACE INTO "limit_storage_level_fraction" VALUES('electricville',2025,'s1','d1','batt',2025,'e',0.5,NULL); +REPLACE INTO "limit_storage_level_fraction" VALUES('electricville','s1','d1','batt','e',0.5,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 6c5787321..0f49b84b5 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -1,51 +1,19 @@ -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'spring','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'summer','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'fall','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'winter','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2020,'winter','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'spring','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'summer','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'fall','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'winter','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2020,'winter','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'spring','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'summer','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'fall','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'winter','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2025,'winter','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'spring','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'summer','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'fall','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'winter','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2025,'winter','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'spring','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'summer','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'fall','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'winter','day','E_SOLPV',0.6,''); -REPLACE INTO "capacity_factor_tech" VALUES('R1',2030,'winter','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'spring','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'spring','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'summer','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'summer','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'fall','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'fall','night','E_SOLPV',0.0,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'winter','day','E_SOLPV',0.48,''); -REPLACE INTO "capacity_factor_tech" VALUES('R2',2030,'winter','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','spring','day','E_SOLPV',0.6,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','spring','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','summer','day','E_SOLPV',0.6,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','summer','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','fall','day','E_SOLPV',0.6,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','fall','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','winter','day','E_SOLPV',0.6,''); +REPLACE INTO "capacity_factor_tech" VALUES('R1','winter','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','spring','day','E_SOLPV',0.48,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','spring','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','summer','day','E_SOLPV',0.48,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','summer','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','fall','day','E_SOLPV',0.48,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','fall','night','E_SOLPV',0.0,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','winter','day','E_SOLPV',0.48,''); +REPLACE INTO "capacity_factor_tech" VALUES('R2','winter','night','E_SOLPV',0.0,''); REPLACE INTO "capacity_to_activity" VALUES('R1', 'S_IMPETH', 1.0, NULL, ''); REPLACE INTO "capacity_to_activity" VALUES('R1', 'S_IMPOIL', 1.0, NULL, ''); REPLACE INTO "capacity_to_activity" VALUES('R1', 'S_IMPNG', 1.0, NULL, ''); @@ -267,54 +235,22 @@ REPLACE INTO "demand" VALUES('R2',2030,'RH',84.0,'',''); REPLACE INTO "demand" VALUES('R2',2020,'VMT',36.0,'',''); REPLACE INTO "demand" VALUES('R2',2025,'VMT',39.0,'',''); REPLACE INTO "demand" VALUES('R2',2030,'VMT',42.0,'',''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2020,'winter','night','RH',0.4,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2020,'winter','night','RH',0.4,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2025,'winter','night','RH',0.4,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2025,'winter','night','RH',0.4,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R1',2030,'winter','night','RH',0.4,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'spring','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'spring','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'summer','day','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'summer','night','RH',0.0,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'fall','day','RH',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'fall','night','RH',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'winter','day','RH',0.3,''); -REPLACE INTO "demand_specific_distribution" VALUES('R2',2030,'winter','night','RH',0.4,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','spring','day','RH',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','spring','night','RH',0.1,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','summer','day','RH',0.0,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','summer','night','RH',0.0,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','fall','day','RH',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','fall','night','RH',0.1,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','winter','day','RH',0.3,''); +REPLACE INTO "demand_specific_distribution" VALUES('R1','winter','night','RH',0.4,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','spring','day','RH',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','spring','night','RH',0.1,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','summer','day','RH',0.0,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','summer','night','RH',0.0,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','fall','day','RH',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','fall','night','RH',0.1,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','winter','day','RH',0.3,''); +REPLACE INTO "demand_specific_distribution" VALUES('R2','winter','night','RH',0.4,''); REPLACE INTO "efficiency" VALUES('R1', 'ethos', 'S_IMPETH', 2020, 'ETH', 1.0, NULL, ''); REPLACE INTO "efficiency" VALUES('R1', 'ethos', 'S_IMPOIL', 2020, 'OIL', 1.0, NULL, ''); REPLACE INTO "efficiency" VALUES('R1', 'ethos', 'S_IMPNG', 2020, 'NG', 1.0, NULL, ''); @@ -443,8 +379,8 @@ REPLACE INTO "limit_emission" VALUES('R1',2030,'CO2','le',23000.0,'kT CO2',''); REPLACE INTO "limit_emission" VALUES('global',2020,'CO2','le',37500.0,'kT CO2',''); REPLACE INTO "limit_emission" VALUES('global',2025,'CO2','le',36000.0,'kT CO2',''); REPLACE INTO "limit_emission" VALUES('global',2030,'CO2','le',34500.0,'kT CO2',''); -REPLACE INTO "limit_storage_level_fraction" VALUES('R1',2025,'winter','day','E_BATT',2025,'e',0.5,''); -REPLACE INTO "limit_storage_level_fraction" VALUES('R2',2020,'summer','day','E_BATT',2020,'e',0.5,''); +REPLACE INTO "limit_storage_level_fraction" VALUES('R1','winter','day','E_BATT','e',0.5,''); +REPLACE INTO "limit_storage_level_fraction" VALUES('R2','summer','day','E_BATT','e',0.5,''); REPLACE INTO "limit_tech_input_split" VALUES('R1',2020,'GSL','T_BLND','ge',0.9,''); REPLACE INTO "limit_tech_input_split" VALUES('R1',2020,'ETH','T_BLND','ge',0.1,''); REPLACE INTO "limit_tech_input_split" VALUES('R1',2025,'GSL','T_BLND','ge',0.9,''); diff --git a/tests/testing_data/test_system_sets.json b/tests/testing_data/test_system_sets.json index d5d02b8d4..e631dff29 100644 --- a/tests/testing_data/test_system_sets.json +++ b/tests/testing_data/test_system_sets.json @@ -9237,4038 +9237,1158 @@ 2015 ] ], - "capacity_factor_rpsdt": [ + "capacity_factor_rsdt": [ [ "R1", - 2020, "winter", "night", "E_NUCLEAR" ], [ "R2", - 2030, "spring", "night", "E_SOLPV" ], [ "R1", - 2030, "fall", "night", "T_EV" ], [ "R1", - 2020, "fall", "day", "E_NGCC" ], [ "R2", - 2025, "winter", "day", "R_EH" ], [ "R1", - 2025, "fall", "day", "T_DSL" ], [ "R2", - 2030, "fall", "night", "R_NGH" ], [ "R1", - 2030, "summer", "night", "T_EV" ], [ "R2", - 2030, "fall", "night", "E_NUCLEAR" ], [ "R2-R1", - 2030, "spring", "day", "E_TRANS" ], [ "R2", - 2025, "spring", "night", "T_EV" ], [ "R2", - 2030, "spring", "day", "T_EV" ], [ "R1", - 2025, "fall", "day", "S_OILREF" ], [ "R1", - 2030, "fall", "night", "T_DSL" ], [ "R2", - 2030, "spring", "night", "R_EH" ], [ "R1", - 2030, "summer", "night", "T_DSL" ], [ "R1", - 2020, "summer", "night", "R_NGH" ], [ "R2", - 2020, "winter", "day", "E_BATT" ], [ "R2", - 2020, "winter", "day", "T_BLND" ], [ "R2", - 2030, "spring", "day", "T_DSL" ], [ "R1", - 2030, "fall", "night", "S_OILREF" ], [ "R1", - 2030, "summer", "night", "S_OILREF" ], [ "R2-R1", - 2030, "winter", "night", "E_TRANS" ], [ "R1-R2", - 2020, "spring", "night", "E_TRANS" ], [ "R2", - 2025, "spring", "night", "S_OILREF" ], [ "R1", - 2020, - "fall", - "night", - "T_EV" - ], - [ - "R1", - 2025, "spring", "day", "E_SOLPV" ], [ "R2", - 2025, "winter", "night", "E_BATT" ], [ "R2", - 2025, "winter", "night", "T_BLND" ], [ "R2", - 2030, "spring", "day", "S_OILREF" ], [ "R1", - 2020, "winter", "night", "E_SOLPV" ], [ "R2", - 2025, "summer", "day", "R_EH" ], [ "R1", - 2020, "spring", "night", "R_NGH" ], [ "R2-R1", - 2020, "fall", "day", "E_TRANS" ], [ "R1", - 2020, "spring", "night", "E_NUCLEAR" ], [ "R2", - 2030, - "winter", - "day", - "E_BATT" - ], - [ - "R2", - 2030, - "winter", - "day", - "T_BLND" - ], - [ - "R2", - 2030, "fall", "day", "T_GSL" ], [ "R2", - 2025, "spring", "day", "T_GSL" ], [ "R2", - 2020, "winter", "night", "T_GSL" ], [ "R2", - 2030, "winter", "night", "E_NGCC" ], [ "R1", - 2030, "spring", "night", "E_SOLPV" ], [ "R1", - 2025, "summer", "night", "T_BLND" ], [ "R1", - 2020, "winter", "day", "R_NGH" ], [ "R1", - 2025, "summer", "day", "E_BATT" ], [ "R1", - 2025, "summer", "day", "T_BLND" ], [ "R1", - 2020, "winter", "day", "E_NUCLEAR" ], [ "R2", - 2020, "spring", "night", "E_BATT" ], [ "R2", - 2020, "spring", "night", "T_BLND" ], [ "R1", - 2025, "spring", "day", "R_EH" ], [ "R2-R1", - 2025, "fall", "night", "E_TRANS" ], [ "R2", - 2030, "fall", "night", "T_EV" ], [ "R1", - 2020, "winter", "night", "R_EH" ], [ "R1", - 2025, "summer", "night", "E_NGCC" ], [ "R1", - 2020, - "fall", - "night", - "S_OILREF" - ], - [ - "R1", - 2030, "spring", "day", "R_NGH" ], [ "R2", - 2020, "spring", "night", "E_NGCC" ], [ "R1", - 2020, "summer", "day", "T_GSL" ], [ "R1", - 2030, "spring", "day", "E_NUCLEAR" ], [ "R1", - 2025, "winter", "night", "R_NGH" ], [ "R1", - 2020, "winter", "night", "T_DSL" ], - [ - "R2-R1", - 2020, - "winter", - "night", - "E_TRANS" - ], - [ - "R1", - 2025, - "winter", - "night", - "E_NUCLEAR" - ], [ "R1", - 2030, "spring", "night", "R_EH" ], [ "R1", - 2020, "fall", "day", "T_GSL" ], - [ - "R1", - 2020, - "summer", - "night", - "T_EV" - ], [ "R2", - 2030, "summer", "night", "T_BLND" ], [ "R1", - 2030, "spring", "night", "T_DSL" ], - [ - "R1", - 2020, - "spring", - "night", - "E_SOLPV" - ], - [ - "R1", - 2030, - "fall", - "day", - "S_OILREF" - ], [ "R2", - 2030, "fall", "night", "S_OILREF" ], [ "R2", - 2025, "fall", "night", "T_BLND" ], [ "R2", - 2025, "fall", "night", "E_BATT" ], [ "R2", - 2030, "summer", "night", "E_NGCC" ], [ "R1", - 2025, "winter", "day", "E_NGCC" ], [ "R1-R2", - 2020, "winter", "day", "E_TRANS" ], [ "R1", - 2020, "spring", "night", "T_EV" ], [ "R1", - 2020, - "spring", - "day", - "R_NGH" - ], - [ - "R1", - 2020, - "spring", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2030, "winter", "night", "E_NGCC" ], - [ - "R2-R1", - 2020, - "spring", - "day", - "E_TRANS" - ], - [ - "R1", - 2020, - "spring", - "night", - "R_EH" - ], [ "R1", - 2020, - "summer", - "night", - "S_OILREF" - ], - [ - "R1", - 2020, "winter", "day", "T_EV" ], - [ - "R1", - 2030, - "spring", - "day", - "E_SOLPV" - ], [ "R2", - 2020, "spring", "day", "E_BATT" ], [ "R1", - 2020, - "spring", - "night", - "T_DSL" - ], - [ - "R1", - 2025, "fall", "night", "R_NGH" ], [ "R1", - 2025, "fall", "night", "E_NUCLEAR" ], [ "R1", - 2030, "spring", "day", "T_EV" ], [ "R2-R1", - 2025, "spring", "night", "E_TRANS" ], [ "R2", - 2020, "fall", "night", "E_SOLPV" ], [ "R2", - 2020, "summer", "day", "R_NGH" ], [ "R1", - 2025, "winter", "night", "T_EV" ], [ "R2", - 2020, "summer", "day", "E_NUCLEAR" ], [ "R1", - 2020, "winter", "day", "T_DSL" ], - [ - "R2", - 2030, - "winter", - "night", - "T_GSL" - ], [ "R1-R2", - 2025, "summer", "day", "E_TRANS" ], [ "R2", - 2025, "summer", "night", "E_BATT" ], [ "R2", - 2025, - "summer", - "night", - "T_BLND" - ], - [ - "R2", - 2020, "fall", "day", "R_NGH" ], [ "R1", - 2025, "summer", "night", "T_GSL" ], [ "R2", - 2020, "fall", "day", "E_NUCLEAR" ], [ "R2", - 2030, "summer", "day", "E_BATT" ], [ "R1", - 2020, "winter", "day", "S_OILREF" ], [ "R2", - 2030, "summer", "day", "T_BLND" ], [ "R1", - 2030, "spring", "day", "T_DSL" ], [ "R2", - 2020, "spring", "night", "T_GSL" ], - [ - "R1", - 2025, - "fall", - "day", - "E_NGCC" - ], [ "R2", - 2020, "fall", "night", "R_EH" ], [ "R2", - 2020, "fall", "night", "T_DSL" ], [ "R1", - 2030, - "summer", - "day", - "E_BATT" - ], - [ - "R1", - 2030, - "summer", - "day", - "T_BLND" - ], - [ - "R1", - 2030, "spring", "day", "S_OILREF" ], - [ - "R2", - 2025, - "spring", - "night", - "T_BLND" - ], [ "R1", - 2025, "winter", "night", "S_OILREF" ], [ "R1", - 2030, "winter", "day", "E_BATT" ], [ "R1", - 2030, "winter", "day", "T_BLND" ], [ "R1", - 2030, "fall", "night", "E_NGCC" ], - [ - "R1", - 2020, - "spring", - "day", - "T_EV" - ], - [ - "R1", - 2030, - "summer", - "night", - "E_NGCC" - ], - [ - "R2", - 2025, - "spring", - "night", - "E_NGCC" - ], [ "R2", - 2030, "summer", "night", "T_GSL" ], [ "R1", - 2025, "winter", "day", "T_GSL" ], [ "R2", - 2030, "spring", "day", "E_NGCC" ], [ "R2", - 2020, "summer", "night", "E_SOLPV" ], [ "R2", - 2025, "winter", "night", "E_SOLPV" ], - [ - "R1-R2", - 2025, - "winter", - "day", - "E_TRANS" - ], - [ - "R1", - 2025, - "fall", - "night", - "T_EV" - ], - [ - "R2", - 2020, - "winter", - "day", - "R_EH" - ], - [ - "R2-R1", - 2025, - "spring", - "day", - "E_TRANS" - ], [ "R2", - 2020, "fall", "day", "E_SOLPV" ], [ "R1", - 2030, "winter", "night", "T_GSL" ], [ "R2", - 2020, "summer", "day", "T_EV" ], [ "R1", - 2020, "fall", "night", "T_BLND" ], - [ - "R1", - 2025, - "spring", - "night", - "E_NUCLEAR" - ], [ "R2", - 2025, "winter", "day", "R_NGH" ], [ "R2", - 2025, "winter", "day", "E_NUCLEAR" ], [ "R1", - 2025, "summer", "day", "E_SOLPV" ], - [ - "R1", - 2020, - "spring", - "day", - "S_OILREF" - ], [ "R2", - 2020, "summer", "night", "R_EH" ], - [ - "R1", - 2020, - "fall", - "night", - "E_NGCC" - ], [ "R2", - 2025, "winter", "night", "R_EH" ], - [ - "R1", - 2025, - "fall", - "night", - "T_DSL" - ], [ "R2", - 2020, "fall", "day", "T_EV" ], [ "R2", - 2020, "summer", "night", "T_DSL" ], - [ - "R2-R1", - 2030, - "spring", - "night", - "E_TRANS" - ], - [ - "R2", - 2030, - "winter", - "day", - "R_EH" - ], [ "R2", - 2030, "spring", "night", "R_NGH" ], [ "R2", - 2030, "spring", "night", "E_NUCLEAR" ], - [ - "R1", - 2025, - "fall", - "night", - "S_OILREF" - ], [ "R1-R2", - 2030, - "summer", - "night", - "E_TRANS" - ], - [ - "R1", - 2030, - "fall", - "day", - "E_BATT" - ], - [ - "R1", - 2030, - "fall", - "day", - "T_BLND" - ], - [ - "R2", - 2030, - "fall", - "night", - "T_BLND" - ], - [ - "R1", - 2025, - "summer", - "day", - "R_EH" - ], - [ - "R2", - 2030, - "fall", - "day", - "E_BATT" - ], - [ - "R2", - 2020, - "fall", - "day", - "T_DSL" - ], - [ - "R2", - 2020, "summer", - "day", - "S_OILREF" - ], - [ - "R2", - 2025, - "spring", - "day", - "T_BLND" - ], - [ - "R2", - 2025, - "spring", - "day", - "E_BATT" - ], - [ - "R2", - 2020, - "winter", - "night", - "E_BATT" - ], - [ - "R2", - 2030, - "fall", "night", - "E_NGCC" - ], - [ - "R1", - 2025, - "fall", - "day", - "T_GSL" - ], - [ - "R1-R2", - 2030, - "fall", - "day", "E_TRANS" ], - [ - "R2", - 2025, - "summer", - "day", - "R_NGH" - ], - [ - "R2", - 2020, - "fall", - "day", - "S_OILREF" - ], - [ - "R2", - 2025, - "summer", - "day", - "E_NUCLEAR" - ], [ "R1", - 2020, - "summer", - "night", - "E_BATT" - ], - [ - "R1", - 2025, - "spring", - "night", - "E_SOLPV" - ], - [ - "R1", - 2020, - "summer", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "winter", - "day", - "E_SOLPV" - ], - [ - "R1", - 2030, "fall", - "night", - "T_GSL" - ], - [ - "R2", - 2025, - "fall", - "day", - "R_NGH" - ], - [ - "R1", - 2030, - "summer", - "night", - "T_GSL" - ], - [ - "R2", - 2025, - "fall", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "summer", - "night", - "E_NGCC" - ], - [ - "R2", - 2025, - "spring", - "night", - "T_GSL" - ], - [ - "R1", - 2025, - "spring", - "day", - "R_NGH" - ], - [ - "R1", - 2020, - "fall", - "day", - "E_BATT" - ], - [ - "R1", - 2020, - "fall", - "day", - "T_BLND" - ], - [ - "R2", - 2025, - "winter", - "day", - "T_EV" - ], - [ - "R2", - 2025, - "fall", - "night", - "R_EH" - ], - [ - "R1", - 2025, - "spring", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2030, - "spring", - "day", - "T_GSL" - ], - [ - "R1", - 2020, - "winter", - "night", - "R_NGH" - ], - [ - "R2", - 2020, - "spring", - "day", - "E_SOLPV" - ], - [ - "R1", - 2025, - "spring", - "night", - "R_EH" - ], - [ - "R1", - 2030, - "spring", - "night", - "R_NGH" - ], - [ - "R1", - 2025, - "spring", - "night", - "T_DSL" - ], - [ - "R1", - 2030, - "spring", - "night", - "E_NUCLEAR" - ], - [ - "R2", - 2025, - "winter", - "day", - "T_DSL" - ], - [ - "R2", - 2030, - "spring", - "night", - "T_EV" - ], - [ - "R1", - 2020, - "winter", - "day", - "T_BLND" - ], - [ - "R2", - 2025, - "summer", - "night", - "E_SOLPV" - ], - [ - "R1", - 2020, - "winter", - "day", - "E_NGCC" - ], - [ - "R2", - 2020, - "spring", - "day", - "R_EH" - ], - [ - "R1", - 2020, - "fall", - "night", - "T_GSL" - ], - [ - "R2", - 2025, - "summer", - "day", - "E_SOLPV" - ], - [ - "R1-R2", - 2030, - "winter", - "day", - "E_TRANS" - ], - [ - "R2", - 2025, - "winter", - "day", - "S_OILREF" - ], - [ - "R1", - 2025, - "winter", - "night", - "E_BATT" - ], - [ - "R1", - 2025, - "winter", - "night", - "T_BLND" - ], - [ - "R2", - 2020, - "spring", - "day", - "T_DSL" - ], - [ - "R2", - 2030, - "spring", - "night", - "T_DSL" - ], - [ - "R1", - 2030, - "spring", - "day", - "E_NGCC" - ], - [ - "R2", - 2025, - "fall", - "day", - "E_SOLPV" - ], - [ - "R2", - 2025, - "summer", - "day", - "T_EV" - ], - [ - "R1", - 2025, - "winter", - "night", - "E_NGCC" - ], - [ - "R2", - 2025, - "summer", - "night", - "R_EH" - ], - [ - "R2", - 2030, - "spring", - "night", - "S_OILREF" - ], - [ - "R1", - 2030, - "fall", - "day", - "T_GSL" - ], - [ - "R2", - 2030, - "winter", - "night", - "E_BATT" - ], - [ - "R2", - 2030, - "winter", - "night", - "T_BLND" - ], - [ - "R2", - 2030, - "fall", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "summer", - "day", - "R_EH" - ], - [ - "R2", - 2025, - "fall", - "day", - "T_EV" - ], - [ - "R2", - 2025, - "summer", - "day", - "T_DSL" - ], - [ - "R2-R1", - 2020, - "spring", - "night", - "E_TRANS" - ], - [ - "R1", - 2025, - "spring", - "day", - "T_EV" - ], - [ - "R2", - 2025, - "fall", - "day", - "R_EH" - ], - [ - "R1", - 2025, - "summer", - "night", - "E_BATT" - ], - [ - "R1", - 2020, - "winter", - "night", - "T_EV" - ], - [ - "R1", - 2030, - "summer", - "day", - "R_EH" - ], - [ - "R1", - 2020, - "spring", - "day", - "T_BLND" - ], - [ - "R2", - 2025, - "fall", - "day", - "T_DSL" - ], - [ - "R1-R2", - 2020, - "summer", - "day", - "E_TRANS" - ], - [ - "R1", - 2030, - "winter", - "day", - "R_EH" - ], - [ - "R2", - 2025, - "summer", - "day", - "S_OILREF" - ], - [ - "R1", - 2020, - "summer", - "night", - "T_GSL" - ], - [ - "R1", - 2030, - "spring", - "night", - "T_EV" - ], - [ - "R1", - 2020, - "spring", - "day", - "E_NGCC" - ], - [ - "R1", - 2025, - "spring", - "day", - "T_DSL" - ], - [ - "R1-R2", - 2020, - "fall", - "day", - "E_TRANS" - ], - [ - "R1", - 2025, - "fall", - "night", - "T_BLND" - ], - [ - "R2", - 2020, - "fall", - "night", - "R_NGH" - ], - [ - "R1", - 2025, - "spring", - "day", - "S_OILREF" - ], - [ - "R2", - 2020, - "fall", - "night", - "E_NUCLEAR" - ], - [ - "R2", - 2020, - "summer", - "day", - "T_BLND" - ], - [ - "R1", - 2020, - "winter", - "night", - "S_OILREF" - ], - [ - "R2", - 2030, - "summer", - "night", - "E_BATT" - ], - [ - "R1", - 2025, - "winter", - "day", - "E_BATT" - ], - [ - "R1", - 2025, - "winter", - "day", - "T_BLND" - ], - [ - "R1", - 2025, - "fall", - "night", - "E_NGCC" - ], - [ - "R1-R2", - 2025, - "fall", - "night", - "E_TRANS" - ], - [ - "R2", - 2020, - "summer", - "day", - "E_NGCC" - ], - [ - "R2", - 2030, - "fall", - "day", - "E_SOLPV" - ], - [ - "R1", - 2020, - "winter", - "day", - "T_GSL" - ], - [ - "R1", - 2030, - "spring", - "night", - "S_OILREF" - ], - [ - "R1-R2", - 2020, - "winter", - "night", - "E_TRANS" - ], - [ - "R2", - 2020, - "winter", - "night", - "E_SOLPV" - ], - [ - "R1", - 2030, - "winter", - "night", - "E_BATT" - ], - [ - "R1", - 2030, - "winter", - "night", - "T_BLND" - ], - [ - "R2", - 2020, - "fall", - "day", - "E_NGCC" - ], - [ - "R1", - 2030, - "spring", - "day", - "T_GSL" - ], - [ - "R2-R1", - 2030, - "summer", - "day", - "E_TRANS" - ], - [ - "R1", - 2025, - "winter", - "night", - "T_GSL" - ], - [ - "R2", - 2020, - "winter", - "day", - "R_NGH" - ], - [ - "R2", - 2020, - "winter", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "summer", - "day", - "E_SOLPV" - ], - [ - "R2", - 2030, - "fall", - "day", - "R_EH" - ], - [ - "R2", - 2025, - "spring", - "day", - "R_EH" - ], - [ - "R2", - 2020, - "winter", - "night", - "R_EH" - ], - [ - "R2", - 2020, - "summer", - "night", - "R_NGH" - ], - [ - "R2", - 2020, - "summer", - "night", - "E_NUCLEAR" - ], - [ - "R2", - 2025, - "winter", - "night", - "R_NGH" - ], - [ - "R2-R1", - 2020, - "summer", - "night", - "E_TRANS" - ], - [ - "R2", - 2020, - "winter", - "night", - "T_DSL" - ], - [ - "R2", - 2025, - "winter", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "spring", - "night", - "S_OILREF" - ], - [ - "R2", - 2030, - "winter", - "day", - "R_NGH" - ], - [ - "R1-R2", - 2025, - "summer", - "night", - "E_TRANS" - ], - [ - "R1", - 2025, - "fall", - "day", - "E_BATT" - ], - [ - "R2", - 2030, - "winter", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2025, - "fall", - "day", - "T_BLND" - ], - [ - "R1", - 2020, - "summer", - "day", - "R_EH" - ], - [ - "R2", - 2020, - "fall", - "night", - "T_EV" - ], - [ - "R1", - 2025, - "summer", - "day", - "R_NGH" - ], - [ - "R1", - 2020, - "summer", - "day", - "T_DSL" - ], - [ - "R1", - 2020, - "spring", - "day", - "T_GSL" - ], - [ - "R1", - 2025, - "summer", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2020, - "spring", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "fall", - "day", - "R_EH" - ], - [ - "R1-R2", - 2025, - "fall", - "day", - "E_TRANS" - ], - [ - "R1", - 2030, - "fall", - "night", - "E_BATT" - ], - [ - "R1", - 2030, - "fall", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "winter", - "day", - "E_NGCC" - ], - [ - "R1", - 2030, - "summer", - "night", - "E_BATT" - ], - [ - "R1", - 2030, - "summer", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "spring", - "night", - "E_BATT" - ], - [ - "R2", - 2020, - "winter", - "day", - "E_SOLPV" - ], - [ - "R2", - 2030, - "spring", - "night", - "T_BLND" - ], - [ - "R2", - 2030, - "spring", - "day", - "E_BATT" - ], - [ - "R1", - 2025, - "fall", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "spring", - "day", - "T_BLND" - ], - [ - "R1-R2", - 2030, - "fall", - "night", - "E_TRANS" - ], - [ - "R2", - 2020, - "fall", - "night", - "S_OILREF" - ], - [ - "R2", - 2030, - "spring", - "night", - "E_NGCC" - ], - [ - "R2", - 2020, - "summer", - "day", - "T_GSL" - ], - [ - "R2", - 2020, - "winter", - "day", - "T_EV" - ], - [ - "R1-R2", - 2025, - "winter", - "night", - "E_TRANS" - ], - [ - "R2", - 2030, - "winter", - "night", - "E_SOLPV" - ], - [ - "R2", - 2025, - "fall", - "night", - "R_NGH" - ], - [ - "R2", - 2030, - "winter", - "day", - "E_SOLPV" - ], - [ - "R2", - 2020, - "fall", - "day", - "T_GSL" - ], - [ - "R2", - 2025, - "fall", - "night", - "E_NUCLEAR" - ], - [ - "R2", - 2020, - "summer", - "night", - "T_EV" - ], - [ - "R1", - 2025, - "spring", - "night", - "R_NGH" - ], - [ - "R1", - 2020, - "fall", - "night", - "E_BATT" - ], - [ - "R2", - 2025, - "winter", - "night", - "T_EV" - ], - [ - "R1", - 2025, - "summer", - "night", - "E_SOLPV" - ], - [ - "R2-R1", - 2020, - "summer", - "day", - "E_TRANS" - ], - [ - "R2", - 2020, - "winter", - "day", - "T_DSL" - ], - [ - "R2-R1", - 2025, - "winter", - "day", - "E_TRANS" - ], - [ - "R2", - 2025, - "summer", - "day", - "E_NGCC" - ], - [ - "R2", - 2020, - "spring", - "night", - "E_SOLPV" - ], - [ - "R2", - 2030, - "winter", - "day", - "T_EV" - ], - [ - "R2", - 2030, - "winter", - "night", - "R_EH" - ], - [ - "R1", - 2025, - "spring", - "day", - "T_BLND" - ], - [ - "R2", - 2020, - "winter", - "day", - "S_OILREF" - ], - [ - "R1", - 2025, - "summer", - "day", - "T_EV" - ], - [ - "R2", - 2025, - "fall", - "day", - "E_NGCC" - ], - [ - "R1", - 2020, - "winter", - "night", - "E_BATT" - ], - [ - "R1", - 2020, - "winter", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "winter", - "night", - "T_DSL" - ], - [ - "R2", - 2020, - "spring", - "day", - "R_NGH" - ], - [ - "R2", - 2020, - "spring", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2030, - "winter", - "day", - "T_DSL" - ], - [ - "R1", - 2025, - "summer", - "night", - "R_EH" - ], - [ - "R1", - 2025, - "spring", - "day", - "E_NGCC" - ], - [ - "R2", - 2030, - "fall", - "night", - "E_BATT" - ], - [ - "R1", - 2020, - "winter", - "night", - "E_NGCC" - ], - [ - "R2", - 2020, - "spring", - "night", - "R_EH" - ], - [ - "R2", - 2020, - "summer", - "night", - "S_OILREF" - ], - [ - "R1-R2", - 2025, - "spring", - "day", - "E_TRANS" - ], - [ - "R1", - 2030, - "spring", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "winter", - "night", - "S_OILREF" - ], - [ - "R2", - 2030, - "summer", - "night", - "E_SOLPV" - ], - [ - "R1", - 2025, - "summer", - "day", - "T_DSL" - ], - [ - "R2", - 2020, - "spring", - "night", - "T_DSL" - ], - [ - "R2", - 2030, - "winter", - "day", - "S_OILREF" - ], - [ - "R2", - 2025, - "summer", - "night", - "R_NGH" - ], - [ - "R1", - 2030, - "spring", - "night", - "E_NGCC" - ], - [ - "R2", - 2025, - "fall", - "night", - "E_SOLPV" - ], - [ - "R2", - 2025, - "summer", - "night", - "E_NUCLEAR" - ], - [ - "R1-R2", - 2030, - "spring", - "night", - "E_TRANS" - ], - [ - "R2", - 2025, - "winter", - "day", - "T_GSL" - ], - [ - "R2", - 2030, - "summer", - "day", - "R_NGH" - ], - [ - "R1", - 2025, - "summer", - "day", - "S_OILREF" - ], - [ - "R2", - 2030, - "summer", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2030, - "winter", - "night", - "E_SOLPV" - ], - [ - "R2-R1", - 2030, - "fall", - "day", - "E_TRANS" - ], - [ - "R2", - 2025, - "fall", - "night", - "T_EV" - ], - [ - "R2", - 2030, - "summer", - "night", - "R_EH" - ], - [ - "R1", - 2025, - "winter", - "day", - "R_EH" - ], - [ - "R1", - 2030, - "summer", - "day", - "R_NGH" - ], - [ - "R1", - 2030, - "summer", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2025, - "spring", - "night", - "T_EV" - ], - [ - "R2", - 2030, - "spring", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "summer", - "night", - "T_DSL" - ], - [ - "R1", - 2030, - "winter", - "day", - "R_NGH" - ], - [ - "R1", - 2030, - "winter", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "spring", - "night", - "E_BATT" - ], - [ - "R1", - 2020, - "spring", - "night", - "T_BLND" - ], - [ - "R2", - 2025, - "fall", - "night", - "T_DSL" - ], - [ - "R1", - 2030, - "winter", - "night", - "R_EH" - ], - [ - "R1", - 2020, - "spring", - "night", - "E_NGCC" - ], - [ - "R1", - 2020, - "winter", - "day", - "E_BATT" - ], - [ - "R2", - 2020, - "spring", - "day", - "T_EV" - ], - [ - "R1-R2", - 2020, - "fall", - "night", - "E_TRANS" - ], - [ - "R2", - 2025, - "fall", - "night", - "S_OILREF" - ], - [ - "R2", - 2025, - "summer", - "day", - "T_GSL" - ], - [ - "R1-R2", - 2030, - "winter", - "night", - "E_TRANS" - ], - [ - "R1", - 2025, - "spring", - "night", - "S_OILREF" - ], - [ - "R1", - 2030, - "spring", - "day", - "E_BATT" - ], - [ - "R1", - 2030, - "spring", - "day", - "T_BLND" - ], - [ - "R2", - 2030, - "summer", - "day", - "E_SOLPV" - ], - [ - "R2", - 2025, - "summer", - "night", - "T_EV" - ], - [ - "R1", - 2025, - "spring", - "day", - "T_GSL" - ], - [ - "R2-R1", - 2025, - "summer", - "day", - "E_TRANS" - ], - [ - "R2", - 2020, - "fall", - "night", - "T_BLND" - ], - [ - "R2", - 2030, - "summer", - "day", - "T_EV" - ], - [ - "R1-R2", - 2030, - "spring", - "day", - "E_TRANS" - ], - [ - "R1", - 2030, - "summer", - "day", - "E_SOLPV" - ], - [ - "R1", - 2020, - "winter", - "night", - "T_GSL" - ], - [ - "R2-R1", - 2030, - "winter", - "day", - "E_TRANS" - ], - [ - "R2", - 2025, - "spring", - "night", - "E_SOLPV" - ], - [ - "R1", - 2025, - "fall", - "day", - "R_EH" - ], - [ - "R2", - 2020, - "spring", - "day", - "S_OILREF" - ], - [ - "R1", - 2030, - "winter", - "day", - "E_SOLPV" - ], - [ - "R2", - 2030, - "spring", - "day", - "E_SOLPV" - ], - [ - "R1", - 2030, - "fall", - "day", - "R_NGH" - ], - [ - "R2", - 2020, - "fall", - "night", - "E_NGCC" - ], - [ - "R1", - 2030, - "fall", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2025, - "summer", - "night", - "T_DSL" - ], - [ - "R2", - 2030, - "fall", - "day", - "R_NGH" - ], - [ - "R1", - 2030, - "summer", - "day", - "T_EV" - ], - [ - "R1", - 2030, - "spring", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "fall", - "day", - "E_NUCLEAR" - ], - [ - "R2-R1", - 2030, - "summer", - "night", - "E_TRANS" - ], - [ - "R2", - 2025, - "spring", - "day", - "R_NGH" - ], - [ - "R2", - 2025, - "spring", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2030, - "winter", - "day", - "T_EV" - ], - [ - "R1", - 2030, - "fall", - "night", - "R_EH" - ], - [ - "R2", - 2020, - "winter", - "night", - "R_NGH" - ], - [ - "R2", - 2030, - "summer", - "day", - "T_DSL" - ], - [ - "R2", - 2020, - "winter", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2030, - "summer", - "night", - "R_EH" - ], - [ - "R1", - 2020, - "spring", - "day", - "E_BATT" - ], - [ - "R2", - 2025, - "spring", - "night", - "R_EH" - ], - [ - "R1-R2", - 2020, - "summer", - "night", - "E_TRANS" - ], - [ - "R2", - 2025, - "summer", - "night", - "S_OILREF" - ], - [ - "R2", - 2030, - "spring", - "day", - "R_EH" - ], - [ - "R2", - 2030, - "summer", - "day", - "S_OILREF" - ], - [ - "R1", - 2030, - "summer", - "day", - "T_DSL" - ], - [ - "R2", - 2025, - "spring", - "night", - "T_DSL" - ], - [ - "R1", - 2020, - "fall", - "night", - "E_SOLPV" - ], - [ - "R1", - 2020, - "summer", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "summer", - "day", - "R_NGH" - ], - [ - "R1", - 2030, - "winter", - "day", - "T_DSL" - ], - [ - "R1", - 2020, - "summer", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2025, - "fall", - "day", - "S_OILREF" - ], - [ - "R1", - 2025, - "fall", - "night", - "E_BATT" - ], - [ - "R2", - 2020, - "winter", - "day", - "E_NGCC" - ], - [ - "R1", - 2030, - "summer", - "day", - "S_OILREF" - ], - [ - "R1", - 2020, - "fall", - "day", - "R_NGH" - ], - [ - "R2", - 2020, - "summer", - "night", - "E_BATT" - ], - [ - "R2", - 2020, - "summer", - "night", - "T_BLND" - ], - [ - "R1", - 2020, - "fall", - "day", - "E_NUCLEAR" - ], - [ - "R1", - 2030, - "winter", - "day", - "S_OILREF" - ], - [ - "R2", - 2020, - "summer", - "day", - "E_BATT" - ], - [ - "R1", - 2020, - "spring", - "night", - "T_GSL" - ], - [ - "R1", - 2020, - "fall", - "night", - "R_EH" - ], - [ - "R2", - 2020, - "summer", - "night", - "E_NGCC" - ], - [ - "R1", - 2030, - "fall", - "day", - "E_SOLPV" - ], - [ - "R2", - 2030, - "fall", - "night", - "E_SOLPV" - ], - [ - "R2", - 2025, - "winter", - "night", - "E_NGCC" - ], - [ - "R2", - 2020, - "fall", - "day", - "E_BATT" - ], - [ - "R2", - 2020, - "fall", - "day", - "T_BLND" - ], - [ - "R1", - 2020, - "fall", - "night", - "T_DSL" - ], - [ - "R2", - 2025, - "spring", - "day", - "E_SOLPV" - ], - [ - "R2", - 2030, - "winter", - "day", - "E_NGCC" - ], - [ - "R1", - 2030, - "fall", - "day", - "T_EV" - ], - [ - "R2", - 2030, - "fall", - "day", - "T_EV" - ], - [ - "R1", - 2025, - "summer", - "day", - "E_NGCC" - ], - [ - "R2", - 2025, - "spring", - "day", - "T_EV" - ], - [ - "R2", - 2020, - "winter", - "night", - "T_EV" - ], - [ - "R1", - 2030, - "fall", - "day", - "R_EH" - ], - [ - "R1", - 2020, - "summer", - "night", - "E_SOLPV" - ], - [ - "R2", - 2030, - "fall", - "night", - "R_EH" - ], - [ - "R2-R1", - 2020, - "winter", - "day", - "E_TRANS" - ], - [ - "R1", - 2030, - "fall", - "day", - "T_DSL" - ], - [ - "R2", - 2030, - "fall", - "night", - "T_DSL" - ], - [ - "R2", - 2020, - "fall", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "fall", - "day", - "T_DSL" - ], - [ - "R2", - 2025, - "spring", - "day", - "T_DSL" - ], - [ - "R1", - 2020, - "fall", - "day", - "E_SOLPV" - ], - [ - "R1", - 2020, - "summer", - "day", - "T_EV" - ], - [ - "R2", - 2030, - "winter", - "night", - "R_NGH" - ], - [ - "R2", - 2030, - "winter", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "summer", - "night", - "R_EH" - ], - [ - "R2", - 2030, - "fall", - "day", - "S_OILREF" - ], - [ - "R1-R2", - 2020, - "spring", - "day", - "E_TRANS" - ], - [ - "R2", - 2025, - "spring", - "day", - "S_OILREF" - ], - [ - "R1", - 2020, - "fall", - "day", - "T_EV" - ], - [ - "R1", - 2025, - "spring", - "night", - "E_BATT" - ], - [ - "R1", - 2025, - "spring", - "night", - "T_BLND" - ], - [ - "R1", - 2025, - "summer", - "night", - "R_NGH" - ], - [ - "R1", - 2020, - "summer", - "night", - "T_DSL" - ], - [ - "R2", - 2020, - "winter", - "night", - "S_OILREF" - ], - [ - "R2", - 2025, - "winter", - "day", - "E_BATT" - ], - [ - "R2", - 2025, - "winter", - "day", - "T_BLND" - ], - [ - "R2", - 2025, - "fall", - "night", - "E_NGCC" - ], - [ - "R1", - 2025, - "summer", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2020, - "winter", - "day", - "E_SOLPV" - ], - [ - "R2", - 2020, - "spring", - "night", - "R_NGH" - ], - [ - "R1", - 2025, - "spring", - "night", - "E_NGCC" - ], - [ - "R1-R2", - 2025, - "spring", - "night", - "E_TRANS" - ], - [ - "R2", - 2020, - "winter", - "day", - "T_GSL" - ], - [ - "R1", - 2020, - "fall", - "day", - "T_DSL" - ], - [ - "R1", - 2020, - "summer", - "day", - "S_OILREF" - ], - [ - "R1", - 2025, - "winter", - "night", - "E_SOLPV" - ], - [ - "R2", - 2020, - "spring", - "day", - "T_BLND" - ], - [ - "R2", - 2030, - "spring", - "night", - "E_BATT" - ], - [ - "R2-R1", - 2025, - "fall", - "day", - "E_TRANS" - ], - [ - "R1", - 2020, - "winter", - "day", - "R_EH" - ], - [ - "R2", - 2020, - "summer", - "night", - "T_GSL" - ], - [ - "R1", - 2020, - "fall", - "day", - "S_OILREF" - ], - [ - "R2", - 2020, - "spring", - "day", - "E_NGCC" - ], - [ - "R2", - 2025, - "winter", - "night", - "T_GSL" - ], - [ - "R2", - 2030, - "summer", - "night", - "R_NGH" - ], - [ - "R1", - 2025, - "winter", - "day", - "R_NGH" - ], - [ - "R2", - 2030, - "summer", - "night", - "E_NUCLEAR" - ], - [ - "R1", - 2025, - "winter", - "day", - "E_NUCLEAR" - ], - [ - "R2", - 2030, - "winter", - "day", - "T_GSL" - ], - [ - "R1", - 2030, - "spring", - "day", - "R_EH" - ], - [ - "R2-R1", - 2030, - "fall", - "night", - "E_TRANS" - ], - [ - "R1", - 2025, - "winter", - "night", - "R_EH" - ], - [ - "R2", - 2025, - "summer", - "day", - "E_BATT" - ], - [ - "R2", - 2025, - "summer", - "day", - "T_BLND" - ], - [ - "R1", - 2025, - "summer", - "day", - "T_GSL" - ], - [ - "R1", - 2030, - "winter", - "night", - "R_NGH" - ], - [ - "R1", - 2025, - "winter", - "night", - "T_DSL" - ], - [ - "R2-R1", - 2025, - "winter", - "night", - "E_TRANS" - ], - [ - "R2", - 2025, - "summer", - "night", - "E_NGCC" - ], - [ - "R1", - 2030, - "winter", - "night", - "E_NUCLEAR" - ], - [ - "R2", - 2030, - "winter", - "night", - "T_EV" + "day", + "E_BATT" ], [ "R1", - 2020, - "spring", + "fall", "day", - "E_SOLPV" + "T_BLND" + ], + [ + "R1", + "summer", + "day", + "R_EH" ], [ "R2", - 2025, "fall", "day", "E_BATT" ], [ "R2", - 2025, "fall", "day", - "T_BLND" + "T_DSL" ], [ "R2", - 2030, "summer", "day", - "E_NGCC" - ], - [ - "R1", - 2025, - "summer", - "night", - "T_EV" + "S_OILREF" ], [ - "R1", - 2025, + "R2", "spring", "day", - "E_BATT" + "T_BLND" ], [ "R2", - 2020, - "spring", + "fall", "night", - "T_EV" + "E_NGCC" + ], + [ + "R1-R2", + "fall", + "day", + "E_TRANS" ], [ "R2", - 2030, - "winter", - "night", - "T_DSL" + "fall", + "day", + "S_OILREF" ], [ "R1", - 2030, "summer", + "night", + "E_BATT" + ], + [ + "R2", + "winter", "day", - "E_NGCC" + "E_SOLPV" ], [ "R1", - 2025, "fall", "night", - "E_SOLPV" + "T_GSL" ], [ - "R1", - 2030, + "R2", "winter", "day", - "E_NGCC" + "T_EV" ], [ - "R1", - 2020, + "R2", "spring", "day", - "R_EH" + "E_SOLPV" ], [ - "R1", - 2030, + "R2", + "winter", + "day", + "T_DSL" + ], + [ + "R2", "spring", - "night", - "E_BATT" + "day", + "R_EH" ], [ "R2", - 2020, "summer", "day", "E_SOLPV" ], + [ + "R2", + "winter", + "day", + "S_OILREF" + ], [ "R1", - 2025, - "summer", + "winter", "night", - "T_DSL" + "E_BATT" ], [ "R1", - 2025, "winter", - "day", - "E_SOLPV" + "night", + "T_BLND" ], [ "R2", - 2030, - "winter", + "spring", "night", - "S_OILREF" + "T_DSL" + ], + [ + "R1", + "spring", + "day", + "E_NGCC" ], [ "R2", - 2025, "fall", "night", "T_GSL" ], [ - "R1", - 2020, - "spring", + "R2", + "summer", "day", "T_DSL" ], [ - "R1", - 2025, + "R2", "fall", "day", - "R_NGH" + "R_EH" ], [ "R1", - 2025, - "fall", + "spring", "day", - "E_NUCLEAR" + "T_BLND" ], [ "R1", - 2025, - "spring", - "night", - "T_GSL" + "winter", + "day", + "R_EH" ], [ - "R2-R1", - 2025, - "summer", + "R1-R2", + "fall", "night", "E_TRANS" ], [ "R2", - 2030, "summer", - "night", - "T_EV" + "day", + "E_NGCC" ], [ "R1", - 2025, - "summer", + "spring", "night", "S_OILREF" ], [ - "R1", - 2025, + "R1-R2", "winter", - "day", - "T_EV" - ], - [ - "R1", - 2025, - "fall", "night", - "R_EH" + "E_TRANS" ], [ "R2", - 2020, - "spring", - "night", - "S_OILREF" + "fall", + "day", + "E_NGCC" ], [ "R1", - 2030, - "fall", - "night", - "R_NGH" + "spring", + "day", + "T_GSL" ], [ - "R2", - 2020, + "R2-R1", "summer", "day", - "R_EH" - ], - [ - "R1", - 2030, - "fall", - "night", - "E_NUCLEAR" + "E_TRANS" ], [ - "R1", - 2030, + "R2", "summer", "night", "R_NGH" ], [ - "R1", - 2030, + "R2", "summer", "night", "E_NUCLEAR" ], [ "R2", - 2025, - "spring", + "winter", "night", "R_NGH" ], [ - "R2", - 2020, + "R2-R1", "summer", - "day", - "T_DSL" + "night", + "E_TRANS" ], [ "R2", - 2025, - "spring", + "winter", "night", - "E_NUCLEAR" + "T_DSL" ], [ - "R1", - 2030, + "R2", "winter", "night", - "T_EV" + "E_NUCLEAR" ], [ - "R2", - 2020, - "spring", + "R1", + "summer", "day", - "T_GSL" + "R_NGH" ], [ "R1", - 2025, - "winter", + "summer", "day", "T_DSL" ], [ - "R2", - 2030, - "spring", + "R1", + "summer", "day", - "R_NGH" + "E_NUCLEAR" ], [ - "R2", - 2020, + "R1", "fall", "day", "R_EH" ], [ - "R2", - 2030, - "spring", - "day", - "E_NUCLEAR" + "R1", + "fall", + "night", + "E_BATT" ], [ - "R1-R2", - 2030, - "summer", + "R2", + "winter", "day", - "E_TRANS" + "E_NGCC" ], [ "R2", - 2030, - "fall", + "summer", "day", - "T_BLND" + "T_GSL" ], [ "R2", - 2030, "summer", "night", - "S_OILREF" - ], - [ - "R1", - 2025, - "winter", - "day", - "S_OILREF" + "T_EV" ], [ "R2", - 2020, "winter", "night", - "T_BLND" + "T_EV" ], [ "R1", - 2030, - "fall", - "day", - "E_NGCC" + "summer", + "night", + "E_SOLPV" ], [ - "R1", - 2030, + "R2-R1", "winter", - "night", - "T_DSL" + "day", + "E_TRANS" ], [ - "R2", - 2030, - "fall", + "R1", + "summer", "day", - "E_NGCC" + "T_EV" ], [ "R2", - 2025, - "summer", - "night", - "T_GSL" + "spring", + "day", + "R_NGH" ], [ "R2", - 2025, "spring", "day", - "E_NGCC" + "E_NUCLEAR" ], [ "R1", - 2025, - "fall", - "day", - "E_SOLPV" + "summer", + "night", + "R_EH" ], [ "R2", - 2030, "summer", + "night", + "S_OILREF" + ], + [ + "R1-R2", + "spring", "day", - "T_GSL" + "E_TRANS" ], [ - "R2", - 2020, - "winter", + "R1", + "spring", "night", - "E_NGCC" + "T_BLND" ], [ - "R1", - 2020, - "fall", + "R2", + "winter", "night", - "R_NGH" + "S_OILREF" ], [ "R1", - 2020, - "fall", + "spring", "night", - "E_NUCLEAR" + "E_NGCC" ], [ - "R1", - 2030, + "R2", "winter", - "night", - "S_OILREF" + "day", + "T_GSL" ], [ "R1", - 2020, "summer", "day", + "S_OILREF" + ], + [ + "R1", + "spring", + "night", "E_BATT" ], [ "R1", - 2020, - "summer", + "spring", "day", - "T_BLND" + "E_BATT" ], [ - "R2", - 2025, - "fall", + "R1", + "winter", "day", - "T_GSL" + "E_SOLPV" ], [ - "R2-R1", - 2020, + "R1", "fall", - "night", - "E_TRANS" + "day", + "R_NGH" ], [ "R1", - 2025, "fall", "day", - "T_EV" + "E_NUCLEAR" ], [ "R1", - 2030, - "summer", - "day", + "spring", + "night", "T_GSL" ], [ "R1", - 2030, "fall", "night", - "E_SOLPV" + "R_EH" ], [ "R1", - 2020, - "summer", - "day", - "E_NGCC" + "fall", + "night", + "E_SOLPV" ], [ "R1", - 2030, "summer", "night", + "E_NUCLEAR" + ], + [ + "R1", + "fall", + "day", "E_SOLPV" ], [ "R2", - 2020, "fall", - "night", - "E_BATT" + "day", + "T_BLND" ], [ "R1", - 2030, - "winter", + "fall", "day", - "T_GSL" + "T_EV" + ], + [ + "R1", + "summer", + "day", + "E_NGCC" ] ], "capacity_var_rptv": [ @@ -40014,6 +37134,7 @@ "limit_new_capacity_share_constraint_rpgg": [], "limit_resource_constraint_rt": [], "limit_seasonal_capacity_factor_constraint_rpst": [], + "limit_seasonal_capacity_factor_constraint_rst": [], "limit_storage_fraction_constraint_rpsdtv": [ [ "R1", @@ -40032,6 +37153,112 @@ "E_BATT", 2020, "e" + ], + [ + "R1", + 2030, + "winter", + "day", + "E_BATT", + 2020, + "e" + ], + [ + "R1", + 2030, + "winter", + "day", + "E_BATT", + 2025, + "e" + ], + [ + "R2", + 2025, + "summer", + "day", + "E_BATT", + 2025, + "e" + ], + [ + "R1", + 2025, + "winter", + "day", + "E_BATT", + 2020, + "e" + ], + [ + "R2", + 2025, + "summer", + "day", + "E_BATT", + 2020, + "e" + ], + [ + "R2", + 2030, + "summer", + "day", + "E_BATT", + 2030, + "e" + ], + [ + "R2", + 2030, + "summer", + "day", + "E_BATT", + 2025, + "e" + ], + [ + "R2", + 2030, + "summer", + "day", + "E_BATT", + 2020, + "e" + ], + [ + "R1", + 2020, + "winter", + "day", + "E_BATT", + 2020, + "e" + ], + [ + "R1", + 2030, + "winter", + "day", + "E_BATT", + 2030, + "e" + ] + ], + "limit_storage_fraction_param_rsdt": [ + [ + "R1", + "winter", + "day", + "E_BATT", + "e" + ], + [ + "R2", + "summer", + "day", + "E_BATT", + "e" ] ], "limit_tech_input_split_annual_constraint_rpitv": [], @@ -45350,4 +42577,4 @@ 2020, 2030 ] -} +} \ No newline at end of file diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index 17467e5f7..e3e6a926b 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -1,111 +1,45 @@ -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'inter','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'inter','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'winter','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'winter','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'summer','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2000,'summer','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2000,0.2753,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'inter','day','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'inter','night','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'winter','day','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'winter','night','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'summer','day','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_process" VALUES('utopia',2010,'summer','night','E31',2010,0.2756,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'inter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'winter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',1990,'summer','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'inter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'winter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2000,'summer','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E01',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E21',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E31',0.275,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E51',0.17,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'inter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'winter','night','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','day','E70',0.8,''); -REPLACE INTO "capacity_factor_tech" VALUES('utopia',2010,'summer','night','E70',0.8,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2000,0.2753,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','inter','day','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','inter','night','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','winter','day','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','winter','night','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','summer','day','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_process" VALUES('utopia','summer','night','E31',2010,0.2756,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','day','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','night','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','day','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','night','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','day','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','night','E01',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','day','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','night','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','day','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','night','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','day','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','night','E21',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','day','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','night','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','day','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','night','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','day','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','night','E31',0.275,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','day','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','night','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','day','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','night','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','day','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','night','E51',0.17,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','day','E70',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','inter','night','E70',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','day','E70',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','winter','night','E70',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','day','E70',0.8,''); +REPLACE INTO "capacity_factor_tech" VALUES('utopia','summer','night','E70',0.8,''); REPLACE INTO "capacity_to_activity" VALUES('utopia','E01',31.54,'PJ / (GW * year)',''); REPLACE INTO "capacity_to_activity" VALUES('utopia','E21',31.54,'PJ / (GW * year)',''); REPLACE INTO "capacity_to_activity" VALUES('utopia','E31',31.54,'PJ / (GW * year)',''); @@ -315,36 +249,16 @@ REPLACE INTO "demand" VALUES('utopia',2010,'RL',12.6,'PJ',''); REPLACE INTO "demand" VALUES('utopia',1990,'TX',5.2,'PJ',''); REPLACE INTO "demand" VALUES('utopia',2000,'TX',7.8,'PJ',''); REPLACE INTO "demand" VALUES('utopia',2010,'TX',11.69,'PJ',''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RH',0.12,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RH',0.06,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RH',0.5467,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RH',0.2733,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'inter','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'summer','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','day','RL',0.5,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',1990,'winter','night','RL',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RH',0.12,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RH',0.06,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RH',0.5467,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RH',0.2733,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'inter','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'summer','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','day','RL',0.5,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2000,'winter','night','RL',0.1,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RH',0.12,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RH',0.06,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RH',0.5467,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RH',0.2733,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'inter','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','day','RL',0.15,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'summer','night','RL',0.05,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','day','RL',0.5,''); -REPLACE INTO "demand_specific_distribution" VALUES('utopia',2010,'winter','night','RL',0.1,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','inter','day','RH',0.12,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','inter','night','RH',0.06,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','winter','day','RH',0.5467,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','winter','night','RH',0.2733,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','inter','day','RL',0.15,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','inter','night','RL',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','summer','day','RL',0.15,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','summer','night','RL',0.05,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','winter','day','RL',0.5,''); +REPLACE INTO "demand_specific_distribution" VALUES('utopia','winter','night','RL',0.1,''); REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPDSL1',1990,'DSL',1.0,'PJ / (PJ)',''); REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPGSL1',1990,'GSL',1.0,'PJ / (PJ)',''); REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPHCO1',1990,'HCO',1.0,'PJ / (PJ)',''); diff --git a/tests/testing_data/utopia_sets.json b/tests/testing_data/utopia_sets.json index 51b9b5830..405afb963 100644 --- a/tests/testing_data/utopia_sets.json +++ b/tests/testing_data/utopia_sets.json @@ -5679,1518 +5679,438 @@ 2000 ] ], - "capacity_factor_rpsdt": [ + "capacity_factor_rsdt": [ [ "utopia", - 2000, "inter", "day", "RL1" ], [ "utopia", - 2010, "winter", "day", "E51" ], [ "utopia", - 2000, "winter", "night", "E01" ], [ "utopia", - 2000, "winter", "night", "E51" ], [ "utopia", - 2000, "summer", "day", "TXG" ], [ "utopia", - 2010, "winter", "night", "TXG" ], [ "utopia", - 2000, "summer", "day", "TXD" ], [ "utopia", - 1990, "winter", "night", "TXE" ], [ "utopia", - 2010, "winter", "night", "TXD" ], [ "utopia", - 2010, "winter", "day", "TXG" ], [ "utopia", - 1990, "winter", "day", "RL1" ], [ "utopia", - 2000, "summer", "day", "E31" ], [ "utopia", - 2010, "winter", "night", "E31" ], [ "utopia", - 2000, "summer", "day", "E21" ], [ "utopia", - 2010, "summer", "night", "E70" ], [ "utopia", - 2010, "winter", "day", "SRE" ], [ "utopia", - 2010, "winter", "night", "E21" ], [ "utopia", - 2000, "winter", "night", "SRE" ], [ "utopia", - 2010, "summer", "day", "E70" ], [ "utopia", - 1990, "inter", "night", "E70" ], [ "utopia", - 2000, "winter", "day", "RHO" ], [ "utopia", - 1990, "summer", "night", "E01" ], [ "utopia", - 2000, - "summer", - "night", - "E70" - ], - [ - "utopia", - 1990, "inter", "day", "E70" ], [ "utopia", - 1990, "summer", "day", "E01" ], [ "utopia", - 2000, - "winter", - "night", - "TXE" - ], - [ - "utopia", - 2000, - "winter", - "day", - "RL1" - ], - [ - "utopia", - 1990, "summer", "day", "E51" ], [ "utopia", - 2010, "inter", "night", "RHO" ], [ "utopia", - 2010, "summer", "night", "RHE" ], [ "utopia", - 1990, "summer", "night", "SRE" ], [ "utopia", - 1990, "summer", "night", "RHO" ], [ "utopia", - 2010, - "inter", - "day", - "E70" - ], - [ - "utopia", - 2010, "summer", "day", "RHE" ], [ "utopia", - 1990, "inter", "night", "RHE" ], [ "utopia", - 2010, "inter", "night", "RL1" ], [ "utopia", - 2000, - "inter", - "night", - "E70" - ], - [ - "utopia", - 1990, "summer", "day", "SRE" ], [ "utopia", - 2000, - "summer", - "night", - "RHE" - ], - [ - "utopia", - 1990, "inter", "night", "E51" ], [ "utopia", - 1990, "inter", "day", "RHE" ], [ "utopia", - 1990, "summer", "night", "RL1" ], [ "utopia", - 2010, "summer", "night", "TXG" ], [ "utopia", - 2010, "summer", "night", "TXD" ], [ "utopia", - 1990, "summer", "night", "TXE" ], [ "utopia", - 2000, - "inter", - "day", - "E70" - ], - [ - "utopia", - 2000, - "summer", - "day", - "E01" - ], - [ - "utopia", - 2010, - "winter", - "night", - "E01" - ], - [ - "utopia", - 2000, "summer", "night", "E51" ], [ "utopia", - 1990, "winter", "night", "RHO" ], [ "utopia", - 2010, "winter", "day", "E01" ], [ "utopia", - 2000, - "summer", - "day", - "E51" - ], - [ - "utopia", - 2010, - "winter", - "night", - "E51" - ], - [ - "utopia", - 2010, "summer", "night", "E31" ], [ "utopia", - 2010, "summer", "night", "E21" ], [ "utopia", - 1990, "summer", "day", "TXE" ], [ "utopia", - 2010, - "summer", - "day", - "TXD" - ], - [ - "utopia", - 1990, "inter", "night", "TXG" ], [ "utopia", - 1990, "inter", "night", "TXD" ], [ "utopia", - 2010, - "inter", + "winter", "day", - "RHE" + "E70" ], [ "utopia", - 1990, - "winter", - "day", - "E70" + "inter", + "night", + "E31" ], [ "utopia", - 2000, - "summer", + "inter", "night", - "TXG" + "E21" ], [ "utopia", - 2000, - "summer", + "winter", "night", - "TXD" + "RL1" ], [ "utopia", - 2010, - "summer", + "inter", "day", - "E21" + "TXG" ], [ "utopia", - 2010, - "summer", + "inter", "day", - "E31" + "TXD" ], [ "utopia", - 1990, "inter", - "night", + "day", "E31" ], [ "utopia", - 1990, "inter", - "night", + "day", "E21" ], [ "utopia", - 2000, - "inter", - "night", + "winter", + "day", "RHE" ], [ "utopia", - 1990, "winter", - "night", - "RL1" - ], - [ - "utopia", - 1990, - "inter", "day", - "TXG" + "TXE" ], [ "utopia", - 1990, - "inter", + "winter", "day", "TXD" ], [ "utopia", - 2000, - "summer", - "night", - "E31" - ], - [ - "utopia", - 2000, - "summer", + "inter", "night", - "E21" + "E01" ], [ "utopia", - 2000, - "summer", + "winter", "day", - "SRE" + "E31" ], [ "utopia", - 2010, "winter", - "night", - "SRE" + "day", + "E21" ], [ "utopia", - 1990, - "inter", + "summer", "day", - "E31" + "RHO" ], [ "utopia", - 1990, "inter", "day", - "E21" + "E01" ], [ "utopia", - 2000, "inter", - "night", + "day", "E51" ], [ "utopia", - 2000, - "inter", + "summer", "day", - "RHE" + "RL1" ], [ "utopia", - 2010, "winter", - "day", - "RHO" + "night", + "E70" ], [ "utopia", - 2000, - "winter", + "inter", "night", - "RHO" + "SRE" ], [ "utopia", - 2010, "inter", "day", - "TXD" + "SRE" ], [ "utopia", - 2000, "inter", "night", - "TXG" + "TXE" ], [ "utopia", - 2010, "winter", "night", - "TXE" + "RHE" ], [ "utopia", - 2000, "inter", - "night", - "TXD" - ], - [ - "utopia", - 2000, - "summer", "day", "TXE" ], [ "utopia", - 1990, - "winter", - "day", - "RHE" - ], - [ - "utopia", - 2010, - "winter", - "day", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "day", - "E31" - ], - [ - "utopia", - 2010, - "winter", - "day", - "TXE" - ], - [ - "utopia", - 2000, - "winter", - "day", - "E70" - ], - [ - "utopia", - 2010, - "inter", - "day", - "E21" - ], - [ - "utopia", - 2000, - "inter", - "night", - "E31" - ], - [ - "utopia", - 2000, - "inter", - "night", - "E21" - ], - [ - "utopia", - 2000, - "winter", - "night", - "RL1" - ], - [ - "utopia", - 2000, - "inter", - "day", - "TXG" - ], - [ - "utopia", - 2000, - "inter", - "day", - "TXD" - ], - [ - "utopia", - 2000, - "inter", - "day", - "E31" - ], - [ - "utopia", - 2000, - "inter", - "day", - "E21" - ], - [ - "utopia", - 2010, - "inter", - "night", - "E70" - ], - [ - "utopia", - 2010, - "summer", - "night", - "E01" - ], - [ - "utopia", - 1990, - "winter", - "day", - "TXG" - ], - [ - "utopia", - 2010, - "summer", - "night", - "E51" - ], - [ - "utopia", - 1990, - "winter", - "day", - "TXD" - ], - [ - "utopia", - 1990, - "summer", - "night", - "E70" - ], - [ - "utopia", - 1990, - "inter", - "night", - "E01" - ], - [ - "utopia", - 1990, - "winter", - "day", - "E31" - ], - [ - "utopia", - 1990, - "winter", - "day", - "E21" - ], - [ - "utopia", - 1990, - "summer", - "day", - "RHO" - ], - [ - "utopia", - 2000, - "winter", - "day", - "RHE" - ], - [ - "utopia", - 2010, - "summer", - "day", - "E51" - ], - [ - "utopia", - 2000, - "summer", - "night", - "E01" - ], - [ - "utopia", - 1990, - "inter", - "day", - "E01" - ], - [ - "utopia", - 2010, - "summer", - "night", - "SRE" - ], - [ - "utopia", - 1990, - "inter", - "day", - "E51" - ], - [ - "utopia", - 1990, - "summer", - "day", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "night", - "RHE" - ], - [ - "utopia", - 2010, - "summer", - "day", - "TXG" - ], - [ - "utopia", - 1990, - "winter", - "night", - "E70" - ], - [ - "utopia", - 2010, - "summer", - "day", - "SRE" - ], - [ - "utopia", - 1990, - "inter", - "night", - "SRE" - ], - [ - "utopia", - 2000, - "winter", - "day", - "TXG" - ], - [ - "utopia", - 2000, - "winter", - "day", - "TXD" - ], - [ - "utopia", - 2010, - "summer", - "night", - "TXE" - ], - [ - "utopia", - 2000, - "summer", - "night", - "SRE" - ], - [ - "utopia", - 2010, - "inter", - "day", - "E51" - ], - [ - "utopia", - 2000, - "inter", - "night", - "E01" - ], - [ - "utopia", - 2000, - "winter", - "day", - "E31" - ], - [ - "utopia", - 2000, - "winter", - "day", - "E21" - ], - [ - "utopia", - 2000, - "summer", - "day", - "RHO" - ], - [ - "utopia", - 1990, - "inter", - "day", - "SRE" - ], - [ - "utopia", - 2010, - "winter", - "night", - "RHO" - ], - [ - "utopia", - 1990, - "inter", - "night", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "night", - "TXG" - ], - [ - "utopia", - 1990, - "inter", - "night", - "TXE" - ], - [ - "utopia", - 2010, - "inter", - "night", - "TXD" - ], - [ - "utopia", - 2000, - "inter", - "day", - "E01" - ], - [ - "utopia", - 2010, - "inter", - "day", - "TXG" - ], - [ - "utopia", - 2010, - "winter", - "day", - "E70" - ], - [ - "utopia", - 2000, - "summer", - "night", - "TXE" - ], - [ - "utopia", - 2000, - "inter", - "day", - "E51" - ], - [ - "utopia", - 1990, - "winter", - "night", - "RHE" - ], - [ - "utopia", - 2000, - "summer", - "day", - "RL1" - ], - [ - "utopia", - 2010, - "winter", - "night", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "night", - "E31" - ], - [ - "utopia", - 2010, - "inter", - "night", - "E21" - ], - [ - "utopia", - 1990, - "inter", - "day", - "TXE" - ], - [ - "utopia", - 2000, - "winter", - "night", - "E70" - ], - [ - "utopia", - 2010, - "inter", - "day", - "SRE" - ], - [ - "utopia", - 2000, - "inter", - "night", - "SRE" - ], - [ - "utopia", - 1990, - "winter", - "day", - "E01" - ], - [ - "utopia", - 1990, - "summer", - "night", - "E31" - ], - [ - "utopia", - 1990, - "winter", - "day", - "E51" - ], - [ - "utopia", - 2000, - "inter", - "day", - "SRE" - ], - [ - "utopia", - 1990, - "winter", - "night", - "TXG" - ], - [ - "utopia", - 2000, - "inter", - "night", - "RL1" - ], - [ - "utopia", - 1990, - "winter", - "night", - "TXD" - ], - [ - "utopia", - 2000, - "inter", - "night", - "TXE" - ], - [ - "utopia", - 2010, - "winter", - "day", - "RHE" - ], - [ - "utopia", - 1990, - "winter", - "night", - "E31" - ], - [ - "utopia", - 1990, - "winter", - "night", - "E21" - ], - [ - "utopia", - 1990, - "winter", - "day", - "SRE" - ], - [ - "utopia", - 2010, - "summer", - "day", - "E01" - ], - [ - "utopia", - 2000, - "winter", - "night", - "RHE" - ], - [ - "utopia", - 2000, - "inter", - "day", - "TXE" - ], - [ - "utopia", - 2000, - "winter", - "day", - "E01" - ], - [ - "utopia", - 1990, - "summer", - "day", - "E70" - ], - [ - "utopia", - 2000, - "winter", - "day", - "E51" - ], - [ - "utopia", - 2010, - "summer", - "night", - "RHO" - ], - [ - "utopia", - 1990, - "winter", - "day", - "TXE" - ], - [ - "utopia", - 2010, - "winter", - "day", - "TXD" - ], - [ - "utopia", - 2000, - "winter", - "night", - "TXG" - ], - [ - "utopia", - 2010, - "inter", - "night", - "E01" - ], - [ - "utopia", - 2000, - "winter", - "night", - "TXD" - ], - [ - "utopia", - 2010, - "winter", - "day", - "E31" - ], - [ - "utopia", - 2010, - "winter", - "day", - "E21" - ], - [ - "utopia", - 2010, - "summer", - "day", - "RHO" - ], - [ - "utopia", - 1990, - "inter", - "night", - "RHO" - ], - [ - "utopia", - 2010, - "inter", - "day", - "E01" - ], - [ - "utopia", - 1990, - "summer", - "night", - "RHE" - ], - [ - "utopia", - 2010, - "inter", - "night", - "E51" - ], - [ - "utopia", - 2010, - "summer", - "night", - "RL1" - ], - [ - "utopia", - 2000, - "winter", - "night", - "E31" - ], - [ - "utopia", - 2000, - "winter", - "night", - "E21" - ], - [ - "utopia", - 2000, - "summer", - "night", - "RHO" - ], - [ - "utopia", - 2000, - "winter", - "day", - "SRE" - ], - [ - "utopia", - 1990, - "inter", - "day", - "RHO" - ], - [ - "utopia", - 1990, - "summer", - "night", - "E51" - ], - [ - "utopia", - 1990, - "summer", - "day", - "RHE" - ], - [ - "utopia", - 2010, - "summer", - "day", - "RL1" - ], - [ - "utopia", - 2010, - "summer", - "day", - "TXE" - ], - [ - "utopia", - 2000, - "summer", - "day", - "E70" - ], - [ - "utopia", - 2010, - "winter", - "night", - "E70" - ], - [ - "utopia", - 2000, - "summer", - "night", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "night", - "SRE" - ], - [ - "utopia", - 2000, - "winter", - "day", - "TXE" - ], - [ - "utopia", - 1990, - "summer", - "night", - "TXG" - ], - [ - "utopia", - 1990, - "inter", - "day", - "RL1" - ], - [ - "utopia", - 1990, - "summer", - "night", - "TXD" - ], - [ - "utopia", - 2010, - "inter", - "day", - "RHO" - ], - [ - "utopia", - 1990, - "winter", - "night", - "E01" - ], - [ - "utopia", - 2000, - "inter", - "night", - "RHO" - ], - [ - "utopia", - 1990, - "winter", - "night", - "E51" - ], - [ - "utopia", - 1990, - "summer", - "night", - "E21" - ], - [ - "utopia", - 1990, - "summer", - "day", - "TXG" - ], - [ - "utopia", - 1990, - "summer", - "day", - "TXD" - ], - [ - "utopia", - 2010, - "inter", - "night", - "TXE" - ], - [ - "utopia", - 2010, - "inter", - "day", - "RL1" - ], - [ - "utopia", - 2010, - "inter", - "day", - "TXE" - ], - [ - "utopia", - 2000, "inter", "day", "RHO" - ], - [ - "utopia", - 1990, - "summer", - "day", - "E31" - ], - [ - "utopia", - 1990, - "summer", - "day", - "E21" - ], - [ - "utopia", - 2000, - "summer", - "day", - "RHE" - ], - [ - "utopia", - 2010, - "winter", - "night", - "RHE" - ], - [ - "utopia", - 1990, - "winter", - "night", - "SRE" - ], - [ - "utopia", - 1990, - "winter", - "day", - "RHO" ] ], "capacity_var_rptv": [ @@ -22294,7 +21214,9 @@ "limit_new_capacity_share_constraint_rpgg": [], "limit_resource_constraint_rt": [], "limit_seasonal_capacity_factor_constraint_rpst": [], + "limit_seasonal_capacity_factor_constraint_rst": [], "limit_storage_fraction_constraint_rpsdtv": [], + "limit_storage_fraction_param_rsdt": [], "limit_tech_input_split_annual_constraint_rpitv": [], "limit_tech_input_split_average_constraint_rpitv": [], "limit_tech_input_split_constraint_rpsditv": [], @@ -25242,4 +24164,4 @@ 2010, 1990 ] -} +} \ No newline at end of file From 5aeee57592603eacc419a8afdeb1d90705674fac Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Wed, 4 Mar 2026 18:06:48 -0500 Subject: [PATCH 08/40] Update test_system legacy values for more storage frac constraints --- tests/legacy_test_values.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/legacy_test_values.py b/tests/legacy_test_values.py index b4a355a9a..b4c0ecf23 100644 --- a/tests/legacy_test_values.py +++ b/tests/legacy_test_values.py @@ -19,14 +19,16 @@ class ExpectedVals(Enum): test_vals = { 'test_system': { # reduced after removing ancient 1-year-shift obj function bug - ExpectedVals.OBJ_VALUE: 468550.1905, + # increased by ~25 after removing period index from storagefrac (more constraints) + ExpectedVals.OBJ_VALUE: 468575.0703, ExpectedVals.EFF_DOMAIN_SIZE: 30720, ExpectedVals.EFF_INDEX_SIZE: 74, # increased by 2 when reworking storageinit. # increased after making annualretirement derived var # reduced 2025/07/25 by 504 after annualising demands # increased 2025/08/19 after making annual demands optional - ExpectedVals.CONSTR_COUNT: 2810, + # increased by 10 after removing period index from storagefrac (more constraints) + ExpectedVals.CONSTR_COUNT: 2820, # reduced by 6 when reworking storageinit. # increased after making annualretirement derived var # reduced 2025/07/21 after removing existing vintage v_new_capacity indices From 8b548ef50faae100ba2d29d26261dca5eca198f0 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Thu, 5 Mar 2026 13:06:50 -0500 Subject: [PATCH 09/40] Remove season_label table --- data_files/example_dbs/materials.sql | 37 ++++++---------- data_files/example_dbs/morris_utopia.sql | 36 ++++++--------- data_files/example_dbs/seasonal_storage.sql | 49 ++++++--------------- data_files/example_dbs/survival_curve.sql | 34 ++++++-------- data_files/example_dbs/test_system.sql | 37 ++++++---------- data_files/example_dbs/utopia.sql | 36 ++++++--------- data_files/temoa_schema_v4.sql | 37 +++++++--------- temoa/db_schema/temoa_schema_v4.sql | 37 +++++++--------- temoa/tutorial_assets/utopia.sql | 38 +++++++--------- tests/testing_data/emissions.sql | 1 - tests/testing_data/materials.sql | 4 -- tests/testing_data/mediumville.sql | 2 - tests/testing_data/seasonal_storage.sql | 16 ------- tests/testing_data/simple_linked_tech.sql | 2 - tests/testing_data/storageville.sql | 2 - tests/testing_data/survival_curve.sql | 1 - tests/testing_data/test_system.sql | 4 -- tests/testing_data/utopia_data.sql | 3 -- 18 files changed, 131 insertions(+), 245 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 915f31886..d69769fae 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -31,7 +31,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -301,7 +301,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -441,7 +441,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -801,7 +801,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -814,7 +814,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1102,7 +1102,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1125,7 +1125,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1200,7 +1200,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1248,7 +1248,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1268,15 +1268,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('summer',NULL); -INSERT INTO "season_label" VALUES('autumn',NULL); -INSERT INTO "season_label" VALUES('winter',NULL); -INSERT INTO "season_label" VALUES('spring',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1386,9 +1377,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'summer',NULL); INSERT INTO "time_season" VALUES(1,'autumn',NULL); @@ -1399,7 +1390,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1409,7 +1400,7 @@ CREATE TABLE time_season_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 479eac354..b6ff49928 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -43,7 +43,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -399,7 +399,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -503,7 +503,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -883,7 +883,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -896,7 +896,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1137,7 +1137,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1160,7 +1160,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1235,7 +1235,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1282,7 +1282,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1302,14 +1302,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('inter',NULL); -INSERT INTO "season_label" VALUES('summer',NULL); -INSERT INTO "season_label" VALUES('winter',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1423,9 +1415,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'summer',NULL); INSERT INTO "time_season" VALUES(1,'winter',NULL); @@ -1435,7 +1427,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1445,7 +1437,7 @@ CREATE TABLE time_season_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index e82b099f9..956ba531b 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -31,7 +31,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -176,7 +176,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -218,7 +218,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -534,7 +534,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -547,7 +547,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -783,7 +783,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -806,7 +806,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -881,7 +881,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -928,7 +928,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -948,27 +948,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('charge','non-sequential season - charging day'); -INSERT INTO "season_label" VALUES('discharge','non-sequential season - discharging day'); -INSERT INTO "season_label" VALUES('summer','sequential season - summer day'); -INSERT INTO "season_label" VALUES('sept_w1','sequential season - day in first week of September'); -INSERT INTO "season_label" VALUES('sept_w2','sequential season - day in second week of September'); -INSERT INTO "season_label" VALUES('sept_w3','sequential season - day in third week of September'); -INSERT INTO "season_label" VALUES('sept_w4','sequential season - day in fourth week of September'); -INSERT INTO "season_label" VALUES('sept_29th','sequential season - 29th of September'); -INSERT INTO "season_label" VALUES('sept_30th','sequential season - 30th of September'); -INSERT INTO "season_label" VALUES('winter','sequential season - winter day'); -INSERT INTO "season_label" VALUES('apr_w1','sequential season - day in first week of September'); -INSERT INTO "season_label" VALUES('apr_w2','sequential season - day in second week of September'); -INSERT INTO "season_label" VALUES('apr_w3','sequential season - day in third week of September'); -INSERT INTO "season_label" VALUES('apr_w4','sequential season - day in fourth week of September'); -INSERT INTO "season_label" VALUES('apr_29th','sequential season - 29th of April'); -INSERT INTO "season_label" VALUES('apr_30th','sequential season - 30th of April'); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1061,9 +1040,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'charge',NULL); INSERT INTO "time_season" VALUES(1,'discharge',NULL); @@ -1072,7 +1051,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1096,7 +1075,7 @@ INSERT INTO "time_season_sequential" VALUES('apr_30th','discharge',1.0,NULL); CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index b833a702f..75e8171f5 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -31,7 +31,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -220,7 +220,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -258,7 +258,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -636,7 +636,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -649,7 +649,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -883,7 +883,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -906,7 +906,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -981,7 +981,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1028,7 +1028,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1048,12 +1048,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('s',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1147,9 +1141,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'s',NULL); @@ -1157,7 +1151,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1167,7 +1161,7 @@ CREATE TABLE time_season_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 9b8c47841..fea65db11 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -31,7 +31,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -383,7 +383,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -503,7 +503,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -873,7 +873,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -886,7 +886,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1146,7 +1146,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1169,7 +1169,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1244,7 +1244,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1292,7 +1292,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1312,15 +1312,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('summer',NULL); -INSERT INTO "season_label" VALUES('fall',NULL); -INSERT INTO "season_label" VALUES('winter',NULL); -INSERT INTO "season_label" VALUES('spring',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1431,9 +1422,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'spring',NULL); INSERT INTO "time_season" VALUES(1,'summer',NULL); @@ -1444,7 +1435,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1454,7 +1445,7 @@ CREATE TABLE time_season_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index f04eab310..f066de7a4 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -43,7 +43,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -397,7 +397,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -501,7 +501,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -881,7 +881,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -894,7 +894,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1134,7 +1134,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1157,7 +1157,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1232,7 +1232,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1279,7 +1279,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1299,14 +1299,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('inter',NULL); -INSERT INTO "season_label" VALUES('summer',NULL); -INSERT INTO "season_label" VALUES('winter',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1420,9 +1412,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'inter',NULL); INSERT INTO "time_season" VALUES(1,'summer',NULL); @@ -1432,7 +1424,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1442,7 +1434,7 @@ CREATE TABLE time_season_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 937bdbc36..fae58d864 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -39,11 +39,6 @@ CREATE TABLE IF NOT EXISTS output_objective objective_name TEXT, total_system_cost REAL ); -CREATE TABLE IF NOT EXISTS season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); CREATE TABLE IF NOT EXISTS sector_label ( sector TEXT PRIMARY KEY, @@ -68,7 +63,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_process period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -85,7 +80,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_tech period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -220,7 +215,7 @@ CREATE TABLE IF NOT EXISTS demand_specific_distribution period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -267,7 +262,7 @@ CREATE TABLE IF NOT EXISTS efficiency_variable period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -478,7 +473,7 @@ CREATE TABLE IF NOT EXISTS limit_storage_level_fraction period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -603,7 +598,7 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -777,7 +772,7 @@ CREATE TABLE IF NOT EXISTS output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -801,7 +796,7 @@ CREATE TABLE IF NOT EXISTS output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -825,7 +820,7 @@ CREATE TABLE IF NOT EXISTS output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -874,7 +869,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -886,7 +881,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate CREATE TABLE IF NOT EXISTS time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, @@ -929,11 +924,11 @@ VALUES ('ps', 'storage production technology'); -- CREATE TABLE IF NOT EXISTS time_manual -- ( -- season TEXT --- REFERENCES season_label (season), +-- REFERENCES time_season (season), -- tod TEXT -- REFERENCES time_of_day (tod), -- season_next TEXT --- REFERENCES season_label (season), +-- REFERENCES time_season (season), -- tod_next TEXT -- REFERENCES time_of_day (tod), -- notes TEXT, @@ -1043,16 +1038,16 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); CREATE TABLE IF NOT EXISTS time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 66328d8ad..d4d46fdd1 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -39,11 +39,6 @@ CREATE TABLE IF NOT EXISTS output_objective objective_name TEXT, total_system_cost REAL ); -CREATE TABLE IF NOT EXISTS season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); CREATE TABLE IF NOT EXISTS sector_label ( sector TEXT PRIMARY KEY, @@ -66,7 +61,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -81,7 +76,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -214,7 +209,7 @@ CREATE TABLE IF NOT EXISTS demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -259,7 +254,7 @@ CREATE TABLE IF NOT EXISTS efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -468,7 +463,7 @@ CREATE TABLE IF NOT EXISTS limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -589,7 +584,7 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -763,7 +758,7 @@ CREATE TABLE IF NOT EXISTS output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -787,7 +782,7 @@ CREATE TABLE IF NOT EXISTS output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -811,7 +806,7 @@ CREATE TABLE IF NOT EXISTS output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -858,7 +853,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -870,7 +865,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate CREATE TABLE IF NOT EXISTS time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, @@ -913,11 +908,11 @@ VALUES ('ps', 'storage production technology'); -- CREATE TABLE IF NOT EXISTS time_manual -- ( -- season TEXT --- REFERENCES season_label (season), +-- REFERENCES time_season (season), -- tod TEXT -- REFERENCES time_of_day (tod), -- season_next TEXT --- REFERENCES season_label (season), +-- REFERENCES time_season (season), -- tod_next TEXT -- REFERENCES time_of_day (tod), -- notes TEXT, @@ -1027,16 +1022,16 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); CREATE TABLE IF NOT EXISTS time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index b3c7f039a..b881c1237 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -16,7 +16,7 @@ CREATE TABLE capacity_factor_process ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -43,7 +43,7 @@ CREATE TABLE capacity_factor_tech ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -399,7 +399,7 @@ CREATE TABLE demand_specific_distribution ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), demand_name TEXT @@ -504,7 +504,7 @@ CREATE TABLE efficiency_variable ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -886,7 +886,7 @@ CREATE TABLE limit_seasonal_capacity_factor region TEXT REFERENCES region (region), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), operator TEXT NOT NULL DEFAULT "le" @@ -899,7 +899,7 @@ CREATE TABLE limit_storage_level_fraction ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1144,7 +1144,7 @@ CREATE TABLE output_flow_in period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1168,7 +1168,7 @@ CREATE TABLE output_flow_out period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT @@ -1246,7 +1246,7 @@ CREATE TABLE output_storage_level period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), tech TEXT @@ -1294,7 +1294,7 @@ CREATE TABLE reserve_capacity_derate ( region TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tech TEXT REFERENCES technology (tech), vintage INTEGER, @@ -1314,14 +1314,6 @@ CREATE TABLE rps_requirement requirement REAL NOT NULL, notes TEXT ); -CREATE TABLE season_label -( - season TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "season_label" VALUES('inter',NULL); -INSERT INTO "season_label" VALUES('summer',NULL); -INSERT INTO "season_label" VALUES('winter',NULL); CREATE TABLE sector_label ( sector TEXT PRIMARY KEY, @@ -1435,9 +1427,9 @@ INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( sequence INTEGER, - season TEXT REFERENCES season_label(season), + season TEXT, notes TEXT, - PRIMARY KEY (sequence, season) + PRIMARY KEY (season) ); INSERT INTO "time_season" VALUES(0,'inter',NULL); INSERT INTO "time_season" VALUES(1,'summer',NULL); @@ -1446,7 +1438,7 @@ CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, - season TEXT REFERENCES season_label(season), + season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (sequence, seas_seq, season), @@ -1459,7 +1451,7 @@ CREATE TABLE time_season_to_sequential sequence INTEGER, seas_seq TEXT, season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), num_days REAL NOT NULL, notes TEXT, PRIMARY KEY (period, sequence, seas_seq, season), @@ -1468,7 +1460,7 @@ CREATE TABLE time_season_to_sequential CREATE TABLE time_segment_fraction ( season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), segment_fraction REAL, diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index cbfdaa8b2..671ed2283 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -75,7 +75,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('Testregion',NULL); -REPLACE INTO "season_label" VALUES('S1',NULL); REPLACE INTO "technology" VALUES('TechAnnual','p','energy',NULL,NULL,0,1,0,0,0,0,0,0,NULL); REPLACE INTO "technology" VALUES('TechFlex','p','energy',NULL,NULL,0,0,0,0,0,1,0,0,NULL); REPLACE INTO "technology" VALUES('TechOrdinary','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index c7ac6f363..b3ed8c4e0 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -338,10 +338,6 @@ REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('regionA',NULL); REPLACE INTO "region" VALUES('regionB',NULL); -REPLACE INTO "season_label" VALUES('summer',NULL); -REPLACE INTO "season_label" VALUES('autumn',NULL); -REPLACE INTO "season_label" VALUES('winter',NULL); -REPLACE INTO "season_label" VALUES('spring',NULL); REPLACE INTO "storage_duration" VALUES('regionA','BATT_GRID',2.0,'2 hours energy storage'); REPLACE INTO "storage_duration" VALUES('regionB','BATT_GRID',2.0,'2 hours energy storage'); REPLACE INTO "technology" VALUES('IMPORT_LI','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'lithium importer'); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 7c7b80127..f1992ab18 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -155,8 +155,6 @@ REPLACE INTO "ramp_up_hourly" VALUES('A','EH',0.05,NULL); REPLACE INTO "region" VALUES('A','main region'); REPLACE INTO "region" VALUES('B','just a 2nd region'); REPLACE INTO "rps_requirement" VALUES('B',2025,'RPS_common',0.3,NULL); -REPLACE INTO "season_label" VALUES('s1',NULL); -REPLACE INTO "season_label" VALUES('s2',NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 0a61c71aa..62704c798 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -50,22 +50,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('region',NULL); -REPLACE INTO "season_label" VALUES('charge','non-sequential season - charging day'); -REPLACE INTO "season_label" VALUES('discharge','non-sequential season - discharging day'); -REPLACE INTO "season_label" VALUES('summer','sequential season - summer day'); -REPLACE INTO "season_label" VALUES('sept_w1','sequential season - day in first week of September'); -REPLACE INTO "season_label" VALUES('sept_w2','sequential season - day in second week of September'); -REPLACE INTO "season_label" VALUES('sept_w3','sequential season - day in third week of September'); -REPLACE INTO "season_label" VALUES('sept_w4','sequential season - day in fourth week of September'); -REPLACE INTO "season_label" VALUES('sept_29th','sequential season - 29th of September'); -REPLACE INTO "season_label" VALUES('sept_30th','sequential season - 30th of September'); -REPLACE INTO "season_label" VALUES('winter','sequential season - winter day'); -REPLACE INTO "season_label" VALUES('apr_w1','sequential season - day in first week of September'); -REPLACE INTO "season_label" VALUES('apr_w2','sequential season - day in second week of September'); -REPLACE INTO "season_label" VALUES('apr_w3','sequential season - day in third week of September'); -REPLACE INTO "season_label" VALUES('apr_w4','sequential season - day in fourth week of September'); -REPLACE INTO "season_label" VALUES('apr_29th','sequential season - 29th of April'); -REPLACE INTO "season_label" VALUES('apr_30th','sequential season - 30th of April'); REPLACE INTO "sector_label" VALUES('electricity',NULL); REPLACE INTO "storage_duration" VALUES('region','dly_stor',4.0,NULL); REPLACE INTO "storage_duration" VALUES('region','seas_stor',8760.0,NULL); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index fac6239c3..46043dfcf 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -35,8 +35,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('linkville',NULL); -REPLACE INTO "season_label" VALUES('summer',NULL); -REPLACE INTO "season_label" VALUES('winter',NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index e98bf3966..84498a741 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -49,8 +49,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('electricville',NULL); -REPLACE INTO "season_label" VALUES('s1',NULL); -REPLACE INTO "season_label" VALUES('s2',NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index 36e81024d..2eae1a7d5 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -150,7 +150,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('region',NULL); -REPLACE INTO "season_label" VALUES('s',NULL); REPLACE INTO "technology" VALUES('tech_ancient','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); REPLACE INTO "technology" VALUES('tech_old','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); REPLACE INTO "technology" VALUES('tech_current','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 0f49b84b5..87e2ffe3d 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -414,10 +414,6 @@ REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('R1',NULL); REPLACE INTO "region" VALUES('R2',NULL); -REPLACE INTO "season_label" VALUES('summer',NULL); -REPLACE INTO "season_label" VALUES('fall',NULL); -REPLACE INTO "season_label" VALUES('winter',NULL); -REPLACE INTO "season_label" VALUES('spring',NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index e3e6a926b..d3601faec 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -401,9 +401,6 @@ REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('utopia',NULL); -REPLACE INTO "season_label" VALUES('inter',NULL); -REPLACE INTO "season_label" VALUES('summer',NULL); -REPLACE INTO "season_label" VALUES('winter',NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); From 4b0e730b9d5c9755aeba1b561e4e61aeaf2ea9b9 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Thu, 5 Mar 2026 13:22:12 -0500 Subject: [PATCH 10/40] Change time_season_sequential pk to only seas_seq --- data_files/example_dbs/materials.sql | 2 +- data_files/example_dbs/morris_utopia.sql | 2 +- data_files/example_dbs/seasonal_storage.sql | 30 ++++++++++----------- data_files/example_dbs/stepped_demand.sql | 4 +-- data_files/example_dbs/survival_curve.sql | 2 +- data_files/example_dbs/test_system.sql | 2 +- data_files/example_dbs/utopia.sql | 2 +- data_files/temoa_schema_v4.sql | 2 +- temoa/db_schema/temoa_schema_v4.sql | 2 +- temoa/tutorial_assets/utopia.sql | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index d69769fae..623080905 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1393,7 +1393,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index b6ff49928..849349f6c 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1430,7 +1430,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 956ba531b..8c1ffc861 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1054,23 +1054,23 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); -INSERT INTO "time_season_sequential" VALUES('summer','charge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_w1','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_w2','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_w3','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_w4','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_29th','discharge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES('sept_30th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES('winter','discharge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_w1','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_w2','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_w3','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_w4','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_29th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES('apr_30th','discharge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES(1,'summer','charge',152.5,NULL); +INSERT INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(3,'sept_w2','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(5,'sept_w4','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES(7,'sept_30th','charge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES(8,'winter','discharge',152.5,NULL); +INSERT INTO "time_season_sequential" VALUES(9,'apr_w1','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(11,'apr_w3','charge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',7.0,NULL); +INSERT INTO "time_season_sequential" VALUES(13,'apr_29th','charge',1.0,NULL); +INSERT INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',1.0,NULL); CREATE TABLE time_segment_fraction ( diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index dc5c62d16..4a8c70ee2 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1120,10 +1120,10 @@ CREATE TABLE time_season_sequential sequence INTEGER, seas_seq TEXT, season TEXT - REFERENCES SeasonLabel (season), + REFERENCES time_season (season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); CREATE TABLE TimePeriodType diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 75e8171f5..4edbcfab6 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1154,7 +1154,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index fea65db11..871f3656a 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1438,7 +1438,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index f066de7a4..f11b17908 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1427,7 +1427,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index fae58d864..32591263e 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -1050,7 +1050,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index d4d46fdd1..97084b2ea 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -1034,7 +1034,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index b881c1237..438dc1f78 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1441,7 +1441,7 @@ CREATE TABLE time_season_sequential season TEXT REFERENCES time_season(season), num_days REAL NOT NULL, notes TEXT, - PRIMARY KEY (sequence, seas_seq, season), + PRIMARY KEY (seas_seq), CHECK (num_days > 0) ); CREATE TABLE time_season_to_sequential From e0ea36075feb6ba4fa053098f46aff9555daf389 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Thu, 5 Mar 2026 15:06:02 -0500 Subject: [PATCH 11/40] Fix ramp rate constraints to adjust limit to hourly output --- temoa/components/operations.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/temoa/components/operations.py b/temoa/components/operations.py index fc6cac36e..7460927dd 100644 --- a/temoa/components/operations.py +++ b/temoa/components/operations.py @@ -344,7 +344,10 @@ def ramp_up_day_constraint( activity_increase = hourly_activity_sd_next - hourly_activity_sd # opposite sign from rampdown rampable_activity = ( - ramp_fraction * model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) + ramp_fraction + * model.v_capacity[r, p, t, v] + * value(model.capacity_to_activity[r, t]) + / (24 * value(model.days_per_period)) # adjust capacity to hourly basis ) expr = activity_increase <= rampable_activity @@ -434,7 +437,10 @@ def ramp_down_day_constraint( activity_decrease = hourly_activity_sd - hourly_activity_sd_next # opposite sign from rampup rampable_activity = ( - ramp_fraction * model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) + ramp_fraction + * model.v_capacity[r, p, t, v] + * value(model.capacity_to_activity[r, t]) + / (24 * value(model.days_per_period)) # adjust capacity to hourly basis ) expr = activity_decrease <= rampable_activity @@ -509,7 +515,10 @@ def ramp_up_season_constraint( activity_increase = hourly_activity_sd_next - hourly_activity_sd # opposite sign from rampdown rampable_activity = ( - ramp_fraction * model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) + ramp_fraction + * model.v_capacity[r, p, t, v] + * value(model.capacity_to_activity[r, t]) + / (24 * value(model.days_per_period)) # adjust capacity to hourly basis ) expr = activity_increase <= rampable_activity @@ -584,7 +593,10 @@ def ramp_down_season_constraint( activity_decrease = hourly_activity_sd - hourly_activity_sd_next # opposite sign from rampup rampable_activity = ( - ramp_fraction * model.v_capacity[r, p, t, v] * value(model.capacity_to_activity[r, t]) + ramp_fraction + * model.v_capacity[r, p, t, v] + * value(model.capacity_to_activity[r, t]) + / (24 * value(model.days_per_period)) # adjust capacity to hourly basis ) expr = activity_decrease <= rampable_activity From bb243ca1d220c330ff78354197ed5a6ae5988630 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 08:11:37 -0500 Subject: [PATCH 12/40] Add hours column to time_of_day --- data_files/example_dbs/materials.sql | 12 ++++--- data_files/example_dbs/morris_utopia.sql | 8 +++-- data_files/example_dbs/seasonal_storage.sql | 12 ++++--- data_files/example_dbs/survival_curve.sql | 6 ++-- data_files/example_dbs/test_system.sql | 8 +++-- data_files/example_dbs/utopia.sql | 8 +++-- data_files/temoa_schema_v4.sql | 4 ++- temoa/components/operations.py | 40 +++++---------------- temoa/core/model.py | 1 + temoa/data_io/component_manifest.py | 7 ++++ temoa/db_schema/temoa_schema_v4.sql | 4 ++- temoa/tutorial_assets/utopia.sql | 8 +++-- tests/testing_data/annualised_demand.sql | 2 +- tests/testing_data/emissions.sql | 4 +-- tests/testing_data/materials.sql | 8 ++--- tests/testing_data/mediumville.sql | 4 +-- tests/testing_data/seasonal_storage.sql | 8 ++--- tests/testing_data/simple_linked_tech.sql | 2 +- tests/testing_data/storageville.sql | 10 +++--- tests/testing_data/survival_curve.sql | 2 +- tests/testing_data/test_system.sql | 4 +-- tests/testing_data/utopia_data.sql | 4 +-- 22 files changed, 84 insertions(+), 82 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 623080905..6770176ca 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1347,12 +1347,14 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(1,'morning'); -INSERT INTO "time_of_day" VALUES(2,'afternoon'); -INSERT INTO "time_of_day" VALUES(3,'evening'); -INSERT INTO "time_of_day" VALUES(4,'overnight'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'morning',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'afternoon',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(3,'evening',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(4,'overnight',6); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 849349f6c..d68bd52db 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1385,10 +1385,12 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(1,'day'); -INSERT INTO "time_of_day" VALUES(2,'night'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 8c1ffc861..a80659d55 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1013,12 +1013,14 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(0,'a'); -INSERT INTO "time_of_day" VALUES(1,'b'); -INSERT INTO "time_of_day" VALUES(2,'c'); -INSERT INTO "time_of_day" VALUES(3,'d'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'a',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'b',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'c',6); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(3,'d',6); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 4edbcfab6..1b45c4406 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1110,9 +1110,11 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(0,'d'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'d',24); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 871f3656a..6172c0bc2 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1394,10 +1394,12 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(1,'day'); -INSERT INTO "time_of_day" VALUES(2,'night'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',12); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',12); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index f11b17908..126ccd161 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1382,10 +1382,12 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(1,'day'); -INSERT INTO "time_of_day" VALUES(2,'night'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 32591263e..8907f82dc 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -938,7 +938,9 @@ CREATE TABLE IF NOT EXISTS time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); CREATE TABLE IF NOT EXISTS time_period ( diff --git a/temoa/components/operations.py b/temoa/components/operations.py index 7460927dd..61d04ef5f 100644 --- a/temoa/components/operations.py +++ b/temoa/components/operations.py @@ -323,14 +323,8 @@ def ramp_up_day_constraint( # elapsed hours from middle of this time slice to middle of next time slice hours_elapsed = ( - 24 - / 2 - * ( - value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) - + value(model.segment_fraction[s_next, d_next]) - / value(model.segment_fraction_per_season[s_next]) - ) - ) + model.time_of_day_hours[d] + model.time_of_day_hours[d_next] + ) / 2 ramp_fraction = hours_elapsed * value(model.ramp_up_hourly[r, t]) if ramp_fraction >= 1: @@ -416,14 +410,8 @@ def ramp_down_day_constraint( # elapsed hours from middle of this time slice to middle of next time slice hours_elapsed = ( - 24 - / 2 - * ( - value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) - + value(model.segment_fraction[s_next, d_next]) - / value(model.segment_fraction_per_season[s_next]) - ) - ) + model.time_of_day_hours[d] + model.time_of_day_hours[d_next] + ) / 2 ramp_fraction = hours_elapsed * value(model.ramp_down_hourly[r, t]) if ramp_fraction >= 1: @@ -494,14 +482,8 @@ def ramp_up_season_constraint( # elapsed hours from middle of this time slice to middle of next time slice hours_elapsed = ( - 24 - / 2 - * ( - value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) - + value(model.segment_fraction[s_next, d_next]) - / value(model.segment_fraction_per_season[s_next]) - ) - ) + model.time_of_day_hours[d] + model.time_of_day_hours[d_next] + ) / 2 ramp_fraction = hours_elapsed * value(model.ramp_up_hourly[r, t]) if ramp_fraction >= 1: @@ -572,14 +554,8 @@ def ramp_down_season_constraint( # elapsed hours from middle of this time slice to middle of next time slice hours_elapsed = ( - 24 - / 2 - * ( - value(model.segment_fraction[s, d]) / value(model.segment_fraction_per_season[s]) - + value(model.segment_fraction[s_next, d_next]) - / value(model.segment_fraction_per_season[s_next]) - ) - ) + model.time_of_day_hours[d] + model.time_of_day_hours[d_next] + ) / 2 ramp_fraction = hours_elapsed * value(model.ramp_down_hourly[r, t]) if ramp_fraction >= 1: diff --git a/temoa/core/model.py b/temoa/core/model.py index fe9d7f9b2..f4a21750c 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -330,6 +330,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Define time-related parameters self.period_length = Param(self.time_optimize, initialize=time.param_period_length) self.segment_fraction = Param(self.time_season, self.time_of_day) + self.time_of_day_hours = Param(self.time_of_day, default=1) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) self.time_sequencing = Set() # How do states carry between time segments? self.time_manual = Set( diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index b796a9dc5..05510c79a 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -237,6 +237,13 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_table_required=False, fallback_data=[('D',)], ), + LoadItem( + component=model.time_of_day_hours, + table='time_of_day', + columns=['tod', 'hours'], + is_period_filtered=False, + is_table_required=False, + ), LoadItem( component=model.time_season, table='time_season', diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 97084b2ea..78df150d4 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -922,7 +922,9 @@ CREATE TABLE IF NOT EXISTS time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); CREATE TABLE IF NOT EXISTS time_period ( diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 438dc1f78..d9f4ce1a0 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1397,10 +1397,12 @@ CREATE TABLE time_of_day ( sequence INTEGER UNIQUE, tod TEXT - PRIMARY KEY + PRIMARY KEY, + hours INTEGER NOT NULL DEFAULT 1, + notes TEXT ); -INSERT INTO "time_of_day" VALUES(1,'day'); -INSERT INTO "time_of_day" VALUES(2,'night'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); CREATE TABLE time_period ( sequence INTEGER UNIQUE, diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index 1f37dd211..f1996c1a7 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -45,7 +45,7 @@ REPLACE INTO "technology" VALUES('non_annual','p','energy',NULL,NULL,0,0,0,0,0,0 REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(0,'D1'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'D1',24); REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2001,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 671ed2283..5d0a03a68 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -86,8 +86,8 @@ REPLACE INTO "technology" VALUES('TechEndOfLife','p','energy',NULL,NULL,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'TOD1'); -REPLACE INTO "time_of_day" VALUES(2,'TOD2'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'TOD1',12); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'TOD2',12); REPLACE INTO "time_period" VALUES(1,1999,'e'); REPLACE INTO "time_period" VALUES(2,2000,'f'); REPLACE INTO "time_period" VALUES(3,2005,'f'); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index b3ed8c4e0..817f8bd23 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -362,10 +362,10 @@ REPLACE INTO "technology" VALUES('ELEC_INTERTIE','p','electricity',NULL,NULL,0,0 REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'morning'); -REPLACE INTO "time_of_day" VALUES(2,'afternoon'); -REPLACE INTO "time_of_day" VALUES(3,'evening'); -REPLACE INTO "time_of_day" VALUES(4,'overnight'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'morning',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'afternoon',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'evening',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(4,'overnight',6); REPLACE INTO "time_period" VALUES(1,1990,'e'); REPLACE INTO "time_period" VALUES(2,2000,'f'); REPLACE INTO "time_period" VALUES(3,2010,'f'); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index f1992ab18..ea6f2ac7a 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -180,8 +180,8 @@ REPLACE INTO "technology" VALUES('GeoHeater','p','residential','hydro','',0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'d1'); -REPLACE INTO "time_of_day" VALUES(2,'d2'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'d1',12); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'d2',12); REPLACE INTO "time_period" VALUES(1,2020,'e'); REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 62704c798..7f43d33b8 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -60,10 +60,10 @@ REPLACE INTO "technology" VALUES('demand','p','electricity',NULL,NULL,0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(0,'a'); -REPLACE INTO "time_of_day" VALUES(1,'b'); -REPLACE INTO "time_of_day" VALUES(2,'c'); -REPLACE INTO "time_of_day" VALUES(3,'d'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'a',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'b',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'c',6); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'d',6); REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index 46043dfcf..092f4d8f2 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -48,7 +48,7 @@ REPLACE INTO "technology" VALUES('FAKE_SOURCE','p','supply',NULL,NULL,1,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'day'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',24); REPLACE INTO "time_period" VALUES(0,1995,'e'); REPLACE INTO "time_period" VALUES(1,2000,'f'); REPLACE INTO "time_period" VALUES(2,2005,'f'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 84498a741..9c8cc0049 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -63,11 +63,11 @@ REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'d1'); -REPLACE INTO "time_of_day" VALUES(2,'d2'); -REPLACE INTO "time_of_day" VALUES(3,'d3'); -REPLACE INTO "time_of_day" VALUES(4,'d4'); -REPLACE INTO "time_of_day" VALUES(5,'d5'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'d1', 4.8); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'d2', 4.8); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'d3', 4.8); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(4,'d4', 4.8); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(5,'d5', 4.8); REPLACE INTO "time_period" VALUES(1,2020,'e'); REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index 2eae1a7d5..195ed2ee8 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -157,7 +157,7 @@ REPLACE INTO "technology" VALUES('tech_future','p','energy',NULL,NULL,0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(0,'d'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'d',24); REPLACE INTO "time_period" VALUES(-2,1994,'e'); REPLACE INTO "time_period" VALUES(-1,2010,'e'); REPLACE INTO "time_period" VALUES(0,2025,'f'); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 87e2ffe3d..5aca40ba6 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -441,8 +441,8 @@ REPLACE INTO "technology" VALUES('E_TRANS','p','electric','','',0,0,0,0,0,0,1,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'day'); -REPLACE INTO "time_of_day" VALUES(2,'night'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',12); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',12); REPLACE INTO "time_period" VALUES(1,2015,'e'); REPLACE INTO "time_period" VALUES(2,2020,'f'); REPLACE INTO "time_period" VALUES(3,2025,'f'); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index d3601faec..18510e127 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -429,8 +429,8 @@ REPLACE INTO "technology" VALUES('TXG','p','transport','petroleum','',0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" VALUES(1,'day'); -REPLACE INTO "time_of_day" VALUES(2,'night'); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); +INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); REPLACE INTO "time_period" VALUES(1,1960,'e'); REPLACE INTO "time_period" VALUES(2,1970,'e'); REPLACE INTO "time_period" VALUES(3,1980,'e'); From fbf140859dd0561c2bc2a03f698eaf689ebcd612 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 09:05:01 -0500 Subject: [PATCH 13/40] Move segment_fraction definition to season tables --- data_files/example_dbs/materials.sql | 40 ++------- data_files/example_dbs/morris_utopia.sql | 28 ++---- data_files/example_dbs/seasonal_storage.sql | 58 +++++------- data_files/example_dbs/stepped_demand.sql | 4 +- data_files/example_dbs/survival_curve.sql | 19 +--- data_files/example_dbs/test_system.sql | 32 ++----- data_files/example_dbs/utopia.sql | 28 ++---- data_files/temoa_schema_v4.sql | 16 +--- temoa/components/time.py | 98 ++++++++++----------- temoa/core/model.py | 7 +- temoa/data_io/component_manifest.py | 15 ++-- temoa/data_io/hybrid_loader.py | 17 ---- temoa/db_schema/temoa_schema_v4.sql | 16 +--- temoa/tutorial_assets/utopia.sql | 32 ++----- tests/testing_data/annualised_demand.sql | 3 +- tests/testing_data/emissions.sql | 4 +- tests/testing_data/materials.sql | 40 +++------ tests/testing_data/mediumville.sql | 8 +- tests/testing_data/seasonal_storage.sql | 40 ++++----- tests/testing_data/simple_linked_tech.sql | 6 +- tests/testing_data/storageville.sql | 14 +-- tests/testing_data/survival_curve.sql | 13 ++- tests/testing_data/test_system.sql | 16 +--- tests/testing_data/utopia_data.sql | 12 +-- 24 files changed, 171 insertions(+), 395 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 6770176ca..7db879b55 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1380,51 +1380,25 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'summer',NULL); -INSERT INTO "time_season" VALUES(1,'autumn',NULL); -INSERT INTO "time_season" VALUES(2,'winter',NULL); -INSERT INTO "time_season" VALUES(3,'spring',NULL); +INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); +INSERT INTO "time_season" VALUES(1,'autumn',0.25,NULL); +INSERT INTO "time_season" VALUES(2,'winter',0.25,NULL); +INSERT INTO "time_season" VALUES(3,'spring',0.25,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('summer', 'morning', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('autumn', 'morning', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('winter', 'morning', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('spring', 'morning', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('summer', 'afternoon', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('autumn', 'afternoon', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('winter', 'afternoon', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('spring', 'afternoon', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('summer', 'evening', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('autumn', 'evening', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('winter', 'evening', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('spring', 'evening', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('summer', 'overnight', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('autumn', 'overnight', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('winter', 'overnight', 0.0625, NULL); -INSERT INTO "time_segment_fraction" VALUES('spring', 'overnight', 0.0625, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index d68bd52db..78b051a28 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1418,40 +1418,24 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'summer',NULL); -INSERT INTO "time_season" VALUES(1,'winter',NULL); -INSERT INTO "time_season" VALUES(2,'inter',NULL); +INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); +INSERT INTO "time_season" VALUES(1,'winter',0.5,NULL); +INSERT INTO "time_season" VALUES(2,'inter',0.25,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); -INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index a80659d55..dfdf77167 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1043,55 +1043,37 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'charge',NULL); -INSERT INTO "time_season" VALUES(1,'discharge',NULL); +INSERT INTO "time_season" VALUES(0,'charge',0.5,NULL); +INSERT INTO "time_season" VALUES(1,'discharge',0.5,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) -); -INSERT INTO "time_season_sequential" VALUES(1,'summer','charge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(3,'sept_w2','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(5,'sept_w4','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(7,'sept_30th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(8,'winter','discharge',152.5,NULL); -INSERT INTO "time_season_sequential" VALUES(9,'apr_w1','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(11,'apr_w3','charge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',7.0,NULL); -INSERT INTO "time_season_sequential" VALUES(13,'apr_29th','charge',1.0,NULL); -INSERT INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',1.0,NULL); + CHECK (segment_fraction > 0) +); +INSERT INTO "time_season_sequential" VALUES(1,'summer','charge',0.417808,NULL); +INSERT INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(3,'sept_w2','charge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(5,'sept_w4','charge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',0.002740,NULL); +INSERT INTO "time_season_sequential" VALUES(7,'sept_30th','charge',0.002740,NULL); +INSERT INTO "time_season_sequential" VALUES(8,'winter','discharge',0.417808,NULL); +INSERT INTO "time_season_sequential" VALUES(9,'apr_w1','charge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(11,'apr_w3','charge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',0.019178,NULL); +INSERT INTO "time_season_sequential" VALUES(13,'apr_29th','charge',0.002740,NULL); +INSERT INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',0.002740,NULL); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('charge', 'a', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('charge', 'b', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('charge', 'c', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('charge', 'd', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('discharge', 'a', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('discharge', 'b', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('discharge', 'c', 0.125, NULL); -INSERT INTO "time_segment_fraction" VALUES('discharge', 'd', 0.125, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index 4a8c70ee2..ff81864b2 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1121,10 +1121,10 @@ CREATE TABLE time_season_sequential seas_seq TEXT, season TEXT REFERENCES time_season (season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); CREATE TABLE TimePeriodType ( diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 1b45c4406..473d0b03e 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1144,33 +1144,22 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'s',NULL); +INSERT INTO "time_season" VALUES(0,'s',1.0,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('s', 'd', 1.0, NULL); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 6172c0bc2..1122a38f6 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1425,43 +1425,25 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'spring',NULL); -INSERT INTO "time_season" VALUES(1,'summer',NULL); -INSERT INTO "time_season" VALUES(2,'fall',NULL); -INSERT INTO "time_season" VALUES(3,'winter',NULL); +INSERT INTO "time_season" VALUES(0,'spring',0.25,NULL); +INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); +INSERT INTO "time_season" VALUES(2,'fall',0.25,NULL); +INSERT INTO "time_season" VALUES(3,'winter',0.25,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('spring', 'day', 0.125, 'Spring - Day'); -INSERT INTO "time_segment_fraction" VALUES('spring', 'night', 0.125, 'Spring - Night'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.125, 'Summer - Day'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.125, 'Summer - Night'); -INSERT INTO "time_segment_fraction" VALUES('fall', 'day', 0.125, 'Fall - Day'); -INSERT INTO "time_segment_fraction" VALUES('fall', 'night', 0.125, 'Fall - Night'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.125, 'Winter - Day'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.125, 'Winter - Night'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 126ccd161..38206dc91 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1415,40 +1415,24 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'inter',NULL); -INSERT INTO "time_season" VALUES(1,'summer',NULL); -INSERT INTO "time_season" VALUES(2,'winter',NULL); +INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); +INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); +INSERT INTO "time_season" VALUES(2,'winter',0.5,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); -INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 8907f82dc..2a7064fb4 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -878,17 +878,6 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate PRIMARY KEY (region, period, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); -CREATE TABLE IF NOT EXISTS time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); CREATE TABLE IF NOT EXISTS storage_duration ( region TEXT, @@ -1041,6 +1030,7 @@ CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); @@ -1050,10 +1040,10 @@ CREATE TABLE IF NOT EXISTS time_season_sequential sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/components/time.py b/temoa/components/time.py index efe0b44a0..352a5a809 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -88,8 +88,17 @@ def validate_time(model: TemoaModel) -> None: def validate_segment_fraction(model: TemoaModel) -> None: - """Ensure that the segment fractions adds up to 1""" - + """Compute and validate segment_fraction from season fractions and TOD hours.""" + + # Compute segment_fraction[s, d] = segment_fraction_per_season[s] * hours[d] / total_hours + total_hours: float = sum(value(model.time_of_day_hours[d]) for d in model.time_of_day) + for s in model.time_season: + for d in model.time_of_day: + model.segment_fraction[s, d] = ( + value(model.segment_fraction_per_season[s]) + * value(model.time_of_day_hours[d]) + / total_hours + ) expected_keys: set[tuple[str, str]] = { (s, d) for s in model.time_season for d in model.time_of_day } @@ -99,9 +108,9 @@ def validate_segment_fraction(model: TemoaModel) -> None: extra: set[tuple[str, str]] = keys.difference(expected_keys) missing: set[tuple[str, str]] = expected_keys.difference(keys) msg: str = ( - 'time_segment_fraction elements do not match time_season and time_of_day.' - f'\n\nIndices missing from time_segment_fraction:\n{missing}' - f'\n\nIndices in time_segment_fraction missing from time_season/time_of_day:\n' + 'Computed segment_fraction elements do not match time_season × time_of_day.' + f'\n\nIndices missing from segment_fraction:\n{missing}' + f'\n\nIndices in segment_fraction not matching time_season/time_of_day:\n' f'{extra}' ) logger.error(msg) @@ -127,7 +136,7 @@ def get_str_padding(obj: object) -> int: items: str = '\n '.join(f'{str(k):<{key_padding}} = {v}' for k, v in items_list) msg = ( - 'The values of time_segment_fraction do not sum to 1. ' + 'The values of segment_fraction do not sum to 1. ' 'Each item in segment_fraction represents a fraction of a year, so they must ' f'total to 1. Current values:\n {items}\n\tsum = {total}' ) @@ -158,9 +167,9 @@ def validate_time_manual(model: TemoaModel) -> None: if missing_sd or missing_sd_next: msg: str = ( 'Failed to build state sequence. ' - f'\nThese states from time_segment_fraction were not given a next state:\n' + f'\nThese segment_fraction states were not given a next state:\n' f'{missing_sd}\n' - f'\nThese states from time_segment_fraction do not follow any state:\n' + f'\nThese segment_fraction states do not follow any state:\n' f'{missing_sd_next}' ) logger.error(msg) @@ -187,14 +196,6 @@ def init_set_vintage_optimize(model: TemoaModel) -> list[int]: return sorted(model.time_optimize) -def segment_fraction_per_season_rule(model: TemoaModel, s: Season) -> float: - """Rule to calculate the total fraction of a period represented by a season.""" - return sum( - value(model.segment_fraction[s, d]) - for d in model.time_of_day - if (s, d) in model.segment_fraction - ) - def param_period_length(model: TemoaModel, p: Period) -> int: """Rule to calculate the length of each optimization period in years.""" @@ -324,14 +325,12 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: if model.time_sequencing.first() in ('consecutive_days', 'seasonal_timeslices'): logger.info( 'No data in time_season_sequential. By default, assuming sequential seasons ' - 'match time_season and time_segment_fraction.' + 'match time_season.' ) for s in model.time_season: model.time_season_to_sequential.add(s) model.ordered_season_sequential.add((s, s)) - model.time_season_sequential[s, s] = value( - model.segment_fraction_per_season[s] - ) * value(model.days_per_period) + model.time_season_sequential[s, s] = value(model.segment_fraction_per_season[s]) else: msg = ( @@ -345,64 +344,61 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: logger.error(msg) raise ValueError(msg) - sequential: dict[str, float] = {} - prev_n: float = 0 + seas_fracs_seq: dict[str, float] = {} + prev_frac: float = 0 for s_seq, s in model.time_season_sequential.sparse_iterkeys(): - num_days: float = value(model.time_season_sequential[s_seq, s]) + seg_frac_seq: float = value(model.time_season_sequential[s_seq, s]) if ( model.time_sequencing.first() == 'consecutive_days' - and prev_n - and abs(num_days - prev_n) >= 0.001 + and prev_frac + and abs(seg_frac_seq - prev_frac) >= 0.001 ): msg = ( 'time_sequencing set to consecutive_days but two consecutive seasons do not ' - 'represent the same number of days. This discontinuity will lead to bad model ' - f'behaviour: {s}, days: {num_days}. ' - f'Previous number of days: {prev_n}. Check the config file for more information.' + 'represent the same fraction of the year. This discontinuity will lead to bad ' + f'model behaviour: {s}, fraction: {seg_frac_seq}. ' + f'Previous fraction: {prev_frac}. Check the config file for more information.' ) logger.error(msg) raise ValueError(msg) - prev_n = num_days # for validating next in sequence + prev_frac = seg_frac_seq # for validating next in sequence - # Regardless of their order, make sure the total number of days adds up - sequential[s] = sequential.get(s, 0) + num_days + # Regardless of their order, make sure the total fractions add up + seas_fracs_seq[s] = seas_fracs_seq.get(s, 0) + seg_frac_seq - # Check that time_season_sequential num_days total to number of days per period - count_total: float = sum(sequential.values()) - if abs(count_total - value(model.days_per_period)) >= 0.001: + # Check that time_season_sequential segment_fraction totals to 1.0 + frac_total: float = sum(seas_fracs_seq.values()) + if abs(frac_total - 1.0) >= 0.001: logger.warning( - 'Sum of num_days in time_season_sequential (%s) ' - 'does not sum to days_per_period (%s) ' - 'from the MetaData table.', - count_total, - value(model.days_per_period), + 'Sum of segment_fraction in time_season_sequential (%s) does not sum to 1.0.', + frac_total, ) # Check that seasons used in storage seasons are actual seasons - for s in sequential: - if s not in model.segment_fraction_per_season: + for s in seas_fracs_seq: + if s not in model.time_season: msg = ( - f'Season {s!r} that does not exist in ' - 'time_segment_fraction referenced in time_season_sequential.' + f'Season {s!r} referenced in time_season_sequential ' + 'does not exist in time_season.' ) logger.error(msg) raise ValueError(msg) - for s in model.segment_fraction_per_season.sparse_iterkeys(): + for s in model.time_season: # Check that all seasons are used in sequential seasons - if s not in sequential: + if s not in seas_fracs_seq: msg = f'Season {s!r} absent from time_season_sequential' logger.warning(msg) # Check that the two tables agree on the total seasonal composition - segment_fraction = value(model.segment_fraction_per_season[s]) - segment_fraction_seq = sequential[s] / count_total - if abs(segment_fraction - segment_fraction_seq) >= 0.001: + season_frac = value(model.segment_fraction_per_season[s]) + season_frac_seq = seas_fracs_seq[s] + if abs(season_frac - season_frac_seq) >= 0.001: msg = ( 'Discrepancy of total seasonal composition between ' - 'time_segment_fraction and time_season_sequential. Total fraction ' + 'time_season and time_season_sequential. Total fraction ' 'assigned to each season should match: ' - f'time_segment_fraction: {(s, value(model.segment_fraction_per_season[s]))}' - f', time_season_sequential: {(s, segment_fraction_seq)}' + f'time_season: {(s, season_frac)}' + f', time_season_sequential: {(s, season_frac_seq)}' ) logger.warning(msg) diff --git a/temoa/core/model.py b/temoa/core/model.py index f4a21750c..8e9e1fc4c 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -329,7 +329,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Define time-related parameters self.period_length = Param(self.time_optimize, initialize=time.param_period_length) - self.segment_fraction = Param(self.time_season, self.time_of_day) + self.segment_fraction = Param(self.time_season, self.time_of_day, mutable=True) self.time_of_day_hours = Param(self.time_of_day, default=1) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) self.time_sequencing = Set() # How do states carry between time segments? @@ -494,10 +494,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Set up representation of time self.days_per_period = Param() - self.segment_fraction_per_season = Param( - self.time_season, - initialize=time.segment_fraction_per_season_rule, - ) + self.segment_fraction_per_season = Param(self.time_season) self.time_season_sequential = Param( self.time_season_to_sequential, self.time_season, mutable=True ) diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index 05510c79a..0613e897e 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -253,18 +253,17 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_table_required=False, ), LoadItem( - component=model.time_season_sequential, - table='time_season_sequential', - columns=['seas_seq', 'season', 'num_days'], - custom_loader_name='_load_time_season_sequential', + component=model.segment_fraction_per_season, + table='time_season', + columns=['season', 'segment_fraction'], is_period_filtered=False, is_table_required=False, ), LoadItem( - component=model.segment_fraction, - table='time_segment_fraction', - columns=['season', 'tod', 'segment_fraction'], - custom_loader_name='_load_segment_fraction', + component=model.time_season_sequential, + table='time_season_sequential', + columns=['seas_seq', 'season', 'segment_fraction'], + custom_loader_name='_load_time_season_sequential', is_period_filtered=False, is_table_required=False, ), diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 6c6107e92..22db76951 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -573,23 +573,6 @@ def _load_time_season_sequential( seq_data = sorted({(row[0],) for row in filtered_data}) self._load_component_data(data, model.time_season_to_sequential, seq_data) - def _load_segment_fraction( - self, - data: dict[str, object], - raw_data: Sequence[tuple[object, ...]], - filtered_data: Sequence[tuple[object, ...]], - ) -> None: - """Handles dynamic fallbacks for segment_fraction if its table is missing.""" - model = TemoaModel() - if filtered_data: - self._load_component_data(data, model.segment_fraction, filtered_data) - else: - logger.warning( - 'No segment_fraction table found. Generating default segment_fraction values.' - ) - fallback: list[tuple[object, ...]] = [('S', 'D', 1.0)] - self._load_component_data(data, model.segment_fraction, fallback) - # --- Capacity and Cost Components --- def _load_existing_capacity( self, diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 78df150d4..2f659c26b 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -862,17 +862,6 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); -CREATE TABLE IF NOT EXISTS time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); CREATE TABLE IF NOT EXISTS storage_duration ( region TEXT, @@ -1025,6 +1014,7 @@ CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); @@ -1034,10 +1024,10 @@ CREATE TABLE IF NOT EXISTS time_season_sequential sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index d9f4ce1a0..5c5964480 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1430,21 +1430,22 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, + segment_fraction REAL, notes TEXT, PRIMARY KEY (season) ); -INSERT INTO "time_season" VALUES(0,'inter',NULL); -INSERT INTO "time_season" VALUES(1,'summer',NULL); -INSERT INTO "time_season" VALUES(2,'winter',NULL); +INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); +INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); +INSERT INTO "time_season" VALUES(2,'winter',0.5,NULL); CREATE TABLE time_season_sequential ( sequence INTEGER, seas_seq TEXT, season TEXT REFERENCES time_season(season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); CREATE TABLE time_season_to_sequential ( @@ -1454,27 +1455,10 @@ CREATE TABLE time_season_to_sequential seas_seq TEXT, season TEXT REFERENCES time_season (season), - num_days REAL NOT NULL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (period, sequence, seas_seq, season), - CHECK (num_days > 0) + CHECK (segment_fraction > 0) ); -CREATE TABLE time_segment_fraction -( - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - segment_fraction REAL, - notes TEXT, - PRIMARY KEY (season, tod), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -INSERT INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); -INSERT INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); -INSERT INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); -INSERT INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index f1996c1a7..c841716cb 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -50,5 +50,4 @@ REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2001,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(0,'S1',NULL); -REPLACE INTO "time_segment_fraction" VALUES('S1', 'D1', 1.0, NULL); +REPLACE INTO "time_season" VALUES(0,'S1',1.0,NULL); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 5d0a03a68..67b6c3631 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -94,6 +94,4 @@ REPLACE INTO "time_period" VALUES(3,2005,'f'); REPLACE INTO "time_period" VALUES(4,2010,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'S1',NULL); -REPLACE INTO "time_segment_fraction" VALUES('S1', 'TOD1', 0.5, NULL); -REPLACE INTO "time_segment_fraction" VALUES('S1', 'TOD2', 0.5, NULL); +REPLACE INTO "time_season" VALUES(1,'S1',1.0,NULL); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index 817f8bd23..8ffc34c90 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -373,31 +373,15 @@ REPLACE INTO "time_period" VALUES(4,2020,'f'); REPLACE INTO "time_period" VALUES(5,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'summer',NULL); -REPLACE INTO "time_season" VALUES(2,'autumn',NULL); -REPLACE INTO "time_season" VALUES(3,'winter',NULL); -REPLACE INTO "time_season" VALUES(4,'spring',NULL); -REPLACE INTO "time_season" VALUES(5,'summer',NULL); -REPLACE INTO "time_season" VALUES(6,'autumn',NULL); -REPLACE INTO "time_season" VALUES(7,'winter',NULL); -REPLACE INTO "time_season" VALUES(8,'spring',NULL); -REPLACE INTO "time_season" VALUES(9,'summer',NULL); -REPLACE INTO "time_season" VALUES(10,'autumn',NULL); -REPLACE INTO "time_season" VALUES(11,'winter',NULL); -REPLACE INTO "time_season" VALUES(12,'spring',NULL); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'morning', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('autumn', 'morning', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'morning', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'morning', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'afternoon', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('autumn', 'afternoon', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'afternoon', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'afternoon', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'evening', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('autumn', 'evening', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'evening', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'evening', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'overnight', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('autumn', 'overnight', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'overnight', 0.0625, NULL); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'overnight', 0.0625, NULL); +REPLACE INTO "time_season" VALUES(1,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(2,'autumn',0.25,NULL); +REPLACE INTO "time_season" VALUES(3,'winter',0.25,NULL); +REPLACE INTO "time_season" VALUES(4,'spring',0.25,NULL); +REPLACE INTO "time_season" VALUES(5,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(6,'autumn',0.25,NULL); +REPLACE INTO "time_season" VALUES(7,'winter',0.25,NULL); +REPLACE INTO "time_season" VALUES(8,'spring',0.25,NULL); +REPLACE INTO "time_season" VALUES(9,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(10,'autumn',0.25,NULL); +REPLACE INTO "time_season" VALUES(11,'winter',0.25,NULL); +REPLACE INTO "time_season" VALUES(12,'spring',0.25,NULL); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index ea6f2ac7a..8a8357ef1 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -187,9 +187,5 @@ REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'s1',NULL); -REPLACE INTO "time_season" VALUES(2,'s2',NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd1', 0.25, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd2', 0.25, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd1', 0.25, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd2', 0.25, NULL); +REPLACE INTO "time_season" VALUES(1,'s1',0.5,NULL); +REPLACE INTO "time_season" VALUES(2,'s2',0.5,NULL); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 7f43d33b8..1b7e62bfb 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -68,27 +68,19 @@ REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(0,'charge',NULL); -REPLACE INTO "time_season" VALUES(1,'discharge',NULL); -REPLACE INTO "time_season_sequential" VALUES(1,'summer','charge',152.5,NULL); -REPLACE INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(3,'sept_w2','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(5,'sept_w4','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(7,'sept_30th','charge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(8,'winter','discharge',152.5,NULL); -REPLACE INTO "time_season_sequential" VALUES(9,'apr_w1','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(11,'apr_w3','charge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',7.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(13,'apr_29th','charge',1.0,NULL); -REPLACE INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',1.0,NULL); -REPLACE INTO "time_segment_fraction" VALUES('charge', 'a', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('charge', 'b', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('charge', 'c', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('charge', 'd', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('discharge', 'a', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('discharge', 'b', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('discharge', 'c', 0.125, NULL); -REPLACE INTO "time_segment_fraction" VALUES('discharge', 'd', 0.125, NULL); +REPLACE INTO "time_season" VALUES(0,'charge',0.5,NULL); +REPLACE INTO "time_season" VALUES(1,'discharge',0.5,NULL); +REPLACE INTO "time_season_sequential" VALUES(1,'summer','charge',0.417808,NULL); +REPLACE INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(3,'sept_w2','charge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(4,'sept_w3','discharge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(5,'sept_w4','charge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(6,'sept_29th','discharge',0.002740,NULL); +REPLACE INTO "time_season_sequential" VALUES(7,'sept_30th','charge',0.002740,NULL); +REPLACE INTO "time_season_sequential" VALUES(8,'winter','discharge',0.417808,NULL); +REPLACE INTO "time_season_sequential" VALUES(9,'apr_w1','charge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(10,'apr_w2','discharge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(11,'apr_w3','charge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(12,'apr_w4','discharge',0.019178,NULL); +REPLACE INTO "time_season_sequential" VALUES(13,'apr_29th','charge',0.002740,NULL); +REPLACE INTO "time_season_sequential" VALUES(14,'apr_30th','discharge',0.002740,NULL); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index 092f4d8f2..25dbf834a 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -54,7 +54,5 @@ REPLACE INTO "time_period" VALUES(1,2000,'f'); REPLACE INTO "time_period" VALUES(2,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'summer',NULL); -REPLACE INTO "time_season" VALUES(2,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.5, '# S-D'); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.5, '# W-D'); +REPLACE INTO "time_season" VALUES(1,'summer',0.5,NULL); +REPLACE INTO "time_season" VALUES(2,'winter',0.5,NULL); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 9c8cc0049..61073e1e9 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -73,15 +73,5 @@ REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'s1',NULL); -REPLACE INTO "time_season" VALUES(2,'s2',NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd3', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd1', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd2', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd3', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd1', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd2', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd4', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s1', 'd5', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd4', 0.1, NULL); -REPLACE INTO "time_segment_fraction" VALUES('s2', 'd5', 0.1, NULL); +REPLACE INTO "time_season" VALUES(1,'s1',0.5,NULL); +REPLACE INTO "time_season" VALUES(2,'s2',0.5,NULL); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index 195ed2ee8..fb258e566 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -169,10 +169,9 @@ REPLACE INTO "time_period" VALUES(5,2050,'f'); REPLACE INTO "time_period" VALUES(6,2055,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(0,'s',NULL); -REPLACE INTO "time_season" VALUES(1,'s',NULL); -REPLACE INTO "time_season" VALUES(2,'s',NULL); -REPLACE INTO "time_season" VALUES(3,'s',NULL); -REPLACE INTO "time_season" VALUES(4,'s',NULL); -REPLACE INTO "time_season" VALUES(5,'s',NULL); -REPLACE INTO "time_segment_fraction" VALUES('s', 'd', 1.0, NULL); +REPLACE INTO "time_season" VALUES(0,'s',1.0,NULL); +REPLACE INTO "time_season" VALUES(1,'s',1.0,NULL); +REPLACE INTO "time_season" VALUES(2,'s',1.0,NULL); +REPLACE INTO "time_season" VALUES(3,'s',1.0,NULL); +REPLACE INTO "time_season" VALUES(4,'s',1.0,NULL); +REPLACE INTO "time_season" VALUES(5,'s',1.0,NULL); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 5aca40ba6..070a515f0 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -450,15 +450,7 @@ REPLACE INTO "time_period" VALUES(4,2030,'f'); REPLACE INTO "time_period" VALUES(5,2035,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'spring',NULL); -REPLACE INTO "time_season" VALUES(2,'summer',NULL); -REPLACE INTO "time_season" VALUES(3,'fall',NULL); -REPLACE INTO "time_season" VALUES(4,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'day', 0.125, 'Spring - Day'); -REPLACE INTO "time_segment_fraction" VALUES('spring', 'night', 0.125, 'Spring - Night'); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.125, 'Summer - Day'); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'night', 0.125, 'Summer - Night'); -REPLACE INTO "time_segment_fraction" VALUES('fall', 'day', 0.125, 'Fall - Day'); -REPLACE INTO "time_segment_fraction" VALUES('fall', 'night', 0.125, 'Fall - Night'); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.125, 'Winter - Day'); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'night', 0.125, 'Winter - Night'); +REPLACE INTO "time_season" VALUES(1,'spring',0.25,NULL); +REPLACE INTO "time_season" VALUES(2,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(3,'fall',0.25,NULL); +REPLACE INTO "time_season" VALUES(4,'winter',0.25,NULL); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index 18510e127..d0ebbd4e9 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -440,12 +440,6 @@ REPLACE INTO "time_period" VALUES(6,2010,'f'); REPLACE INTO "time_period" VALUES(7,2020,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); -REPLACE INTO "time_season" VALUES(1,'inter',NULL); -REPLACE INTO "time_season" VALUES(2,'summer',NULL); -REPLACE INTO "time_season" VALUES(3,'winter',NULL); -REPLACE INTO "time_segment_fraction" VALUES('inter', 'day', 0.1667, '# I-D'); -REPLACE INTO "time_segment_fraction" VALUES('inter', 'night', 0.0833, '# I-N'); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'day', 0.1667, '# S-D'); -REPLACE INTO "time_segment_fraction" VALUES('summer', 'night', 0.0833, '# S-N'); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'day', 0.3333, '# W-D'); -REPLACE INTO "time_segment_fraction" VALUES('winter', 'night', 0.1667, '# W-N'); +REPLACE INTO "time_season" VALUES(1,'inter',0.25,NULL); +REPLACE INTO "time_season" VALUES(2,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(3,'winter',0.5,NULL); From e23f2671f589043664c6c7c9e07ee41202b3192b Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 10:23:06 -0500 Subject: [PATCH 14/40] Fix sequencing of model construction for time params --- temoa/core/model.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/temoa/core/model.py b/temoa/core/model.py index 8e9e1fc4c..3ad0d5aff 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -327,12 +327,25 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.global_discount_rate = Param(default=0.05) + # These need to come before validate_season_sequential as they tell us whether + # we need sequential seasons + self.ramp_up_hourly = Param(self.regions, self.tech_upramping, validate=validate_0to1) + self.ramp_down_hourly = Param(self.regions, self.tech_downramping, validate=validate_0to1) + # Define time-related parameters + # Basic period construction + self.time_sequencing = Set() # How do states carry between time segments? self.period_length = Param(self.time_optimize, initialize=time.param_period_length) - self.segment_fraction = Param(self.time_season, self.time_of_day, mutable=True) + self.days_per_period = Param() self.time_of_day_hours = Param(self.time_of_day, default=1) + self.segment_fraction_per_season = Param(self.time_season) + self.segment_fraction = Param(self.time_season, self.time_of_day, mutable=True) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) - self.time_sequencing = Set() # How do states carry between time segments? + self.time_season_sequential = Param( + self.time_season_to_sequential, self.time_season, mutable=True + ) + self.validate_season_sequential = BuildAction(rule=time.create_time_season_to_sequential) + self.create_time_sequence = BuildAction(rule=time.create_time_sequence) self.time_manual = Set( ordered=True ) # This is just to get data from the table. Hidden feature and usually not used @@ -488,19 +501,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.renewable_portfolio_standard_constraint_rpg, validate=validate_0to1 ) - # These need to come before validate_season_sequential - self.ramp_up_hourly = Param(self.regions, self.tech_upramping, validate=validate_0to1) - self.ramp_down_hourly = Param(self.regions, self.tech_downramping, validate=validate_0to1) - - # Set up representation of time - self.days_per_period = Param() - self.segment_fraction_per_season = Param(self.time_season) - self.time_season_sequential = Param( - self.time_season_to_sequential, self.time_season, mutable=True - ) - self.validate_season_sequential = BuildAction(rule=time.create_time_season_to_sequential) - self.create_time_sequence = BuildAction(rule=time.create_time_sequence) - # The method below creates a series of helper functions that are used to # perform the sparse matrix of indexing for the parameters, variables, and # equations below. From ba9ecc11525188fdb4cf1d36f05477b1bf514f2e Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 10:23:28 -0500 Subject: [PATCH 15/40] Update seasonal storage season weight adjustment --- temoa/components/storage.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 8bcc46405..18889b845 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -204,14 +204,15 @@ def seasonal_storage_energy_constraint( s_seq_next: Season = model.time_next_sequential[s_seq] s_next: Season = model.sequential_to_season[s_seq_next] - # Flows and StorageLevel are normalised to the number of days in the non-sequential season, - # so must - # be adjusted to the number of days in the sequential season - days_adjust = value(model.time_season_sequential[s_seq, s]) / ( - value(model.segment_fraction_per_season[s]) * value(model.days_per_period) + # Flows and StorageLevel are adjusted for the weight of seasons and so must be + # readjusted for the relative weight of the sequential season + days_adjust = ( + value(model.time_season_sequential[s_seq, s]) + / value(model.segment_fraction_per_season[s]) ) - days_adjust_next = value(model.time_season_sequential[s_seq_next, s_next]) / ( - value(model.segment_fraction_per_season[s_next]) * value(model.days_per_period) + days_adjust_next = ( + value(model.time_season_sequential[s_seq_next, s_next]) + / value(model.segment_fraction_per_season[s_next]) ) stored_energy = (charge - discharge) * days_adjust @@ -352,11 +353,11 @@ def seasonal_storage_energy_upper_bound_constraint( * (value(model.storage_duration[r, t]) / (24 * value(model.days_per_period))) ) - # Flows and StorageLevel are normalised to the number of days in the non-sequential season, - # so must - # be adjusted to the number of days in the sequential season - days_adjust = value(model.time_season_sequential[s_seq, s]) / ( - value(model.segment_fraction_per_season[s]) * value(model.days_per_period) + # Flows and StorageLevel are adjusted for the weight of seasons and so must be + # readjusted for the relative weight of the sequential season + days_adjust = ( + value(model.time_season_sequential[s_seq, s]) + / value(model.segment_fraction_per_season[s]) ) # v_storage_level tracks the running cumulative delta in the non-sequential season, From c211edbdc850f0be54dbbec71655cda0421dac4c Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 10:34:03 -0500 Subject: [PATCH 16/40] Update test values for new seg_frac definition as no longer rounded --- tests/legacy_test_values.py | 3 ++- tests/test_full_runs.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/legacy_test_values.py b/tests/legacy_test_values.py index b4c0ecf23..653349392 100644 --- a/tests/legacy_test_values.py +++ b/tests/legacy_test_values.py @@ -41,7 +41,8 @@ class ExpectedVals(Enum): # reduced after removing ancient 1-year-shift obj function bug # increased after rework of inter-season sequencing # reduced after changing fixed costs from MLP to PL - ExpectedVals.OBJ_VALUE: 34711.5173, + # reduced by <1 after changing season definition (segfrac no longer rounded) + ExpectedVals.OBJ_VALUE: 34710.6730, ExpectedVals.EFF_DOMAIN_SIZE: 12312, ExpectedVals.EFF_INDEX_SIZE: 64, # reduced 3/27: unlim_cap techs now employed. diff --git a/tests/test_full_runs.py b/tests/test_full_runs.py index 9cb39cec7..cbd979f7e 100644 --- a/tests/test_full_runs.py +++ b/tests/test_full_runs.py @@ -120,7 +120,8 @@ def test_myopic_utopia( # reduced this target after storageinit rework # reduced after removing ancient 1-year shift bug from objective function # increased after rework of inter-season sequencing - assert invest_sum == pytest.approx(11004.8335), 'sum of investment costs did not match expected' + # reduced by <1 after changing season definition (segfrac no longer rounded) + assert invest_sum == pytest.approx(11004.3544), 'sum of investment costs did not match expected' con.close() @@ -139,7 +140,8 @@ def test_stochastic_utopia( _, _, _, sequencer = system_test_run # Stochastic Expected Value for current utopia configuration - expected_obj = 34389.9878 + # reduced by <1 after changing season definition (segfrac no longer rounded) + expected_obj = 34389.1352 assert sequencer.stochastic_sequencer is not None assert sequencer.stochastic_sequencer.objective_value == pytest.approx(expected_obj, rel=1e-5) From 74193175058ce4b0eb4ab4ac0df4bb35d721d730 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 10:57:16 -0500 Subject: [PATCH 17/40] Fix two bugs in new season_seq definition --- temoa/_internal/table_data_puller.py | 5 +++-- temoa/components/storage.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/temoa/_internal/table_data_puller.py b/temoa/_internal/table_data_puller.py index f936dd0bb..0c8395475 100644 --- a/temoa/_internal/table_data_puller.py +++ b/temoa/_internal/table_data_puller.py @@ -241,8 +241,9 @@ def poll_storage_level_results(model: TemoaModel, epsilon: float = 1e-5) -> dict # Ratio of days in virtual storage season to days in actual season # Flows and StorageLevel are normalised to the number of days in the ACTUAL season, so must # be adjusted to the number of days in the virtual storage season - days_adjust = value(model.time_season_sequential[s_seq, s]) / ( - value(model.segment_fraction_per_season[s]) * value(model.days_per_period) + days_adjust = ( + value(model.time_season_sequential[s_seq, s]) + / value(model.segment_fraction_per_season[s]) ) for d in model.time_of_day: state = ( diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 18889b845..fa9a26b32 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -548,7 +548,7 @@ def limit_storage_fraction_constraint( if model.is_seasonal_storage[t]: # seasonal storage upper energy limit is absolute energy_level = model.v_seasonal_storage_level[r, p, s_seq, t, v] + energy_level * value( - model.time_season_sequential[s_seq, s] + model.time_season_sequential[s_seq, s] * value(model.days_per_period) ) expr = operator_expression(energy_level, Operator(op), energy_limit) From 495e26cf53b5516b810a3e016769c70f1afb15da Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 11:00:52 -0500 Subject: [PATCH 18/40] Remove erroneous fk from limit_storage_level_fraction --- data_files/example_dbs/materials.sql | 3 +-- data_files/example_dbs/morris_utopia.sql | 3 +-- data_files/example_dbs/seasonal_storage.sql | 3 +-- data_files/example_dbs/survival_curve.sql | 3 +-- data_files/example_dbs/test_system.sql | 3 +-- data_files/example_dbs/utopia.sql | 3 +-- data_files/temoa_schema_v4.sql | 3 +-- temoa/db_schema/temoa_schema_v4.sql | 3 +-- temoa/tutorial_assets/utopia.sql | 3 +-- 9 files changed, 9 insertions(+), 18 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 7db879b55..bb287f4e5 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -813,8 +813,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 78b051a28..91aa491e7 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -895,8 +895,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index dfdf77167..7beecb1dc 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -546,8 +546,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 473d0b03e..afbf85ac9 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -648,8 +648,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 1122a38f6..6cfdaf1b7 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -885,8 +885,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 38206dc91..4a969a995 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -893,8 +893,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 2a7064fb4..06f7f9e09 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -472,8 +472,7 @@ CREATE TABLE IF NOT EXISTS limit_storage_level_fraction region TEXT, period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 2f659c26b..eb3e4eac3 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -462,8 +462,7 @@ CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity_delta CREATE TABLE IF NOT EXISTS limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 5c5964480..240aeefd0 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -898,8 +898,7 @@ CREATE TABLE limit_seasonal_capacity_factor CREATE TABLE limit_storage_level_fraction ( region TEXT, - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT From 9f8ea11cd572f12f693ad83bdedfcd81803afe68 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 11:50:18 -0500 Subject: [PATCH 19/40] Update hours column of time_of_day to REAL not INTEGER --- data_files/example_dbs/materials.sql | 2 +- data_files/example_dbs/morris_utopia.sql | 2 +- data_files/example_dbs/seasonal_storage.sql | 2 +- data_files/example_dbs/survival_curve.sql | 2 +- data_files/example_dbs/test_system.sql | 2 +- data_files/example_dbs/utopia.sql | 2 +- data_files/temoa_schema_v4.sql | 2 +- temoa/db_schema/temoa_schema_v4.sql | 2 +- temoa/tutorial_assets/utopia.sql | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index bb287f4e5..bc7e18da2 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1347,7 +1347,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'morning',6); diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 91aa491e7..5c40dbade 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1385,7 +1385,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 7beecb1dc..9e48fa0bb 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1013,7 +1013,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'a',6); diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index afbf85ac9..4a7c1a1d5 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1110,7 +1110,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'d',24); diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 6cfdaf1b7..3c800571d 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1394,7 +1394,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',12); diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 4a969a995..8bc394623 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1382,7 +1382,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 06f7f9e09..a6d2364e1 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -927,7 +927,7 @@ CREATE TABLE IF NOT EXISTS time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); CREATE TABLE IF NOT EXISTS time_period diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index eb3e4eac3..b2533b211 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -911,7 +911,7 @@ CREATE TABLE IF NOT EXISTS time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); CREATE TABLE IF NOT EXISTS time_period diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 240aeefd0..17571f431 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1397,7 +1397,7 @@ CREATE TABLE time_of_day sequence INTEGER UNIQUE, tod TEXT PRIMARY KEY, - hours INTEGER NOT NULL DEFAULT 1, + hours REAL NOT NULL DEFAULT 1, notes TEXT ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); From 52981e02dfc9669e346277c1632e41218afa13de Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 14:22:19 -0500 Subject: [PATCH 20/40] Reinforce 0 to 1 constraint on segfrac --- data_files/example_dbs/materials.sql | 5 +++-- data_files/example_dbs/morris_utopia.sql | 5 +++-- data_files/example_dbs/seasonal_storage.sql | 5 +++-- data_files/example_dbs/stepped_demand.sql | 2 +- data_files/example_dbs/survival_curve.sql | 5 +++-- data_files/example_dbs/test_system.sql | 5 +++-- data_files/example_dbs/utopia.sql | 5 +++-- data_files/temoa_schema_v4.sql | 5 +++-- temoa/db_schema/temoa_schema_v4.sql | 5 +++-- temoa/tutorial_assets/utopia.sql | 7 ++++--- 10 files changed, 29 insertions(+), 20 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index bc7e18da2..156a0cfe5 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1381,7 +1381,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); INSERT INTO "time_season" VALUES(1,'autumn',0.25,NULL); @@ -1396,7 +1397,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 5c40dbade..ccbf37f72 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1419,7 +1419,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); INSERT INTO "time_season" VALUES(1,'winter',0.5,NULL); @@ -1433,7 +1434,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 9e48fa0bb..5dd96cbcf 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1044,7 +1044,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'charge',0.5,NULL); INSERT INTO "time_season" VALUES(1,'discharge',0.5,NULL); @@ -1057,7 +1058,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season_sequential" VALUES(1,'summer','charge',0.417808,NULL); INSERT INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',0.019178,NULL); diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index ff81864b2..8729b7853 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1124,7 +1124,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE TimePeriodType ( diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 4a7c1a1d5..e84aa40b5 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1145,7 +1145,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'s',1.0,NULL); @@ -1157,7 +1158,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 3c800571d..6249c4708 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1426,7 +1426,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'spring',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1441,7 +1442,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 8bc394623..ba78097b6 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1416,7 +1416,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1430,7 +1431,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index a6d2364e1..9978af396 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -1031,7 +1031,8 @@ CREATE TABLE IF NOT EXISTS time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE IF NOT EXISTS time_season_sequential @@ -1042,7 +1043,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index b2533b211..1a85dfc02 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -1015,7 +1015,8 @@ CREATE TABLE IF NOT EXISTS time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE IF NOT EXISTS time_season_sequential @@ -1026,7 +1027,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 17571f431..f92b94f53 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1431,7 +1431,8 @@ CREATE TABLE time_season season TEXT, segment_fraction REAL, notes TEXT, - PRIMARY KEY (season) + PRIMARY KEY (season), + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1444,7 +1445,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE TABLE time_season_to_sequential ( @@ -1457,7 +1458,7 @@ CREATE TABLE time_season_to_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (period, sequence, seas_seq, season), - CHECK (segment_fraction > 0) + CHECK (segment_fraction > 0 AND segment_fraction < 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; From 6c0d467b999515db653bd81bb857d8056b9a70f0 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 14:26:38 -0500 Subject: [PATCH 21/40] Remove erroneous season fk from output_storage_level --- data_files/example_dbs/materials.sql | 3 +-- data_files/example_dbs/morris_utopia.sql | 3 +-- data_files/example_dbs/seasonal_storage.sql | 3 +-- data_files/example_dbs/survival_curve.sql | 3 +-- data_files/example_dbs/test_system.sql | 3 +-- data_files/example_dbs/utopia.sql | 3 +-- data_files/temoa_schema_v4.sql | 3 +-- temoa/db_schema/temoa_schema_v4.sql | 3 +-- temoa/tutorial_assets/utopia.sql | 3 +-- 9 files changed, 9 insertions(+), 18 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 156a0cfe5..85f062e73 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1198,8 +1198,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index ccbf37f72..03cd2d2c0 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1233,8 +1233,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 5dd96cbcf..eb659550a 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -879,8 +879,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index e84aa40b5..eff700d61 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -979,8 +979,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 6249c4708..e44100bbe 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1242,8 +1242,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index ba78097b6..593a75ce7 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1230,8 +1230,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 9978af396..42880fd75 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -818,8 +818,7 @@ CREATE TABLE IF NOT EXISTS output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 1a85dfc02..164312c36 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -804,8 +804,7 @@ CREATE TABLE IF NOT EXISTS output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index f92b94f53..9976b7da0 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1244,8 +1244,7 @@ CREATE TABLE output_storage_level REFERENCES sector_label (sector), period INTEGER REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), + season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT From e9443567908203e6ff5e32e9596b9176aef96cb2 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 14:28:25 -0500 Subject: [PATCH 22/40] Fix season fk in output_curtailment --- data_files/example_dbs/materials.sql | 2 +- data_files/example_dbs/morris_utopia.sql | 2 +- data_files/example_dbs/seasonal_storage.sql | 2 +- data_files/example_dbs/survival_curve.sql | 2 +- data_files/example_dbs/test_system.sql | 2 +- data_files/example_dbs/utopia.sql | 2 +- data_files/temoa_schema_v4.sql | 2 +- temoa/db_schema/temoa_schema_v4.sql | 2 +- temoa/tutorial_assets/utopia.sql | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 85f062e73..7cec5bf03 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1054,7 +1054,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 03cd2d2c0..96cf2efad 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1089,7 +1089,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index eb659550a..d3b50c167 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -735,7 +735,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index eff700d61..f62a31a4c 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -835,7 +835,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index e44100bbe..f33d12453 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1098,7 +1098,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 593a75ce7..16ba0b096 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1086,7 +1086,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 42880fd75..33c6dcc33 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -700,7 +700,7 @@ CREATE TABLE IF NOT EXISTS output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 164312c36..b9031ac00 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -686,7 +686,7 @@ CREATE TABLE IF NOT EXISTS output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 9976b7da0..f65df81b0 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1094,7 +1094,7 @@ CREATE TABLE output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES time_period (period), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT From 9076cfcca06010bb576a44b57c213174fa4b50df Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 14:46:04 -0500 Subject: [PATCH 23/40] Fix storage fraction constraints in example dbs --- data_files/example_dbs/seasonal_storage.sql | 4 ++-- data_files/example_dbs/test_system.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index d3b50c167..4429cb1f0 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -557,8 +557,8 @@ CREATE TABLE limit_storage_level_fraction notes TEXT, PRIMARY KEY(region, season, tod, tech, operator) ); -INSERT INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor',2000,0.5,NULL); -INSERT INTO "limit_storage_level_fraction" VALUES('region','charge','b','dly_stor',2000,0.5,NULL); +INSERT INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor','e',0.5,NULL); +INSERT INTO "limit_storage_level_fraction" VALUES('region','charge','b','dly_stor','e',0.5,NULL); CREATE TABLE limit_tech_input_split ( region TEXT, diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index f33d12453..da3f24042 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -896,8 +896,8 @@ CREATE TABLE limit_storage_level_fraction notes TEXT, PRIMARY KEY(region, season, tod, tech, operator) ); -INSERT INTO "limit_storage_level_fraction" VALUES('R1','winter','day','E_BATT',2025,0.5,''); -INSERT INTO "limit_storage_level_fraction" VALUES('R2','summer','day','E_BATT',2020,0.5,''); +INSERT INTO "limit_storage_level_fraction" VALUES('R1','winter','day','E_BATT','e',0.5,''); +INSERT INTO "limit_storage_level_fraction" VALUES('R2','summer','day','E_BATT','e',0.5,''); CREATE TABLE limit_tech_input_split ( region TEXT, From 598f461ad50adaf651a35837988075cb4173dbf0 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 15:34:34 -0500 Subject: [PATCH 24/40] Fix 0 to 1 constraint on segment fractions --- data_files/example_dbs/materials.sql | 4 ++-- data_files/example_dbs/morris_utopia.sql | 4 ++-- data_files/example_dbs/seasonal_storage.sql | 4 ++-- data_files/example_dbs/stepped_demand.sql | 2 +- data_files/example_dbs/survival_curve.sql | 4 ++-- data_files/example_dbs/test_system.sql | 4 ++-- data_files/example_dbs/utopia.sql | 4 ++-- data_files/temoa_schema_v4.sql | 4 ++-- temoa/db_schema/temoa_schema_v4.sql | 4 ++-- temoa/tutorial_assets/utopia.sql | 6 +++--- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 7cec5bf03..dac7f5e08 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1381,7 +1381,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); INSERT INTO "time_season" VALUES(1,'autumn',0.25,NULL); @@ -1396,7 +1396,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 96cf2efad..12c07497e 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1419,7 +1419,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'summer',0.25,NULL); INSERT INTO "time_season" VALUES(1,'winter',0.5,NULL); @@ -1433,7 +1433,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index 4429cb1f0..d2478c855 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1044,7 +1044,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'charge',0.5,NULL); INSERT INTO "time_season" VALUES(1,'discharge',0.5,NULL); @@ -1057,7 +1057,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season_sequential" VALUES(1,'summer','charge',0.417808,NULL); INSERT INTO "time_season_sequential" VALUES(2,'sept_w1','discharge',0.019178,NULL); diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index 8729b7853..e459723f4 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1124,7 +1124,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE TimePeriodType ( diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index f62a31a4c..0f3657faa 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1145,7 +1145,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'s',1.0,NULL); @@ -1157,7 +1157,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index da3f24042..0000e3d3b 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1426,7 +1426,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'spring',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1441,7 +1441,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 16ba0b096..3a2198cc9 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1416,7 +1416,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1430,7 +1430,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 33c6dcc33..0f3ec0605 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -1031,7 +1031,7 @@ CREATE TABLE IF NOT EXISTS time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS time_season_sequential @@ -1042,7 +1042,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index b9031ac00..a4a4815f6 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -1015,7 +1015,7 @@ CREATE TABLE IF NOT EXISTS time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS time_season_sequential @@ -1026,7 +1026,7 @@ CREATE TABLE IF NOT EXISTS time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE IF NOT EXISTS myopic_efficiency diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index f65df81b0..6aa06468e 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1431,7 +1431,7 @@ CREATE TABLE time_season segment_fraction REAL, notes TEXT, PRIMARY KEY (season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); INSERT INTO "time_season" VALUES(0,'inter',0.25,NULL); INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); @@ -1444,7 +1444,7 @@ CREATE TABLE time_season_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (seas_seq), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE TABLE time_season_to_sequential ( @@ -1457,7 +1457,7 @@ CREATE TABLE time_season_to_sequential segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (period, sequence, seas_seq, season), - CHECK (segment_fraction > 0 AND segment_fraction < 1) + CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; From 11563a9efde9dc2b4bb49c0c7df1a95957ea9026 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Fri, 6 Mar 2026 15:35:06 -0500 Subject: [PATCH 25/40] Fix index construction for limit_storage_level_fraction and add proper checks --- temoa/components/storage.py | 39 ++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/temoa/components/storage.py b/temoa/components/storage.py index fa9a26b32..11f2692e0 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -13,6 +13,7 @@ from __future__ import annotations +from logging import getLogger from typing import TYPE_CHECKING from pyomo.environ import Constraint, value @@ -25,6 +26,9 @@ from ..types import ExprLike, Period, Region, Season, Technology, TimeOfDay, Vintage +logger = getLogger(__name__) + + # ============================================================================ # PYOMO INDEX SET FUNCTIONS # ============================================================================ @@ -65,16 +69,33 @@ def limit_storage_fraction_constraint_indices( model: TemoaModel, ) -> set[tuple[Region, Period, Season, TimeOfDay, Technology, Vintage, str]]: """Expand the period-free param set to include all valid process (period, vintage) combos.""" - param_keys = set(model.limit_storage_fraction_param_rsdt) - all_storage = set(model.storage_constraints_rpsdtv) | set( - model.seasonal_storage_constraints_rpsdtv + + bad_keys = set( + (r, s, d, t, op) + for r, s, d, t, op in model.limit_storage_fraction_param_rsdt + if (not model.is_seasonal_storage[t]) != (s in model.time_season) ) - result: set[tuple] = set() - for r, p, s, d, t, v in all_storage: - for op in model.operator: - if (r, s, d, t, op) in param_keys: - result.add((r, p, s, d, t, v, op)) - return result + if bad_keys: + msg = ( + "Bad keys identified in limit_storage_level_fraction table. " + "Regular season used for seasonal storage or sequential season " + f"used for diurnal storage. Bad keys: {bad_keys}" + ) + logger.error(msg) + raise ValueError(msg) + + all_storage_constraints = set( + model.storage_constraints_rpsdtv | model.seasonal_storage_constraints_rpsdtv + ) + valid_keys = set( + (r, p, s, d, t, v, op) + for r, s, d, t, op in model.limit_storage_fraction_param_rsdt + for p in model.time_optimize + for v in model.process_vintages.get((r, p, t), []) + if (r, p, s, d, t, v) in all_storage_constraints + ) + + return valid_keys # ============================================================================ From 44541479fb062908f1aa08f2a140d94a84053ae3 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 07:44:38 -0500 Subject: [PATCH 26/40] Remove period from deprecated cfp check --- temoa/model_checking/validators.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/temoa/model_checking/validators.py b/temoa/model_checking/validators.py index af3b95ea1..7ebf021fd 100644 --- a/temoa/model_checking/validators.py +++ b/temoa/model_checking/validators.py @@ -274,7 +274,6 @@ def validate_capacity_factor_process( model: TemoaModel, val: float, r: Region, - p: Period, s: Season, d: TimeOfDay, t: Technology, @@ -297,7 +296,6 @@ def validate_capacity_factor_process( return all( ( r in model.regions, - p in model.time_optimize, s in model.time_season, d in model.time_of_day, t in model.tech_with_capacity, From 71cffe73afb9deeee4c085943ac265b573b9d097 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 07:55:38 -0500 Subject: [PATCH 27/40] Update unit cost explorer tool --- temoa/utilities/unit_cost_explorer.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/temoa/utilities/unit_cost_explorer.py b/temoa/utilities/unit_cost_explorer.py index be9d0a336..6cafe9acb 100644 --- a/temoa/utilities/unit_cost_explorer.py +++ b/temoa/utilities/unit_cost_explorer.py @@ -124,12 +124,17 @@ } ) # QA the total -print(f'quality check. Total of all segment_fraction: {sum(model.segment_fraction.values()):0.3f}') +print( + 'quality check. Total of all segment_fraction: ' + f'{sum(value(v) for v in model.segment_fraction.values()):0.3f}' +) model.process_life_frac.construct(data={('A', 2020, 'battery', 2020): 1.0}) # More VARS model.v_storage_level.construct() -model.segment_fraction_per_season.construct() +model.segment_fraction_per_season.construct( + data=seasonal_fractions +) model.is_seasonal_storage['battery'] = False upper_limit = storage_energy_upper_bound_constraint(model, 'A', 2020, 'winter', 1, 'battery', 2020) From ba2b2a0dbf59a90e9ef49b5dfc0c25575302e756 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 07:56:34 -0500 Subject: [PATCH 28/40] Update sql data validation --- data_files/example_dbs/materials.sql | 5 +++-- data_files/example_dbs/morris_utopia.sql | 5 +++-- data_files/example_dbs/seasonal_storage.sql | 5 +++-- data_files/example_dbs/survival_curve.sql | 5 +++-- data_files/example_dbs/test_system.sql | 5 +++-- data_files/example_dbs/utopia.sql | 5 +++-- data_files/temoa_schema_v4.sql | 5 +++-- temoa/db_schema/temoa_schema_v4.sql | 5 +++-- temoa/tutorial_assets/utopia.sql | 5 +++-- 9 files changed, 27 insertions(+), 18 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index dac7f5e08..620620814 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1347,7 +1347,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'morning',6); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'afternoon',6); @@ -1378,7 +1379,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 12c07497e..9f01e7583 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1385,7 +1385,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); @@ -1416,7 +1417,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index d2478c855..a00d7487d 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1013,7 +1013,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'a',6); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'b',6); @@ -1041,7 +1042,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 0f3657faa..492463f43 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1110,7 +1110,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(0,'d',24); CREATE TABLE time_period @@ -1142,7 +1143,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 0000e3d3b..b4debc381 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1394,7 +1394,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',12); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',12); @@ -1423,7 +1424,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 3a2198cc9..576232f78 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1382,7 +1382,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); @@ -1413,7 +1414,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 0f3ec0605..522921bc3 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -927,7 +927,8 @@ CREATE TABLE IF NOT EXISTS time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); CREATE TABLE IF NOT EXISTS time_period ( @@ -1028,7 +1029,7 @@ CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index a4a4815f6..ea6f43987 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -911,7 +911,8 @@ CREATE TABLE IF NOT EXISTS time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); CREATE TABLE IF NOT EXISTS time_period ( @@ -1012,7 +1013,7 @@ CREATE TABLE IF NOT EXISTS time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 6aa06468e..a27001b0f 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1397,7 +1397,8 @@ CREATE TABLE time_of_day tod TEXT PRIMARY KEY, hours REAL NOT NULL DEFAULT 1, - notes TEXT + notes TEXT, + CHECK (hours > 0) ); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); @@ -1428,7 +1429,7 @@ CREATE TABLE time_season ( sequence INTEGER, season TEXT, - segment_fraction REAL, + segment_fraction REAL NOT NULL, notes TEXT, PRIMARY KEY (season), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) From 4ff38140a2404945ea68973f5f9a6e84d6173b13 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 07:58:57 -0500 Subject: [PATCH 29/40] Add 0 to 1 sql check on limit_storage_level_fraction --- data_files/example_dbs/materials.sql | 1 + data_files/example_dbs/morris_utopia.sql | 1 + data_files/example_dbs/seasonal_storage.sql | 1 + data_files/example_dbs/survival_curve.sql | 1 + data_files/example_dbs/test_system.sql | 1 + data_files/example_dbs/utopia.sql | 1 + data_files/temoa_schema_v4.sql | 1 + temoa/db_schema/temoa_schema_v4.sql | 1 + temoa/tutorial_assets/utopia.sql | 1 + 9 files changed, 9 insertions(+) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index 620620814..b5aaeed80 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -822,6 +822,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 9f01e7583..2ea2762d7 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -904,6 +904,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index a00d7487d..d5eb20917 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -555,6 +555,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); INSERT INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor','e',0.5,NULL); diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 492463f43..11487f906 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -657,6 +657,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index b4debc381..022c525be 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -894,6 +894,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); INSERT INTO "limit_storage_level_fraction" VALUES('R1','winter','day','E_BATT','e',0.5,''); diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index 576232f78..fe4b22135 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -902,6 +902,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 522921bc3..5e19f1363 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -483,6 +483,7 @@ CREATE TABLE IF NOT EXISTS limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, period, season, tod, tech, vintage, operator) ); CREATE TABLE IF NOT EXISTS limit_activity diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index ea6f43987..b07012e0f 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -471,6 +471,7 @@ CREATE TABLE IF NOT EXISTS limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE IF NOT EXISTS limit_activity diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index a27001b0f..15ed2720b 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -907,6 +907,7 @@ CREATE TABLE limit_storage_level_fraction REFERENCES operator (operator), fraction REAL, notes TEXT, + CHECK (fraction >= 0 AND fraction <= 1), PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE limit_tech_input_split From f6eba06630aceb47618d99699e8bb8a4b90068af Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 09:03:06 -0500 Subject: [PATCH 30/40] Change some param domains to PositiveReals to avoid divide-by-zero errors --- temoa/core/model.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/temoa/core/model.py b/temoa/core/model.py index 3ad0d5aff..4a658320b 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -18,6 +18,7 @@ Constraint, Integers, NonNegativeReals, + PositiveReals, Objective, Param, minimize, @@ -336,8 +337,8 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Basic period construction self.time_sequencing = Set() # How do states carry between time segments? self.period_length = Param(self.time_optimize, initialize=time.param_period_length) - self.days_per_period = Param() - self.time_of_day_hours = Param(self.time_of_day, default=1) + self.days_per_period = Param(domain=PositiveReals, default=365.0) + self.time_of_day_hours = Param(self.time_of_day, domain=PositiveReals, default=1.0) self.segment_fraction_per_season = Param(self.time_season) self.segment_fraction = Param(self.time_season, self.time_of_day, mutable=True) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) @@ -408,7 +409,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.tech_all, self.vintage_all, self.commodity_carrier, - within=NonNegativeReals, + within=PositiveReals, validate=validate_efficiency, ) self.validate_used_efficiency_indices = BuildAction( @@ -423,7 +424,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.tech_all, self.vintage_all, self.commodity_carrier, - within=NonNegativeReals, + within=PositiveReals, default=1, ) From 17a0ead9925feb74c1d697a975229935469dd120 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 09:03:34 -0500 Subject: [PATCH 31/40] Make time_of_day consistent with test sql style --- tests/testing_data/annualised_demand.sql | 2 +- tests/testing_data/emissions.sql | 4 ++-- tests/testing_data/materials.sql | 18 +++++------------- tests/testing_data/mediumville.sql | 4 ++-- tests/testing_data/seasonal_storage.sql | 8 ++++---- tests/testing_data/simple_linked_tech.sql | 2 +- tests/testing_data/storageville.sql | 10 +++++----- tests/testing_data/survival_curve.sql | 2 +- tests/testing_data/test_system.sql | 4 ++-- tests/testing_data/utopia_data.sql | 4 ++-- 10 files changed, 25 insertions(+), 33 deletions(-) diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index c841716cb..76d910927 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -45,7 +45,7 @@ REPLACE INTO "technology" VALUES('non_annual','p','energy',NULL,NULL,0,0,0,0,0,0 REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'D1',24); +REPLACE INTO "time_of_day" VALUES(0,'D1',24,NULL); REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2001,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 67b6c3631..0aaa11b02 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -86,8 +86,8 @@ REPLACE INTO "technology" VALUES('TechEndOfLife','p','energy',NULL,NULL,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'TOD1',12); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'TOD2',12); +REPLACE INTO "time_of_day" VALUES(1,'TOD1',12,NULL); +REPLACE INTO "time_of_day" VALUES(2,'TOD2',12,NULL); REPLACE INTO "time_period" VALUES(1,1999,'e'); REPLACE INTO "time_period" VALUES(2,2000,'f'); REPLACE INTO "time_period" VALUES(3,2005,'f'); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index 8ffc34c90..5a357e4df 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -362,10 +362,10 @@ REPLACE INTO "technology" VALUES('ELEC_INTERTIE','p','electricity',NULL,NULL,0,0 REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'morning',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'afternoon',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'evening',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(4,'overnight',6); +REPLACE INTO "time_of_day" VALUES(1,'morning',6,NULL); +REPLACE INTO "time_of_day" VALUES(2,'afternoon',6,NULL); +REPLACE INTO "time_of_day" VALUES(3,'evening',6,NULL); +REPLACE INTO "time_of_day" VALUES(4,'overnight',6,NULL); REPLACE INTO "time_period" VALUES(1,1990,'e'); REPLACE INTO "time_period" VALUES(2,2000,'f'); REPLACE INTO "time_period" VALUES(3,2010,'f'); @@ -376,12 +376,4 @@ REPLACE INTO "time_period_type" VALUES('f','future'); REPLACE INTO "time_season" VALUES(1,'summer',0.25,NULL); REPLACE INTO "time_season" VALUES(2,'autumn',0.25,NULL); REPLACE INTO "time_season" VALUES(3,'winter',0.25,NULL); -REPLACE INTO "time_season" VALUES(4,'spring',0.25,NULL); -REPLACE INTO "time_season" VALUES(5,'summer',0.25,NULL); -REPLACE INTO "time_season" VALUES(6,'autumn',0.25,NULL); -REPLACE INTO "time_season" VALUES(7,'winter',0.25,NULL); -REPLACE INTO "time_season" VALUES(8,'spring',0.25,NULL); -REPLACE INTO "time_season" VALUES(9,'summer',0.25,NULL); -REPLACE INTO "time_season" VALUES(10,'autumn',0.25,NULL); -REPLACE INTO "time_season" VALUES(11,'winter',0.25,NULL); -REPLACE INTO "time_season" VALUES(12,'spring',0.25,NULL); +REPLACE INTO "time_season" VALUES(4,'spring',0.25,NULL); \ No newline at end of file diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 8a8357ef1..b71e7c303 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -180,8 +180,8 @@ REPLACE INTO "technology" VALUES('GeoHeater','p','residential','hydro','',0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'d1',12); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'d2',12); +REPLACE INTO "time_of_day" VALUES(1,'d1',12,NULL); +REPLACE INTO "time_of_day" VALUES(2,'d2',12,NULL); REPLACE INTO "time_period" VALUES(1,2020,'e'); REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 1b7e62bfb..24f4a5b56 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -60,10 +60,10 @@ REPLACE INTO "technology" VALUES('demand','p','electricity',NULL,NULL,0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'a',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'b',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'c',6); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'d',6); +REPLACE INTO "time_of_day" VALUES(0,'a',6,NULL); +REPLACE INTO "time_of_day" VALUES(1,'b',6,NULL); +REPLACE INTO "time_of_day" VALUES(2,'c',6,NULL); +REPLACE INTO "time_of_day" VALUES(3,'d',6,NULL); REPLACE INTO "time_period" VALUES(0,2000,'f'); REPLACE INTO "time_period" VALUES(1,2005,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index 25dbf834a..25760ebc9 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -48,7 +48,7 @@ REPLACE INTO "technology" VALUES('FAKE_SOURCE','p','supply',NULL,NULL,1,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',24); +REPLACE INTO "time_of_day" VALUES(1,'day',24,NULL); REPLACE INTO "time_period" VALUES(0,1995,'e'); REPLACE INTO "time_period" VALUES(1,2000,'f'); REPLACE INTO "time_period" VALUES(2,2005,'f'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index 61073e1e9..f1a3e2203 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -63,11 +63,11 @@ REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'d1', 4.8); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'d2', 4.8); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(3,'d3', 4.8); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(4,'d4', 4.8); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(5,'d5', 4.8); +REPLACE INTO "time_of_day" VALUES(1,'d1', 4.8, NULL); +REPLACE INTO "time_of_day" VALUES(2,'d2', 4.8, NULL); +REPLACE INTO "time_of_day" VALUES(3,'d3', 4.8, NULL); +REPLACE INTO "time_of_day" VALUES(4,'d4', 4.8, NULL); +REPLACE INTO "time_of_day" VALUES(5,'d5', 4.8, NULL); REPLACE INTO "time_period" VALUES(1,2020,'e'); REPLACE INTO "time_period" VALUES(2,2025,'f'); REPLACE INTO "time_period" VALUES(3,2030,'f'); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index fb258e566..d81a436cb 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -157,7 +157,7 @@ REPLACE INTO "technology" VALUES('tech_future','p','energy',NULL,NULL,0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(0,'d',24); +REPLACE INTO "time_of_day" VALUES(0,'d',24,NULL); REPLACE INTO "time_period" VALUES(-2,1994,'e'); REPLACE INTO "time_period" VALUES(-1,2010,'e'); REPLACE INTO "time_period" VALUES(0,2025,'f'); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index 070a515f0..9e188ddb6 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -441,8 +441,8 @@ REPLACE INTO "technology" VALUES('E_TRANS','p','electric','','',0,0,0,0,0,0,1,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',12); -REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',12); +REPLACE INTO "time_of_day" VALUES(1,'day',12,NULL); +REPLACE INTO "time_of_day" VALUES(2,'night',12,NULL); REPLACE INTO "time_period" VALUES(1,2015,'e'); REPLACE INTO "time_period" VALUES(2,2020,'f'); REPLACE INTO "time_period" VALUES(3,2025,'f'); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index d0ebbd4e9..f25bbb875 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -429,8 +429,8 @@ REPLACE INTO "technology" VALUES('TXG','p','transport','petroleum','',0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); -INSERT INTO "time_of_day" (sequence, tod, hours) VALUES(2,'night',8); +INSERT INTO "time_of_day" VALUES(1,'day',16,NULL); +INSERT INTO "time_of_day" VALUES(2,'night',8,NULL); REPLACE INTO "time_period" VALUES(1,1960,'e'); REPLACE INTO "time_period" VALUES(2,1970,'e'); REPLACE INTO "time_period" VALUES(3,1980,'e'); From ec2f3af66fde1b231a4ab1b7d7374b15b7ba0fd8 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 15:07:28 -0500 Subject: [PATCH 32/40] Remove redundant time_season entries from survival_curve test sql --- tests/testing_data/survival_curve.sql | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index d81a436cb..a0f32dc16 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -170,8 +170,3 @@ REPLACE INTO "time_period" VALUES(6,2055,'f'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); REPLACE INTO "time_period_type" VALUES('f','future'); REPLACE INTO "time_season" VALUES(0,'s',1.0,NULL); -REPLACE INTO "time_season" VALUES(1,'s',1.0,NULL); -REPLACE INTO "time_season" VALUES(2,'s',1.0,NULL); -REPLACE INTO "time_season" VALUES(3,'s',1.0,NULL); -REPLACE INTO "time_season" VALUES(4,'s',1.0,NULL); -REPLACE INTO "time_season" VALUES(5,'s',1.0,NULL); From 866a3a65baa72bdbf0bddd5459663a40c87d8640 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 15:08:35 -0500 Subject: [PATCH 33/40] Change INSERT to REPLACE in time_of_day for utopia test --- tests/testing_data/utopia_data.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index f25bbb875..691376dd1 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -429,8 +429,8 @@ REPLACE INTO "technology" VALUES('TXG','p','transport','petroleum','',0,0,0,0,0, REPLACE INTO "technology_type" VALUES('p','production technology'); REPLACE INTO "technology_type" VALUES('pb','baseload production technology'); REPLACE INTO "technology_type" VALUES('ps','storage production technology'); -INSERT INTO "time_of_day" VALUES(1,'day',16,NULL); -INSERT INTO "time_of_day" VALUES(2,'night',8,NULL); +REPLACE INTO "time_of_day" VALUES(1,'day',16,NULL); +REPLACE INTO "time_of_day" VALUES(2,'night',8,NULL); REPLACE INTO "time_period" VALUES(1,1960,'e'); REPLACE INTO "time_period" VALUES(2,1970,'e'); REPLACE INTO "time_period" VALUES(3,1980,'e'); From e37e8cf9e7e71f24c9381da88e438829c8ff2809 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sat, 7 Mar 2026 15:28:48 -0500 Subject: [PATCH 34/40] Make sequence column unique in season tables --- data_files/example_dbs/materials.sql | 4 ++-- data_files/example_dbs/morris_utopia.sql | 4 ++-- data_files/example_dbs/seasonal_storage.sql | 4 ++-- data_files/example_dbs/stepped_demand.sql | 2 +- data_files/example_dbs/survival_curve.sql | 4 ++-- data_files/example_dbs/test_system.sql | 4 ++-- data_files/example_dbs/utopia.sql | 4 ++-- data_files/temoa_schema_v4.sql | 4 ++-- temoa/db_schema/temoa_schema_v4.sql | 4 ++-- temoa/tutorial_assets/utopia.sql | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/data_files/example_dbs/materials.sql b/data_files/example_dbs/materials.sql index b5aaeed80..da4d7bc08 100644 --- a/data_files/example_dbs/materials.sql +++ b/data_files/example_dbs/materials.sql @@ -1378,7 +1378,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1392,7 +1392,7 @@ INSERT INTO "time_season" VALUES(3,'spring',0.25,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/example_dbs/morris_utopia.sql b/data_files/example_dbs/morris_utopia.sql index 2ea2762d7..c8e6bf970 100644 --- a/data_files/example_dbs/morris_utopia.sql +++ b/data_files/example_dbs/morris_utopia.sql @@ -1416,7 +1416,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1429,7 +1429,7 @@ INSERT INTO "time_season" VALUES(2,'inter',0.25,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/example_dbs/seasonal_storage.sql b/data_files/example_dbs/seasonal_storage.sql index d5eb20917..68da03a75 100644 --- a/data_files/example_dbs/seasonal_storage.sql +++ b/data_files/example_dbs/seasonal_storage.sql @@ -1041,7 +1041,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1053,7 +1053,7 @@ INSERT INTO "time_season" VALUES(1,'discharge',0.5,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/example_dbs/stepped_demand.sql b/data_files/example_dbs/stepped_demand.sql index e459723f4..bfd228b26 100644 --- a/data_files/example_dbs/stepped_demand.sql +++ b/data_files/example_dbs/stepped_demand.sql @@ -1117,7 +1117,7 @@ INSERT INTO TimeSeason VALUES(2050,2,'summer',NULL); INSERT INTO TimeSeason VALUES(2050,3,'winter',NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season (season), diff --git a/data_files/example_dbs/survival_curve.sql b/data_files/example_dbs/survival_curve.sql index 11487f906..11fd02bf0 100644 --- a/data_files/example_dbs/survival_curve.sql +++ b/data_files/example_dbs/survival_curve.sql @@ -1142,7 +1142,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1153,7 +1153,7 @@ INSERT INTO "time_season" VALUES(0,'s',1.0,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/example_dbs/test_system.sql b/data_files/example_dbs/test_system.sql index 022c525be..c43d9d17e 100644 --- a/data_files/example_dbs/test_system.sql +++ b/data_files/example_dbs/test_system.sql @@ -1423,7 +1423,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1437,7 +1437,7 @@ INSERT INTO "time_season" VALUES(3,'winter',0.25,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/example_dbs/utopia.sql b/data_files/example_dbs/utopia.sql index fe4b22135..7fdf117c0 100644 --- a/data_files/example_dbs/utopia.sql +++ b/data_files/example_dbs/utopia.sql @@ -1413,7 +1413,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1426,7 +1426,7 @@ INSERT INTO "time_season" VALUES(2,'winter',0.5,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 5e19f1363..e53131f85 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -1028,7 +1028,7 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1038,7 +1038,7 @@ CREATE TABLE IF NOT EXISTS time_season CREATE TABLE IF NOT EXISTS time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index b07012e0f..90a39108c 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -1012,7 +1012,7 @@ CREATE TABLE IF NOT EXISTS output_cost CREATE TABLE IF NOT EXISTS time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1022,7 +1022,7 @@ CREATE TABLE IF NOT EXISTS time_season CREATE TABLE IF NOT EXISTS time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 15ed2720b..aeadbd9e5 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1428,7 +1428,7 @@ INSERT INTO "time_period_type" VALUES('e','existing vintages'); INSERT INTO "time_period_type" VALUES('f','future'); CREATE TABLE time_season ( - sequence INTEGER, + sequence INTEGER UNIQUE, season TEXT, segment_fraction REAL NOT NULL, notes TEXT, @@ -1440,7 +1440,7 @@ INSERT INTO "time_season" VALUES(1,'summer',0.25,NULL); INSERT INTO "time_season" VALUES(2,'winter',0.5,NULL); CREATE TABLE time_season_sequential ( - sequence INTEGER, + sequence INTEGER UNIQUE, seas_seq TEXT, season TEXT REFERENCES time_season(season), segment_fraction REAL NOT NULL, From 74da33a6e95c37482943cc9b623db5941d1861f9 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sun, 8 Mar 2026 12:58:53 -0400 Subject: [PATCH 35/40] Update data_files temoa_schema_v4 --- data_files/temoa_schema_v4.sql | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index e53131f85..90a39108c 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -60,8 +60,6 @@ CREATE TABLE IF NOT EXISTS capacity_credit CREATE TABLE IF NOT EXISTS capacity_factor_process ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tod TEXT @@ -71,14 +69,12 @@ CREATE TABLE IF NOT EXISTS capacity_factor_process vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech, vintage), + PRIMARY KEY (region, season, tod, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS capacity_factor_tech ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tod TEXT @@ -87,7 +83,7 @@ CREATE TABLE IF NOT EXISTS capacity_factor_tech REFERENCES technology (tech), factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, tech), + PRIMARY KEY (region, season, tod, tech), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS capacity_to_activity @@ -212,8 +208,6 @@ CREATE TABLE IF NOT EXISTS demand CREATE TABLE IF NOT EXISTS demand_specific_distribution ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tod TEXT @@ -222,7 +216,7 @@ CREATE TABLE IF NOT EXISTS demand_specific_distribution REFERENCES commodity (name), dsd REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, demand_name), + PRIMARY KEY (region, season, tod, demand_name), CHECK (dsd >= 0 AND dsd <= 1) ); CREATE TABLE IF NOT EXISTS end_of_life_output @@ -259,8 +253,6 @@ CREATE TABLE IF NOT EXISTS efficiency CREATE TABLE IF NOT EXISTS efficiency_variable ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tod TEXT @@ -275,7 +267,7 @@ CREATE TABLE IF NOT EXISTS efficiency_variable REFERENCES commodity (name), efficiency REAL, notes TEXT, - PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), CHECK (efficiency > 0) ); CREATE TABLE IF NOT EXISTS emission_activity @@ -470,21 +462,17 @@ CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity_delta CREATE TABLE IF NOT EXISTS limit_storage_level_fraction ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT, tod TEXT REFERENCES time_of_day (tod), tech TEXT REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), operator TEXT NOT NULL DEFAULT "le" REFERENCES operator (operator), fraction REAL, notes TEXT, CHECK (fraction >= 0 AND fraction <= 1), - PRIMARY KEY(region, period, season, tod, tech, vintage, operator) + PRIMARY KEY(region, season, tod, tech, operator) ); CREATE TABLE IF NOT EXISTS limit_activity ( @@ -595,8 +583,6 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor ( region TEXT REFERENCES region (region), - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tech TEXT @@ -605,7 +591,7 @@ CREATE TABLE IF NOT EXISTS limit_seasonal_capacity_factor REFERENCES operator (operator), factor REAL, notes TEXT, - PRIMARY KEY(region, period, season, tech, operator) + PRIMARY KEY(region, season, tech, operator) ); CREATE TABLE IF NOT EXISTS limit_tech_input_split ( @@ -865,8 +851,6 @@ CREATE TABLE IF NOT EXISTS region CREATE TABLE IF NOT EXISTS reserve_capacity_derate ( region TEXT, - period INTEGER - REFERENCES time_period (period), season TEXT REFERENCES time_season (season), tech TEXT @@ -874,7 +858,7 @@ CREATE TABLE IF NOT EXISTS reserve_capacity_derate vintage INTEGER, factor REAL, notes TEXT, - PRIMARY KEY (region, period, season, tech, vintage), + PRIMARY KEY (region, season, tech, vintage), CHECK (factor >= 0 AND factor <= 1) ); CREATE TABLE IF NOT EXISTS storage_duration From ead3a397b80aff83ff022c32e74af6a385543fde Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Sun, 8 Mar 2026 13:05:36 -0400 Subject: [PATCH 36/40] adapting migrator to changes in v4 schema and adding test for migration --- temoa/tutorial_assets/utopia.sql | 13 --- temoa/utilities/db_migration_v3_1_to_v4.py | 102 +++++++++++++++--- temoa/utilities/sql_migration_v3_1_to_v4.py | 114 +++++++++++++++++--- tests/test_v4_migration.py | 105 ++++++++++++++++++ tests/testing_data/migration_v3_1_mock.sql | 30 ++++++ 5 files changed, 327 insertions(+), 37 deletions(-) create mode 100644 tests/test_v4_migration.py create mode 100644 tests/testing_data/migration_v3_1_mock.sql diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index aeadbd9e5..1b8ce25a0 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1448,18 +1448,5 @@ CREATE TABLE time_season_sequential PRIMARY KEY (seas_seq), CHECK (segment_fraction >= 0 AND segment_fraction <= 1) ); -CREATE TABLE time_season_to_sequential -( - period INTEGER - REFERENCES time_period (period), - sequence INTEGER, - seas_seq TEXT, - season TEXT - REFERENCES time_season (season), - segment_fraction REAL NOT NULL, - notes TEXT, - PRIMARY KEY (period, sequence, seas_seq, season), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); COMMIT; diff --git a/temoa/utilities/db_migration_v3_1_to_v4.py b/temoa/utilities/db_migration_v3_1_to_v4.py index 55e6e2e67..be294bb7b 100644 --- a/temoa/utilities/db_migration_v3_1_to_v4.py +++ b/temoa/utilities/db_migration_v3_1_to_v4.py @@ -149,19 +149,38 @@ def migrate_all(args) -> None: r[0] for r in con_new.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall() ] - print('DEBUG mapping samples:') - for t in ( - 'TimeSeason', - 'time_season', - 'TimeSeasonSequential', - 'time_season_sequential', - 'SegFrac', - ): - print(f' {t} -> {map_token_no_cascade(t)}') total = 0 for old in old_tables: if old.lower().startswith('sqlite_'): continue + if old in ( + 'MetaData', + 'MetaDataReal', + 'TimeSeason', + 'time_season', + 'time_of_day', + 'time_season_sequential', + 'TimeSeasonSequential', + ): + continue + if old == 'CapacityFactorProcess': + # Special case: aggregate across periods + old_data = con_old.execute( + 'SELECT region, season, tod, tech, vintage, AVG(factor) ' + 'FROM CapacityFactorProcess ' + 'GROUP BY region, season, tod, tech, vintage' + ).fetchall() + if old_data: + con_new.executemany( + 'INSERT OR REPLACE INTO capacity_factor_process ' + '(region, season, tod, tech, vintage, factor) ' + 'VALUES (?, ?, ?, ?, ?, ?)', + old_data, + ) + print(f'Aggregated {len(old_data)} rows: {old} -> capacity_factor_process') + total += len(old_data) + continue + new = map_token_no_cascade(old) if new not in new_tables: candidates = [t for t in new_tables if t == new or t.startswith(new) or new in t] @@ -175,10 +194,69 @@ def migrate_all(args) -> None: print(f'Copied {n} rows: {old} -> {new}') total += n except Exception: - import traceback + print(f'Error migrating {old} -> {new}') + raise + + # --- Custom logic for restructured tables (Seasons/TOD) --- + print('Processing custom migration logic for seasons and time-of-day...') + + # 1. time_season (aggregate from TimeSegmentFraction) + try: + old_data = con_old.execute( + 'SELECT season, SUM(segfrac) / COUNT(DISTINCT period) ' + 'FROM TimeSegmentFraction GROUP BY season' + ).fetchall() + if old_data: + con_new.executemany( + 'INSERT OR REPLACE INTO time_season (season, segment_fraction) VALUES (?, ?)', + old_data, + ) + print(f'Propagated {len(old_data)} seasons to time_season.') + total += len(old_data) + except sqlite3.OperationalError: + print('WARNING: Could not migrate seasons from TimeSegmentFraction.') + + # 2. time_of_day (aggregate from TimeSegmentFraction) + try: + old_data = con_old.execute( + 'SELECT tod, SUM(segfrac) FROM TimeSegmentFraction GROUP BY tod' + ).fetchall() + if old_data: + num_periods = ( + con_old.execute( + 'SELECT COUNT(DISTINCT period) FROM TimeSegmentFraction' + ).fetchone()[0] + or 1 + ) + normalized_data = [(r[0], (r[1] / num_periods) * 24.0) for r in old_data] + con_new.executemany( + 'INSERT OR REPLACE INTO time_of_day (tod, hours) VALUES (?, ?)', normalized_data + ) + print(f'Propagated {len(normalized_data)} time-of-day slots to time_of_day.') + total += len(normalized_data) + except sqlite3.OperationalError: + print('WARNING: Could not migrate time_of_day from TimeSegmentFraction.') - print(f'Error migrating {old} -> {new}:') - traceback.print_exc() + # 3. time_season_sequential (aggregate from TimeSeasonSequential) + try: + first_period = con_old.execute('SELECT MIN(period) FROM TimeSeasonSequential').fetchone()[0] + if first_period: + old_data = con_old.execute( + 'SELECT tss.seas_seq, tss.season, (tss.num_days / 365.25) ' + 'FROM TimeSeasonSequential tss ' + 'WHERE tss.period = ?', + (first_period,), + ).fetchall() + if old_data: + con_new.executemany( + 'INSERT OR REPLACE INTO time_season_sequential ' + '(seas_seq, season, segment_fraction) VALUES (?, ?, ?)', + old_data, + ) + print(f'Propagated {len(old_data)} sequential seasons to time_season_sequential.') + total += len(old_data) + except (sqlite3.OperationalError, TypeError): + pass # ensure metadata version bumped cur = con_new.cursor() diff --git a/temoa/utilities/sql_migration_v3_1_to_v4.py b/temoa/utilities/sql_migration_v3_1_to_v4.py index f888d28e6..357e2f17e 100644 --- a/temoa/utilities/sql_migration_v3_1_to_v4.py +++ b/temoa/utilities/sql_migration_v3_1_to_v4.py @@ -165,23 +165,42 @@ def migrate_dump_to_sqlite(args) -> None: if not r[0].lower().startswith('sqlite_') ] - if args.debug: - print('DEBUG Mapping samples:') - for t in ( + # --- 3. Programmatically copy data --- + total_rows_copied = 0 + for old_table_name in old_tables: + if old_table_name in ( + 'MetaData', + 'MetaDataReal', 'TimeSeason', 'time_season', - 'TimeSeasonSequential', + 'time_of_day', 'time_season_sequential', - 'SegFrac', - 'segfrac', + 'TimeSeasonSequential', ): - print(f' {t} -> {map_token_no_cascade(t)}') - print('\nDEBUG Old DB tables:', old_tables) - print('DEBUG New DB tables:', new_db_tables) + if args.debug: + print(f'DEBUG: Skipping {old_table_name} (handled by custom logic)') + continue + + if old_table_name == 'CapacityFactorProcess': + # Special case: aggregate across periods + old_data = con_old_in_memory.execute( + 'SELECT region, season, tod, tech, vintage, AVG(factor) ' + 'FROM CapacityFactorProcess ' + 'GROUP BY region, season, tod, tech, vintage' + ).fetchall() + if old_data: + con_new_in_memory.executemany( + 'INSERT OR REPLACE INTO capacity_factor_process ' + '(region, season, tod, tech, vintage, factor) ' + 'VALUES (?, ?, ?, ?, ?, ?)', + old_data, + ) + print( + f'Aggregated {len(old_data)} rows: {old_table_name} -> capacity_factor_process' + ) + total_rows_copied += len(old_data) + continue - # --- 3. Programmatically copy data --- - total_rows_copied = 0 - for old_table_name in old_tables: mapped_new_table_name = map_table_name(old_table_name) if mapped_new_table_name not in new_db_tables: @@ -265,6 +284,77 @@ def migrate_dump_to_sqlite(args) -> None: print(f'Copied {rows_copied_this_table} rows: {old_table_name} -> {mapped_new_table_name}') total_rows_copied += rows_copied_this_table + # --- 3b. Custom logic for restructured tables (Seasons/TOD) --- + print('Processing custom migration logic for seasons and time-of-day...') + + # 1. time_season (aggregate from TimeSegmentFraction) + try: + # v3.1: TimeSegmentFraction(period, season, tod, segfrac) + # v4: time_season(season, segment_fraction) + old_data = con_old_in_memory.execute( + 'SELECT season, SUM(segfrac) / COUNT(DISTINCT period) ' + 'FROM TimeSegmentFraction GROUP BY season' + ).fetchall() + if old_data: + con_new_in_memory.executemany( + 'INSERT OR REPLACE INTO time_season (season, segment_fraction) VALUES (?, ?)', + old_data, + ) + print(f'Propagated {len(old_data)} seasons to time_season.') + except sqlite3.OperationalError: + print('WARNING: Could not migrate seasons from TimeSegmentFraction (table missing?)') + + # 2. time_of_day (aggregate from TimeSegmentFraction) + try: + # v3.1: TimeSegmentFraction(period, season, tod, segfrac) -> + # tod_weights = SUM(segfrac) over season + # v4: time_of_day(tod, hours) + old_data = con_old_in_memory.execute( + 'SELECT tod, SUM(segfrac) FROM TimeSegmentFraction GROUP BY tod' + ).fetchall() + if old_data: + num_periods = ( + con_old_in_memory.execute( + 'SELECT COUNT(DISTINCT period) FROM TimeSegmentFraction' + ).fetchone()[0] + or 1 + ) + # Normalize to 24 hours + normalized_data = [(r[0], (r[1] / num_periods) * 24.0) for r in old_data] + con_new_in_memory.executemany( + 'INSERT OR REPLACE INTO time_of_day (tod, hours) VALUES (?, ?)', + normalized_data, + ) + print(f'Propagated {len(normalized_data)} time-of-day slots to time_of_day.') + except sqlite3.OperationalError: + print('WARNING: Could not migrate time_of_day from TimeSegmentFraction.') + + # 3. time_season_sequential (aggregate from TimeSeasonSequential and TimeSegmentFraction) + # This is tricky because v3.1 had period-dependent sequential seasons. + # We take the first available period's definition. + try: + # v3.1: TimeSeasonSequential(period, sequence, seas_seq, season, num_days) + # v4: time_season_sequential(seas_seq, season, segment_fraction) + first_period = con_old_in_memory.execute( + 'SELECT MIN(period) FROM TimeSeasonSequential' + ).fetchone()[0] + if first_period: + old_data = con_old_in_memory.execute( + 'SELECT tss.seas_seq, tss.season, (tss.num_days / 365.25) ' + 'FROM TimeSeasonSequential tss ' + 'WHERE tss.period = ?', + (first_period,), + ).fetchall() + if old_data: + con_new_in_memory.executemany( + 'INSERT OR REPLACE INTO time_season_sequential ' + '(seas_seq, season, segment_fraction) VALUES (?, ?, ?)', + old_data, + ) + print(f'Propagated {len(old_data)} sequential seasons to time_season.') + except sqlite3.OperationalError: + pass # Optional table + # --- Final updates and dump --- con_new_in_memory.execute("INSERT OR REPLACE INTO metadata VALUES ('DB_MAJOR', 4, '')") con_new_in_memory.execute("INSERT OR REPLACE INTO metadata VALUES ('DB_MINOR', 0, '')") diff --git a/tests/test_v4_migration.py b/tests/test_v4_migration.py new file mode 100644 index 000000000..644c6fff6 --- /dev/null +++ b/tests/test_v4_migration.py @@ -0,0 +1,105 @@ +import sqlite3 +import subprocess +import sys +from pathlib import Path + +import pytest + +# Constants +REPO_ROOT = Path(__file__).parents[1] +UTILITIES_DIR = REPO_ROOT / 'temoa' / 'utilities' +SCHEMA_V3_1 = REPO_ROOT / 'temoa' / 'db_schema' / 'temoa_schema_v3_1.sql' +SCHEMA_V4 = REPO_ROOT / 'temoa' / 'db_schema' / 'temoa_schema_v4.sql' +MOCK_DATA = REPO_ROOT / 'tests' / 'testing_data' / 'migration_v3_1_mock.sql' + + +def test_v4_migrations(tmp_path: Path) -> None: + """Test both SQL and SQLite v4 migrators.""" + + # 1. Create v3.1 SQLite DB + db_v3_1 = tmp_path / 'test_v3_1.sqlite' + with sqlite3.connect(db_v3_1) as conn: + conn.execute('PRAGMA foreign_keys = OFF') + conn.executescript(SCHEMA_V3_1.read_text()) + conn.executescript(MOCK_DATA.read_text()) + conn.execute('PRAGMA foreign_keys = ON') + + # 2. Dump v3.1 to SQL + sql_v3_1 = tmp_path / 'test_v3_1.sql' + with open(sql_v3_1, 'w') as f: + for line in sqlite3.connect(db_v3_1).iterdump(): + f.write(line + '\n') + + # 3. Verify SQL migration script + sql_v4_migrated = tmp_path / 'test_v4_migrated.sql' + subprocess.run( + [ + sys.executable, + str(UTILITIES_DIR / 'sql_migration_v3_1_to_v4.py'), + '--input', + str(sql_v3_1), + '--schema', + str(SCHEMA_V4), + '--output', + str(sql_v4_migrated), + ], + check=True, + ) + + # Load SQL result into memory to verify + conn_sql = sqlite3.connect(':memory:') + conn_sql.executescript(sql_v4_migrated.read_text()) + + _verify_migrated_data(conn_sql) + + # 4. Verify SQLite direct migration script + db_v4_migrated = tmp_path / 'test_v4_migrated.sqlite' + subprocess.run( + [ + sys.executable, + str(UTILITIES_DIR / 'db_migration_v3_1_to_v4.py'), + '--source', + str(db_v3_1), + '--schema', + str(SCHEMA_V4), + '--out', + str(db_v4_migrated), + ], + check=True, + ) + + with sqlite3.connect(db_v4_migrated) as conn_db: + _verify_migrated_data(conn_db) + + +def _verify_migrated_data(conn: sqlite3.Connection) -> None: + # Check time_season restructuring (aggregated from TimeSegmentFraction) + # Summer: 0.4 + 0.3 = 0.7 + # Winter: 0.2 + 0.1 = 0.3 + seasons = dict(conn.execute('SELECT season, segment_fraction FROM time_season').fetchall()) + assert seasons['summer'] == pytest.approx(0.7) + assert seasons['winter'] == pytest.approx(0.3) + + # Check time_of_day restructuring (normalized to 24 hours based on weights) + # Day weight: 0.2 + 0.4 = 0.6 + # Night weight: 0.1 + 0.3 = 0.4 + # Normalized to 24: Day=0.6*24=14.4, Night=0.4*24=9.6 + tods = dict(conn.execute('SELECT tod, hours FROM time_of_day').fetchall()) + assert tods['day'] == pytest.approx(14.4) + assert tods['night'] == pytest.approx(9.6) + + # Check period removal from capacity_factor_process + # Original PK: (region, period, season, tod, tech, vintage) + # New PK: (region, season, tod, tech, vintage) + cols = [c[1] for c in conn.execute('PRAGMA table_info(capacity_factor_process)').fetchall()] + assert 'period' not in cols + + rows = conn.execute( + 'SELECT region, season, tod, tech, vintage, factor FROM capacity_factor_process' + ).fetchall() + assert len(rows) == 1 + assert rows[0] == ('R1', 'winter', 'day', 'T1', 2030, pytest.approx(0.6)) + + # Check metadata version + major = conn.execute("SELECT value FROM metadata WHERE element='DB_MAJOR'").fetchone()[0] + assert int(major) == 4 diff --git a/tests/testing_data/migration_v3_1_mock.sql b/tests/testing_data/migration_v3_1_mock.sql new file mode 100644 index 000000000..8e97007a1 --- /dev/null +++ b/tests/testing_data/migration_v3_1_mock.sql @@ -0,0 +1,30 @@ +-- Mock data for v3.1 -> v4 migration testing +INSERT INTO Region (region) VALUES ('R1'); +INSERT OR IGNORE INTO TechnologyType (label, description) VALUES ('p', 'production'); +INSERT INTO Technology (tech, flag, unlim_cap, annual, reserve, curtail, retire, flex, exchange, seas_stor) VALUES ('T1', 'p', 0, 0, 0, 0, 0, 0, 0, 0); + +INSERT INTO TimePeriod (sequence, period, flag) VALUES (1, 2020, 'e'); +INSERT INTO TimePeriod (sequence, period, flag) VALUES (2, 2030, 'f'); +INSERT INTO TimePeriod (sequence, period, flag) VALUES (3, 2040, 'f'); + +INSERT INTO SeasonLabel (season) VALUES ('winter'); +INSERT INTO SeasonLabel (season) VALUES ('summer'); + +INSERT INTO TimeOfDay (sequence, tod) VALUES (1, 'day'); +INSERT INTO TimeOfDay (sequence, tod) VALUES (2, 'night'); + +INSERT INTO TimeSeason (period, sequence, season) VALUES (2030, 1, 'winter'); +INSERT INTO TimeSeason (period, sequence, season) VALUES (2030, 2, 'summer'); + +INSERT INTO TimeSegmentFraction (period, season, tod, segfrac) VALUES (2030, 'winter', 'day', 0.2); +INSERT INTO TimeSegmentFraction (period, season, tod, segfrac) VALUES (2030, 'winter', 'night', 0.1); +INSERT INTO TimeSegmentFraction (period, season, tod, segfrac) VALUES (2030, 'summer', 'day', 0.4); +INSERT INTO TimeSegmentFraction (period, season, tod, segfrac) VALUES (2030, 'summer', 'night', 0.3); + +INSERT OR IGNORE INTO CommodityType (label, description) VALUES ('p', 'physical'); +INSERT INTO Commodity (name, flag) VALUES ('In', 'p'); +INSERT INTO Commodity (name, flag) VALUES ('Out', 'p'); + +INSERT INTO CapacityFactorProcess (region, period, season, tod, tech, vintage, factor) VALUES ('R1', 2030, 'winter', 'day', 'T1', 2030, 0.5); +INSERT INTO CapacityFactorProcess (region, period, season, tod, tech, vintage, factor) VALUES ('R1', 2040, 'winter', 'day', 'T1', 2030, 0.7); +INSERT INTO Efficiency (region, input_comm, tech, vintage, output_comm, efficiency) VALUES ('R1', 'In', 'T1', 2030, 'Out', 0.9); From f48bd7ef0c98d0227da493c42d056cdb2a7bdb8f Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Mon, 23 Mar 2026 19:58:39 -0400 Subject: [PATCH 37/40] Rename time_season_sequential and remove unneeded season index --- temoa/_internal/table_data_puller.py | 2 +- temoa/components/storage.py | 8 ++++---- temoa/components/time.py | 16 +++++++--------- temoa/core/model.py | 4 ++-- temoa/data_io/hybrid_loader.py | 7 ++++++- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/temoa/_internal/table_data_puller.py b/temoa/_internal/table_data_puller.py index 57e0c8b07..968a0ba79 100644 --- a/temoa/_internal/table_data_puller.py +++ b/temoa/_internal/table_data_puller.py @@ -275,7 +275,7 @@ def poll_storage_level_results(model: TemoaModel, epsilon: float = 1e-5) -> dict # Ratio of days in virtual storage season to days in actual season # Flows and StorageLevel are normalised to the number of days in the ACTUAL season, so must # be adjusted to the number of days in the virtual storage season - days_adjust = value(model.time_season_sequential[s_seq, s]) / value( + days_adjust = value(model.segment_fraction_per_sequential_season[s_seq]) / value( model.segment_fraction_per_season[s] ) for d in model.time_of_day: diff --git a/temoa/components/storage.py b/temoa/components/storage.py index 541f02a15..4f1aea8df 100644 --- a/temoa/components/storage.py +++ b/temoa/components/storage.py @@ -270,10 +270,10 @@ def seasonal_storage_energy_constraint( # Flows and StorageLevel are adjusted for the weight of seasons and so must be # readjusted for the relative weight of the sequential season - days_adjust = value(model.time_season_sequential[s_seq, s]) / value( + days_adjust = value(model.segment_fraction_per_sequential_season[s_seq]) / value( model.segment_fraction_per_season[s] ) - days_adjust_next = value(model.time_season_sequential[s_seq_next, s_next]) / value( + days_adjust_next = value(model.segment_fraction_per_sequential_season[s_seq_next]) / value( model.segment_fraction_per_season[s_next] ) @@ -417,7 +417,7 @@ def seasonal_storage_energy_upper_bound_constraint( # Flows and StorageLevel are adjusted for the weight of seasons and so must be # readjusted for the relative weight of the sequential season - days_adjust = value(model.time_season_sequential[s_seq, s]) / value( + days_adjust = value(model.segment_fraction_per_sequential_season[s_seq]) / value( model.segment_fraction_per_season[s] ) @@ -609,7 +609,7 @@ def limit_storage_fraction_constraint( if model.is_seasonal_storage[t]: # seasonal storage upper energy limit is absolute energy_level = model.v_seasonal_storage_level[r, p, s_seq, t, v] + energy_level * value( - model.time_season_sequential[s_seq, s] * value(model.days_per_period) + model.segment_fraction_per_sequential_season[s_seq] * value(model.days_per_period) ) expr = operator_expression(energy_level, Operator(op), energy_limit) diff --git a/temoa/components/time.py b/temoa/components/time.py index 352a5a809..5b611dc51 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -155,9 +155,7 @@ def validate_time_manual(model: TemoaModel) -> None: return segment_fraction_sd: set[tuple[str, str]] = set(model.segment_fraction.sparse_iterkeys()) - time_manual_sd: set[tuple[str, str]] = { - (s, d) for s, d, s_next, d_next in model.time_manual - } + time_manual_sd: set[tuple[str, str]] = {(s, d) for s, d, s_next, d_next in model.time_manual} time_manual_sd_next: set[tuple[str, str]] = { (s_next, d_next) for s, d, s_next, d_next in model.time_manual } @@ -196,7 +194,6 @@ def init_set_vintage_optimize(model: TemoaModel) -> list[int]: return sorted(model.time_optimize) - def param_period_length(model: TemoaModel, p: Period) -> int: """Rule to calculate the length of each optimization period in years.""" periods: list[int] = sorted(model.time_future) @@ -321,7 +318,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: # Don't need it anyway return - if not model.time_season_sequential: + if not model.segment_fraction_per_sequential_season: if model.time_sequencing.first() in ('consecutive_days', 'seasonal_timeslices'): logger.info( 'No data in time_season_sequential. By default, assuming sequential seasons ' @@ -330,7 +327,9 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: for s in model.time_season: model.time_season_to_sequential.add(s) model.ordered_season_sequential.add((s, s)) - model.time_season_sequential[s, s] = value(model.segment_fraction_per_season[s]) + model.segment_fraction_per_sequential_season[s] = value( + model.segment_fraction_per_season[s] + ) else: msg = ( @@ -347,7 +346,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: seas_fracs_seq: dict[str, float] = {} prev_frac: float = 0 for s_seq, s in model.time_season_sequential.sparse_iterkeys(): - seg_frac_seq: float = value(model.time_season_sequential[s_seq, s]) + seg_frac_seq: float = value(model.segment_fraction_per_sequential_season[s_seq]) if ( model.time_sequencing.first() == 'consecutive_days' and prev_frac @@ -378,8 +377,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: for s in seas_fracs_seq: if s not in model.time_season: msg = ( - f'Season {s!r} referenced in time_season_sequential ' - 'does not exist in time_season.' + f'Season {s!r} referenced in time_season_sequential does not exist in time_season.' ) logger.error(msg) raise ValueError(msg) diff --git a/temoa/core/model.py b/temoa/core/model.py index 68d4738e5..87f6e0075 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -341,8 +341,8 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.segment_fraction_per_season = Param(self.time_season) self.segment_fraction = Param(self.time_season, self.time_of_day, mutable=True) self.validate_segment_fraction = BuildAction(rule=time.validate_segment_fraction) - self.time_season_sequential = Param( - self.time_season_to_sequential, self.time_season, mutable=True + self.segment_fraction_per_sequential_season = Param( + self.time_season_sequential, mutable=True ) self.validate_season_sequential = BuildAction(rule=time.create_time_season_to_sequential) self.create_time_sequence = BuildAction(rule=time.create_time_sequence) diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 0e85bfb19..7828ba82f 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -575,8 +575,13 @@ def _load_time_season_sequential( Composite loader for time_season_sequential and its associated index sets. """ model = TemoaModel() - self._load_component_data(data, model.time_season_sequential, filtered_data) if filtered_data: + seg_frac_data = [ + (row[0], row[2]) for row in filtered_data + ] # (seas_seq, segment_fraction) + self._load_component_data( + data, model.segment_fraction_per_sequential_season, seg_frac_data + ) ordered_data = [row[0:2] for row in filtered_data] # (seas_seq, season) self._load_component_data(data, model.ordered_season_sequential, ordered_data) seq_data = sorted({(row[0],) for row in filtered_data}) From c08bcad05eb1fd912d9865043f14e912a92fb1d2 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Mon, 23 Mar 2026 20:01:45 -0400 Subject: [PATCH 38/40] Rename time_season_to_sequential (name was wrong) --- temoa/components/time.py | 6 +++--- temoa/core/model.py | 4 ++-- temoa/data_io/hybrid_loader.py | 4 ++-- tests/testing_data/mediumville_sets.json | 2 +- tests/testing_data/test_system_sets.json | 2 +- tests/testing_data/utopia_sets.json | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/temoa/components/time.py b/temoa/components/time.py index 5b611dc51..894dee35e 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -325,7 +325,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: 'match time_season.' ) for s in model.time_season: - model.time_season_to_sequential.add(s) + model.time_season_sequential.add(s) model.ordered_season_sequential.add((s, s)) model.segment_fraction_per_sequential_season[s] = value( model.segment_fraction_per_season[s] @@ -345,7 +345,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: seas_fracs_seq: dict[str, float] = {} prev_frac: float = 0 - for s_seq, s in model.time_season_sequential.sparse_iterkeys(): + for s_seq, s in model.ordered_season_sequential: seg_frac_seq: float = value(model.segment_fraction_per_sequential_season[s_seq]) if ( model.time_sequencing.first() == 'consecutive_days' @@ -355,7 +355,7 @@ def create_time_season_to_sequential(model: TemoaModel) -> None: msg = ( 'time_sequencing set to consecutive_days but two consecutive seasons do not ' 'represent the same fraction of the year. This discontinuity will lead to bad ' - f'model behaviour: {s}, fraction: {seg_frac_seq}. ' + f'model behaviour: {s_seq}, fraction: {seg_frac_seq}. ' f'Previous fraction: {prev_frac}. Check the config file for more information.' ) logger.error(msg) diff --git a/temoa/core/model.py b/temoa/core/model.py index 87f6e0075..4ce2a0275 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -220,14 +220,14 @@ def __init__(self, *args: object, **kwargs: object) -> None: # Define the model time slices self.time_season = Set(ordered=True, validate=no_slash_or_pipe) - self.time_season_to_sequential = Set(ordered=True, validate=no_slash_or_pipe) + self.time_season_sequential = Set(ordered=True, validate=no_slash_or_pipe) self.time_of_day = Set(ordered=True, validate=no_slash_or_pipe) # This is just to get the TimeStorageSeason table sequentially. # There must be a better way but this works for now self.ordered_season_sequential = Set( dimen=2, - within=self.time_season_to_sequential * self.time_season, + within=self.time_season_sequential * self.time_season, ordered=True, ) diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 7828ba82f..5216c247c 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -584,8 +584,8 @@ def _load_time_season_sequential( ) ordered_data = [row[0:2] for row in filtered_data] # (seas_seq, season) self._load_component_data(data, model.ordered_season_sequential, ordered_data) - seq_data = sorted({(row[0],) for row in filtered_data}) - self._load_component_data(data, model.time_season_to_sequential, seq_data) + seq_seasons = [(row[0],) for row in filtered_data] # (seas_seq,) + self._load_component_data(data, model.time_season_sequential, seq_seasons) # --- Capacity and Cost Components --- def _load_existing_capacity( diff --git a/tests/testing_data/mediumville_sets.json b/tests/testing_data/mediumville_sets.json index 266889242..4dd07b4e3 100644 --- a/tests/testing_data/mediumville_sets.json +++ b/tests/testing_data/mediumville_sets.json @@ -4102,7 +4102,7 @@ "s1", "s2" ], - "time_season_to_sequential": [ + "time_season_sequential": [ "s1", "s2" ], diff --git a/tests/testing_data/test_system_sets.json b/tests/testing_data/test_system_sets.json index 4dcc5a0fe..1740580d8 100644 --- a/tests/testing_data/test_system_sets.json +++ b/tests/testing_data/test_system_sets.json @@ -42580,7 +42580,7 @@ "spring", "winter" ], - "time_season_to_sequential": [], + "time_season_sequential": [], "time_sequencing": [ "seasonal_timeslices" ], diff --git a/tests/testing_data/utopia_sets.json b/tests/testing_data/utopia_sets.json index 3ad410eb4..a69112919 100644 --- a/tests/testing_data/utopia_sets.json +++ b/tests/testing_data/utopia_sets.json @@ -24110,7 +24110,7 @@ "inter", "winter" ], - "time_season_to_sequential": [], + "time_season_sequential": [], "time_sequencing": [ "seasonal_timeslices" ], From bbc69b7f67753d1313ab350ea0d05ecd28189c5e Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Mon, 23 Mar 2026 20:02:12 -0400 Subject: [PATCH 39/40] Add sequence ordering to critical ordered time sets in loading --- temoa/data_io/component_manifest.py | 3 +++ temoa/data_io/hybrid_loader.py | 3 +++ temoa/data_io/loader_manifest.py | 1 + 3 files changed, 7 insertions(+) diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index d2ac923f6..f9bf86a1c 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -236,6 +236,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_period_filtered=False, is_table_required=False, fallback_data=[('D',)], + order_by=['sequence'], ), LoadItem( component=model.time_of_day_hours, @@ -251,6 +252,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: custom_loader_name='_load_time_season', is_period_filtered=False, # Custom loader handles myopic filtering is_table_required=False, + order_by=['sequence'], ), LoadItem( component=model.segment_fraction_per_season, @@ -266,6 +268,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: custom_loader_name='_load_time_season_sequential', is_period_filtered=False, is_table_required=False, + order_by=['sequence'], ), LoadItem( component=model.time_manual, diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 5216c247c..3bf3b5e85 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -315,6 +315,9 @@ def _fetch_data( if where_clauses: query += ' WHERE ' + ' AND '.join(where_clauses) + if item.order_by: + query += ' ORDER BY ' + ', '.join(item.order_by) + try: return cur.execute(query, params).fetchall() except OperationalError as e: diff --git a/temoa/data_io/loader_manifest.py b/temoa/data_io/loader_manifest.py index b0350568f..ad6ce930d 100644 --- a/temoa/data_io/loader_manifest.py +++ b/temoa/data_io/loader_manifest.py @@ -57,3 +57,4 @@ class LoadItem: is_table_required: bool = True custom_loader_name: str | None = None fallback_data: list[tuple[object, ...]] | None = None + order_by: list[str] | None = None From c984fa2f857ba48459be626ac02f4fa711fa09c7 Mon Sep 17 00:00:00 2001 From: Davey Elder Date: Mon, 23 Mar 2026 20:35:45 -0400 Subject: [PATCH 40/40] Resolve some merge issues --- data_files/temoa_schema_v4.sql | 2 +- temoa/components/commodities.py | 4 +-- temoa/extensions/myopic/evolution_updater.py | 9 +++--- .../myopic/myopic_progress_mapper.py | 2 +- tests/test_myopic_sequencer.py | 28 +++---------------- 5 files changed, 12 insertions(+), 33 deletions(-) diff --git a/data_files/temoa_schema_v4.sql b/data_files/temoa_schema_v4.sql index 7285effe2..90a39108c 100644 --- a/data_files/temoa_schema_v4.sql +++ b/data_files/temoa_schema_v4.sql @@ -687,7 +687,7 @@ CREATE TABLE IF NOT EXISTS output_curtailment period INTEGER REFERENCES time_period (period), season TEXT - REFERENCES season_label (season), + REFERENCES time_season (season), tod TEXT REFERENCES time_of_day (tod), input_comm TEXT diff --git a/temoa/components/commodities.py b/temoa/components/commodities.py index 904d186e4..2058d469d 100644 --- a/temoa/components/commodities.py +++ b/temoa/components/commodities.py @@ -116,8 +116,8 @@ def check_singleton_demands(model: TemoaModel) -> None: i, t, v = next(iter(upstream_itv)) model.v_flow_out_annual[r, p, i, t, v, dem].fix(val) if t not in model.tech_annual: - for s, d in cross_product(model.time_season[p], model.time_of_day): - dsd = value(model.demand_specific_distribution[r, p, s, d, dem]) + for s, d in cross_product(model.time_season, model.time_of_day): + dsd = value(model.demand_specific_distribution[r, s, d, dem]) model.v_flow_out[r, p, s, d, i, t, v, dem].fix(val * dsd) model.singleton_demands.add((r, p, dem)) diff --git a/temoa/extensions/myopic/evolution_updater.py b/temoa/extensions/myopic/evolution_updater.py index 6791a7eff..7d630dcaa 100644 --- a/temoa/extensions/myopic/evolution_updater.py +++ b/temoa/extensions/myopic/evolution_updater.py @@ -12,12 +12,11 @@ def iterate( ) -> None: """ This function is called at the end of each myopic iteration, - after the results have been recorded to the myopic database. + after the results have been recorded to the myopic database. You can use it to update your myopic database with any additional information you want to track across iterations, or to implement an evolving myopic approach where the model structure changes across iterations based on some user-defined logic. - Parameters: - idx (MyopicIndex): The index object for the current iteration, containing information about the base year, view depth, etc. @@ -28,9 +27,9 @@ def iterate( - db_con (sqlite3.Connection): A connection object to the myopic database, which you can use to read/write data as needed. """ - + logger.info(f"Running myopic iteration updater for base year {idx.base_year}") - + # Update your myopic database here. - return \ No newline at end of file + return diff --git a/temoa/extensions/myopic/myopic_progress_mapper.py b/temoa/extensions/myopic/myopic_progress_mapper.py index 3f17adb18..c1d81508e 100644 --- a/temoa/extensions/myopic/myopic_progress_mapper.py +++ b/temoa/extensions/myopic/myopic_progress_mapper.py @@ -52,7 +52,7 @@ def timestamp(self) -> str: def report(self, mi: MyopicIndex, status): if status not in {'load', 'solve', 'report', 'check', 'evolve'}: raise ValueError(f'bad status: {status} received in MyopicProgressMapper') - + if status == 'evolve': repeats = self.years.index(mi.last_demand_year) - self.years.index(mi.base_year) + 1 print(self.timestamp(), end='') diff --git a/tests/test_myopic_sequencer.py b/tests/test_myopic_sequencer.py index e63f5e707..f0dac220a 100644 --- a/tests/test_myopic_sequencer.py +++ b/tests/test_myopic_sequencer.py @@ -7,45 +7,25 @@ params = [ { 'name': 'single_step', - 'conf_data': { - 'step_size': 1, - 'view_depth': 3, - 'evolving': False, - 'evolution_script': None - }, + 'conf_data': {'step_size': 1, 'view_depth': 3, 'evolving': False, 'evolution_script': None}, 'expected_steps': 2, 'expected_last_base_year': 1, }, { 'name': 'triple_step', - 'conf_data': { - 'step_size': 3, - 'view_depth': 4, - 'evolving': False, - 'evolution_script': None - }, + 'conf_data': {'step_size': 3, 'view_depth': 4, 'evolving': False, 'evolution_script': None}, 'expected_steps': 1, # see end of horizon immediately 'expected_last_base_year': 0, }, { 'name': 'single_step_evolving', - 'conf_data': { - 'step_size': 1, - 'view_depth': 3, - 'evolving': True, - 'evolution_script': None - }, + 'conf_data': {'step_size': 1, 'view_depth': 3, 'evolving': True, 'evolution_script': None}, 'expected_steps': 4, 'expected_last_base_year': 3, }, # 4 single steps { 'name': 'triple_step_evolving', - 'conf_data': { - 'step_size': 3, - 'view_depth': 4, - 'evolving': True, - 'evolution_script': None - }, + 'conf_data': {'step_size': 3, 'view_depth': 4, 'evolving': True, 'evolution_script': None}, 'expected_steps': 2, # 1 step of 3, followed by 1 step of 1 'expected_last_base_year': 3, },