diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5b931f519..5f170d2a2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.11.19 + rev: 0.11.23 hooks: # Dependency management - id: uv-lock @@ -47,7 +47,7 @@ repos: # Python Linting & Formatting with Ruff - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: "v0.15.16" + rev: "v0.15.18" hooks: - id: ruff name: ruff (linter) diff --git a/docs/source/computational_implementation.rst b/docs/source/computational_implementation.rst index 023964f3c..943452766 100644 --- a/docs/source/computational_implementation.rst +++ b/docs/source/computational_implementation.rst @@ -320,6 +320,11 @@ dimensionality of 3, and (following the :ref:`naming scheme :code:`region`, the second an element of :code:`time_optimize`, and third a demand commodity. +.. seealso:: + The same component pattern (index set, parameter, and constraint declared in a + ``model.py`` and implemented in component modules) can be packaged as an + optional, self-contained add-on. See :ref:`extensions` for the extension + framework and a copy-from template. diff --git a/docs/source/extensions.rst b/docs/source/extensions.rst new file mode 100644 index 000000000..e7722ba12 --- /dev/null +++ b/docs/source/extensions.rst @@ -0,0 +1,247 @@ +.. _extensions: + +Extension Framework +=================== + +Temoa includes a lightweight framework for adding **optional model components** +without modifying the core model. An extension can contribute its own database +tables, Pyomo components (sets, parameters, and constraints), and data-loading +rules. Extensions are declared once and then enabled per run through +configuration. + +This page describes how the framework works and how to author a new extension. +A ready-to-copy scaffold lives at ``temoa/extensions/template``. + +Overview +-------- + +Use an extension when you want to add modeling capability that is: + +* **Optional** -- only active when explicitly enabled. +* **Self-contained** -- owns its own tables and model components. +* **Non-invasive** -- adds to the core model rather than editing it. + +If a feature is fundamental to every Temoa run, it belongs in +``temoa/components`` (a core component) instead of an extension. + +Each extension is described by a single :class:`ExtensionSpec` (declarative +metadata plus hook functions). The spec is registered with the framework, after +which users can enable the extension by id. + +Lifecycle +--------- + +When a run is configured with ``extensions = ["..."]``, the framework threads the +enabled specs through configuration, model construction, and data loading: + +.. code-block:: text + + config: extensions = ["my_ext"] + | + v + resolve_extension_specs() validate ids -> ExtensionSpec list + | + v + TemoaModel(extensions=[...]) + | + +--> apply_model_extension_hooks() + | calls spec.register_model_components(model) + | -> attaches Params / Sets / Constraints to the model + | + v + HybridLoader + +--> ensure_enabled_extension_tables_exist() (offer to append schema) + +--> assert_disabled_extension_tables_are_empty() + +--> merge_regional_group_tables() + +--> build_manifest() -> appends spec.build_manifest_items(model) + -> loads each owned table into its component + +The relevant code lives in :mod:`temoa.extensions.framework`, +:mod:`temoa.core.model`, and :mod:`temoa.data_io.hybrid_loader`. + +``ExtensionSpec`` reference +--------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Field + - Purpose + * - ``extension_id`` + - Unique, lowercase id. This is what users put in ``extensions = [...]``. + * - ``owned_tables`` + - Tuple of database tables owned exclusively by this extension. Used by the + disabled/enabled table guards. + * - ``regional_group_tables`` + - Map of ``table -> column`` for tables whose region column may hold a + regional *group* name. Merged into the loader's regional-group handling. + * - ``register_model_components`` + - Hook ``Callable[[TemoaModel], None]`` that attaches model components. + * - ``build_manifest_items`` + - Hook ``Callable[[TemoaModel], list[LoadItem]]`` describing how to load the + extension's data. + * - ``schema_sql_path`` + - Path to a ``.sql`` file applied (with consent) when the extension is + enabled but its tables are missing. + * - ``fail_if_tables_populated_when_disabled`` + - When ``True``, loading fails if the extension is disabled but its owned + tables contain data, preventing silently-ignored inputs. + +Recommended package layout +-------------------------- + +Mirror the structure of the core model (``temoa/core`` + ``temoa/components``) so +extension code is organized the same way as the rest of the codebase: + +.. code-block:: text + + temoa/extensions// + __init__.py # re-export the ExtensionSpec + extension.py # the ExtensionSpec definition + data_manifest.py # build_manifest_items() + tables.sql # CREATE TABLE IF NOT EXISTS for owned tables + core/ + __init__.py + model.py # typing subtype + register_model_components() + components/ + __init__.py + .py # one module per constraint family + +Centralize the component *declarations* in ``core/model.py`` (just as +``temoa/core/model.py`` does) and keep the index-set and constraint-rule logic in +``components/`` modules (just as ``temoa/components`` does). + +.. _extensions-typing: + +The typing pattern +------------------ + +Core model components are declared as attribute assignments inside +``TemoaModel.__init__`` (for example ``self.time_optimize = Set(...)``), which is +why the type checker knows about them. An extension instead adds attributes from +*outside* the class, so without help the type checker reports +``"TemoaModel" has no attribute ...`` and provides no autocomplete. + +Three rules make typing carry over cleanly: + +1. **Declare a ``TYPE_CHECKING``-only subtype.** In ``core/model.py``, define a + subclass of ``TemoaModel`` that annotates every component the extension adds. + It inherits all core attributes, so component code sees both core and + extension members. + + .. code-block:: python + + if TYPE_CHECKING: + from temoa.core.model import TemoaModel + + class ExampleModel(TemoaModel): + example_new_capacity_limit: Param + example_new_capacity_limit_constraint_rpt: Set + example_new_capacity_limit_constraint: Constraint + +2. **Annotate component functions with the subtype.** Index-set and + constraint-rule functions take ``model: ExampleModel``. This restores both + mypy coverage and editor autocomplete. + +3. **Keep spec hooks on the base type and ``cast`` internally.** Functions stored + on the ``ExtensionSpec`` (``register_model_components`` and + ``build_manifest_items``) must keep ``model: TemoaModel`` to match the hook + callable types. Narrowing the parameter is a contravariance error. ``cast`` + once at the top: + + .. code-block:: python + + def register_model_components(model: TemoaModel) -> None: + m = cast('ExampleModel', model) + m.example_new_capacity_limit = Param(...) + +.. note:: + Extension attribute names share the single ``TemoaModel`` namespace at + runtime. Keep them unique across extensions to avoid collisions. + +Adding a new extension +---------------------- + +#. **Copy the template.** Duplicate ``temoa/extensions/template`` to + ``temoa/extensions//``. +#. **Rename ids and tables.** Update ``extension_id``, ``owned_tables``, + ``regional_group_tables``, params, sets, and constraints to your domain. +#. **Declare components.** Add annotations to the typing subtype in + ``core/model.py`` and create the components in ``register_model_components``. +#. **Write the constraint logic.** Add index-set and rule functions under + ``components/`` and annotate them with your subtype. +#. **Describe data loading.** Add one ``LoadItem`` per owned table in + ``data_manifest.py``. +#. **Define the schema.** Add a ``CREATE TABLE IF NOT EXISTS`` per owned table to + ``tables.sql``. +#. **Register the spec.** Import your spec in + :func:`temoa.extensions.framework.get_known_extension_specs` and add it to the + ``specs`` list. (Until you do this, the extension is inert -- enabling it + raises an "Unknown extension id" error.) +#. **Enable it.** Add the id to your configuration TOML: + + .. code-block:: toml + + extensions = [""] + +Data loading and ``LoadItem`` +----------------------------- + +``build_manifest_items`` returns one :class:`temoa.data_io.loader_manifest.LoadItem` +per database table the extension reads. Common fields: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Field + - Purpose + * - ``component`` + - The Pyomo ``Set`` or ``Param`` to populate. + * - ``table`` + - Source table name in the database. + * - ``columns`` + - Columns to select; for a ``Param`` the final column is the value. + * - ``index_length`` + - Number of leading columns that form the index. + * - ``validator_name`` / ``validation_map`` + - Source-trace validation: a viable-set name on the loader and which index + columns it applies to. + * - ``is_table_required`` + - Set ``False`` for optional extension inputs so a missing table is not an + error. + +Verification +------------ + +After authoring an extension, confirm: + +#. **Types** -- ``mypy temoa/extensions/`` reports no issues. +#. **Imports** -- ``python -c "import temoa.extensions..extension"``. +#. **Wiring** -- a model built with the extension enabled attaches the expected + components, and the test suite passes. + +The template extension +----------------------- + +``temoa/extensions/template`` is a complete, type-checked, but deliberately +**unregistered** scaffold. Because it is not listed in +``get_known_extension_specs``, it cannot be enabled until you register it, so it +never affects normal runs. Copy the folder as the starting point for a new +extension; every file carries ``# TEMPLATE:`` comments explaining what to change. + +.. _extension-catalog: + +Available extensions +-------------------- + +The extensions that ship with Temoa are documented on their own pages below. +Each page describes the extension's parameters and constraints. This list grows +as new extensions are added. + +.. toctree:: + :maxdepth: 1 + + extensions/growth_rates + extensions/integer_capacity diff --git a/docs/source/extensions/growth_rates.rst b/docs/source/extensions/growth_rates.rst new file mode 100644 index 000000000..6de399585 --- /dev/null +++ b/docs/source/extensions/growth_rates.rst @@ -0,0 +1,99 @@ +.. _extension-growth-rates: + +Growth Rate Limits +================================== + +The **growth_rates** extension adds optional constraints that bound how quickly +the capacity (or new capacity) of a technology or technology group may change +between consecutive model periods. It is disabled by default and enabled per +run through configuration: + +.. code-block:: toml + + extensions = ["growth_rates"] + +Its parameters live in the extension-owned tables of the same name and are loaded +only when the extension is enabled. See :ref:`extensions` for how the extension +framework wires these components into the model. + +Parameters +---------- + +.. csv-table:: + :header: "Parameter", "Database Table", "Model Element", "Notes" + :widths: 15, 20, 25, 40 + + ":math:`\text{LGC}_{r,t}`", ":code:`limit_growth_capacity`", ":code:`limit_growth_capacity`", "capacity growth rate limits; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\text{LDGC}_{r,t}`", ":code:`limit_degrowth_capacity`", ":code:`limit_degrowth_capacity`", "capacity degrowth rate limits; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\text{LGNC}_{r,t}`", ":code:`limit_growth_new_capacity`", ":code:`limit_growth_new_capacity`", "new capacity growth rate limits; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\text{LDGNC}_{r,t}`", ":code:`limit_degrowth_new_capacity`", ":code:`limit_degrowth_new_capacity`", "new capacity degrowth rate limits; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\mathrm{LGNC}_{\Delta,r,t}`", ":code:`limit_growth_new_capacity_delta`", ":code:`limit_growth_new_capacity_delta`", "new capacity growth acceleration limits; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\mathrm{LDGNC}_{\Delta,r,t}`", ":code:`limit_degrowth_new_capacity_delta`", ":code:`limit_degrowth_new_capacity_delta`", "new capacity degrowth deceleration limits; :code:`tech_or_group` column accepts a technology name or group name" + + +limit_growth_capacity +~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LGC}_{r \in R, t \in T}` + +The :code:`limit_growth_capacity` parameter defines the maximum annual rate at +which the total capacity of a technology (or group) can grow between periods. +The :code:`tech_or_group` column accepts a technology name or group name. + + +limit_degrowth_capacity +~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LDGC}_{r \in R, t \in T}` + +The :code:`limit_degrowth_capacity` parameter defines the maximum annual rate +at which the total capacity of a technology (or group) can shrink between +periods. The :code:`tech_or_group` column accepts a technology name or group name. + + +limit_growth_new_capacity +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LGNC}_{r \in R, t \in T}` + +The :code:`limit_growth_new_capacity` parameter constrains the rate of increase +in new capacity deployment between consecutive periods. + + +limit_degrowth_new_capacity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LDGNC}_{r \in R, t \in T}` + +The :code:`limit_degrowth_new_capacity` parameter constrains the rate of decrease +in new capacity deployment between consecutive periods. + + +limit_growth_new_capacity_delta +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`\mathrm{LGNC}_{\Delta,r \in R, t \in T}` + +The :code:`limit_growth_new_capacity_delta` parameter constrains the acceleration +of new capacity growth between periods. This essentially adds "inertia" to the +growth of new capacity deployment. + + +limit_degrowth_new_capacity_delta +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`\mathrm{LDGNC}_{\Delta,r \in R, t \in T}` + +The :code:`limit_degrowth_new_capacity_delta` parameter constrains the +deceleration of new capacity degrowth between periods, essentially adding +"intertia" to the degrowth of new capacity deployment. + + +Constraints +----------- + +.. autofunction:: temoa.extensions.growth_rates.components.growth_capacity.limit_growth_capacity + +.. autofunction:: temoa.extensions.growth_rates.components.growth_new_capacity.limit_growth_new_capacity + +.. autofunction:: temoa.extensions.growth_rates.components.growth_new_capacity_delta.limit_growth_new_capacity_delta diff --git a/docs/source/extensions/integer_capacity.rst b/docs/source/extensions/integer_capacity.rst new file mode 100644 index 000000000..02560f1ab --- /dev/null +++ b/docs/source/extensions/integer_capacity.rst @@ -0,0 +1,93 @@ +.. _extension-integer-capacity: + +Integer Capacity +================================ + +The **integer_capacity** extension adds optional constraints that force the +capacity of a technology or technology group to be deployed in discrete, +indivisible units rather than as a continuous quantity. This is useful for +modeling lumpy investments or retirements such as a power plant, reactor, or +other facility that can only exist in whole units of a fixed size. + +Enabling the extension introduces integer decision variables, which turns the +model into a mixed-integer program (MIP). It is disabled by default and enabled +per run through configuration: + +.. code-block:: toml + + extensions = ["integer_capacity"] + +Its parameters live in the extension-owned tables of the same name and are loaded +only when the extension is enabled. See :ref:`extensions` for how the extension +framework wires these components into the model. + +Parameters +---------- + +.. csv-table:: + :header: "Parameter", "Database Table", "Model Element", "Notes" + :widths: 15, 20, 25, 40 + + ":math:`\text{LINC}_{r,t}`", ":code:`limit_integer_new_capacity`", ":code:`limit_integer_new_capacity`", "unit size for new capacity additions; new capacity is forced to an integer multiple of this size; :code:`tech_or_group` column accepts a technology name or group name" + ":math:`\text{LIC}_{r,t}`", ":code:`limit_integer_net_capacity`", ":code:`limit_integer_net_capacity`", "unit size for total available (retirement-adjusted) capacity; net capacity is forced to an integer multiple of this size; :code:`tech_or_group` column accepts a technology name or group name" + + +limit_integer_new_capacity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LINC}_{r \in R, t \in T}` + +The :code:`limit_integer_new_capacity` parameter specifies the unit size for new +capacity additions of a technology (or group). The new capacity built in each +vintage is forced to be an integer multiple of this unit size. The +:code:`tech_or_group` column accepts a technology name or group name, and the +:code:`capacity` column gives the size of a single unit. + + +limit_integer_net_capacity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{LIC}_{r \in R, t \in T}` + +The :code:`limit_integer_net_capacity` parameter specifies the unit size for the +total available (retirement-adjusted) capacity of a technology (or group). The +net capacity available in each period is forced to be an integer multiple of this +unit size. The :code:`tech_or_group` column accepts a technology name or group +name, and the :code:`capacity` column gives the size of a single unit. + + +Decision Variables +------------------ + +Enabling the extension adds two integer decision variables, one per constraint. +Each counts the number of discrete units, which is multiplied by the +corresponding unit size to recover the capacity quantity. + +v_integer_new_capacity +~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`INCAP_{r, t, v}` + +The number of discrete units of new capacity built for technology (or group) +:math:`t` in region :math:`r` and vintage :math:`v`. It is restricted to +non-negative integers, and the total new capacity equals this count multiplied by +the unit size :math:`LINC_{r, t}`. + + +v_integer_net_capacity +~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`ICAP_{r, p, t}` + +The number of discrete units of total available (retirement-adjusted) capacity +for technology (or group) :math:`t` in region :math:`r` and period :math:`p`. It +is restricted to non-negative integers, and the net available capacity equals this +count multiplied by the unit size :math:`LIC_{r, t}`. + + +Constraints +----------- + +.. autofunction:: temoa.extensions.integer_capacity.components.integer_capacity.limit_integer_new_capacity_constraint_rule + +.. autofunction:: temoa.extensions.integer_capacity.components.integer_capacity.limit_integer_net_capacity_constraint_rule diff --git a/docs/source/index.rst b/docs/source/index.rst index f9043f39d..3d7f9e3b4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -27,6 +27,7 @@ Temoa Project Documentation myopic stochastics unit_checking + extensions .. toctree:: :maxdepth: 1 diff --git a/docs/source/mathematical_formulation.rst b/docs/source/mathematical_formulation.rst index cc4d3da10..86bd4b4fc 100644 --- a/docs/source/mathematical_formulation.rst +++ b/docs/source/mathematical_formulation.rst @@ -711,35 +711,6 @@ controls the bound direction. The group columns accept either a single technology name or a technology group name. -limit_degrowth_capacity -~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`{LDGC}_{r \in R, t \in T}` - -The :code:`limit_degrowth_capacity` parameter defines the maximum annual rate -at which the total capacity of a technology (or group) can shrink between -periods. The :code:`tech_or_group` column accepts a technology name or group name. - - -limit_degrowth_new_capacity -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`{LDGNC}_{r \in R, t \in T}` - -The :code:`limit_degrowth_new_capacity` parameter constrains the rate of decrease -in new capacity deployment between consecutive periods. - - -limit_degrowth_new_capacity_delta -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`\mathrm{LDGNC}_{\Delta,r \in R, t \in T}` - -The :code:`limit_degrowth_new_capacity_delta` parameter constrains the -deceleration of new capacity degrowth between periods, essentially adding -"intertia" to the degrowth of new capacity deployment. - - limit_emission ~~~~~~~~~~~~~~ @@ -751,35 +722,6 @@ fits within the modeler-specified limit on emission :math:`e` in time period bound, or equality. -limit_growth_capacity -~~~~~~~~~~~~~~~~~~~~~ - -:math:`{LGC}_{r \in R, t \in T}` - -The :code:`limit_growth_capacity` parameter defines the maximum annual rate at -which the total capacity of a technology (or group) can grow between periods. -The :code:`tech_or_group` column accepts a technology name or group name. - - -limit_growth_new_capacity -~~~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`{LGNC}_{r \in R, t \in T}` - -The :code:`limit_growth_new_capacity` parameter constrains the rate of increase -in new capacity deployment between consecutive periods. - - -limit_growth_new_capacity_delta -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`\mathrm{LGNC}_{\Delta,r \in R, t \in T}` - -The :code:`limit_growth_new_capacity_delta` parameter constrains the acceleration -of new capacity growth between periods. This essentially adds "inertia" to the -growth of new capacity deployment. - - limit_new_capacity ~~~~~~~~~~~~~~~~~~ @@ -1437,12 +1379,6 @@ User-Specific Constraints .. autofunction:: temoa.components.storage.limit_storage_fraction_constraint -.. autofunction:: temoa.components.limits.limit_growth_capacity - -.. autofunction:: temoa.components.limits.limit_growth_new_capacity - -.. autofunction:: temoa.components.limits.limit_growth_new_capacity_delta - General Caveats --------------- diff --git a/docs/source/param_desc_and_tables.rst b/docs/source/param_desc_and_tables.rst index 40ff0737d..aef95320e 100644 --- a/docs/source/param_desc_and_tables.rst +++ b/docs/source/param_desc_and_tables.rst @@ -94,20 +94,6 @@ capacity, activity and emissions**. ":math:`\text{LE}_{r,p,e}`", ":code:`limit_emission`", ":code:`limit_emission`", "limit on emissions by region and period" ":math:`\text{LS}_{r,t}`", ":code:`limit_resource`", ":code:`limit_resource`", "cumulative activity limit across time periods (not supported in myopic); :code:`tech_or_group` column accepts a technology name or group name" -Parameters in the table below relate to the specification of **growth and degrowth -limits**. - -.. csv-table:: - :header: "Parameter", "Database Table", "Model Element", "Notes" - :widths: 15, 20, 25, 40 - - ":math:`\text{LGC}_{r,t}`", ":code:`limit_growth_capacity`", ":code:`limit_growth_capacity`", "capacity growth rate limits; :code:`tech_or_group` column accepts a technology name or group name" - ":math:`\text{LDGC}_{r,t}`", ":code:`limit_degrowth_capacity`", ":code:`limit_degrowth_capacity`", "capacity degrowth rate limits; :code:`tech_or_group` column accepts a technology name or group name" - ":math:`\text{LGNC}_{r,t}`", ":code:`limit_growth_new_capacity`", ":code:`limit_growth_new_capacity`", "new capacity growth rate limits; :code:`tech_or_group` column accepts a technology name or group name" - ":math:`\text{LDGNC}_{r,t}`", ":code:`limit_degrowth_new_capacity`", ":code:`limit_degrowth_new_capacity`", "new capacity degrowth rate limits; :code:`tech_or_group` column accepts a technology name or group name" - ":math:`\mathrm{LGNC}_{\Delta,r,t}`", ":code:`limit_growth_new_capacity_delta`", ":code:`limit_growth_new_capacity_delta`", "new capacity growth acceleration limits; :code:`tech_or_group` column accepts a technology name or group name" - ":math:`\mathrm{LDGNC}_{\Delta,r,t}`", ":code:`limit_degrowth_new_capacity_delta`", ":code:`limit_degrowth_new_capacity_delta`", "new capacity degrowth deceleration limits; :code:`tech_or_group` column accepts a technology name or group name" - Parameters in the table below relate to the specification of **operational and split limits**. diff --git a/temoa/_internal/run_actions.py b/temoa/_internal/run_actions.py index d0299a1bb..af2bc0ddd 100644 --- a/temoa/_internal/run_actions.py +++ b/temoa/_internal/run_actions.py @@ -124,6 +124,7 @@ def build_instance( silent: bool = False, keep_lp_file: bool = False, lp_path: Path | None = None, + extensions: Iterable[str] | None = None, ) -> TemoaModel: """ Build a Temoa Instance from data @@ -134,7 +135,7 @@ def build_instance( :param model_name: Optional name for this instance :return: a built TemoaModel """ - model = TemoaModel() + model = TemoaModel(extensions=tuple(extensions or ())) model.dual = Suffix(direction=Suffix.IMPORT) # self.model.rc = Suffix(direction=Suffix.IMPORT) diff --git a/temoa/_internal/temoa_sequencer.py b/temoa/_internal/temoa_sequencer.py index 08ae1290b..bd44044e3 100644 --- a/temoa/_internal/temoa_sequencer.py +++ b/temoa/_internal/temoa_sequencer.py @@ -140,7 +140,11 @@ def build_model(self) -> TemoaModel: tune_sqlite_connection(con, self.config) hybrid_loader = HybridLoader(db_connection=con, config=self.config) data_portal = hybrid_loader.load_data_portal(myopic_index=None) - instance = build_instance(data_portal, silent=self.config.silent) + instance = build_instance( + data_portal, + silent=self.config.silent, + extensions=self.config.extensions, + ) logger.info('Model build process complete.') return instance @@ -220,6 +224,7 @@ def _run_check_mode(self) -> None: silent=self.config.silent, keep_lp_file=self.config.save_lp_file, lp_path=self.config.output_path, + extensions=self.config.extensions, ) if not self.config.price_check: logger.warning('Price check is automatically enabled for CHECK mode.') @@ -238,6 +243,7 @@ def _run_perfect_foresight(self) -> None: silent=self.config.silent, keep_lp_file=self.config.save_lp_file, lp_path=self.config.output_path, + extensions=self.config.extensions, ) if self.config.price_check: price_checker(instance) diff --git a/temoa/cli.py b/temoa/cli.py index 371b0d733..cbcc234c1 100644 --- a/temoa/cli.py +++ b/temoa/cli.py @@ -557,8 +557,8 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None """ Copy tutorial resource files directly to target locations. - The database is generated from the SQL source file to ensure it uses - the latest schema with unit-compliant data (single source of truth). + The database is generated by applying the canonical v4 schema first, + then loading tutorial data SQL. Args: target_config: Path where configuration file should be copied @@ -572,6 +572,7 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None config_resource = base / 'config_sample.toml' sql_resource = base / 'utopia.sql' mc_settings_resource = base / 'mc_settings.csv' + schema_resource = resources.files('temoa.db_schema') / 'temoa_schema_v4.sql' # Copy configuration file with config_resource.open('rb') as source: @@ -582,11 +583,20 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None if target_database.exists(): target_database.unlink() - # Generate database from SQL source (single source of truth) + # Generate database from canonical schema and tutorial data source + schema_content = schema_resource.read_text(encoding='utf-8') sql_content = sql_resource.read_text(encoding='utf-8') with sqlite3.connect(target_database) as conn: + conn.executescript(schema_content) + conn.execute('PRAGMA foreign_keys = OFF;') conn.executescript(sql_content) + conn.execute('PRAGMA foreign_keys = ON;') + fk_violations = conn.execute('PRAGMA foreign_key_check;').fetchall() + if fk_violations: + raise sqlite3.IntegrityError( + f'Foreign key check failed after tutorial data load: {fk_violations[:5]}' + ) # Copy Monte Carlo settings with mc_settings_resource.open('rb') as source: @@ -600,6 +610,7 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None fallback_config = Path(__file__).parent / 'tutorial_assets' / 'config_sample.toml' fallback_sql = Path(__file__).parent / 'tutorial_assets' / 'utopia.sql' fallback_mc = Path(__file__).parent / 'tutorial_assets' / 'mc_settings.csv' + fallback_schema = Path(__file__).parent / 'db_schema' / 'temoa_schema_v4.sql' if not fallback_config.exists(): raise FileNotFoundError( @@ -613,6 +624,12 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None f'SQL: {fallback_sql}' ) from e + if not fallback_schema.exists(): + raise FileNotFoundError( + f'Schema not found. Tried package resources and fallback path:\n' + f'Schema: {fallback_schema}' + ) from e + # Copy config file using fallback path shutil.copy2(fallback_config, target_config) @@ -620,10 +637,19 @@ def _copy_tutorial_resources(target_config: Path, target_database: Path) -> None if target_database.exists(): target_database.unlink() - # Generate database from SQL source + # Generate database from canonical schema and tutorial data source + sql_content = fallback_sql.read_text(encoding='utf-8') with sqlite3.connect(target_database) as conn: - conn.executescript(fallback_sql.read_text(encoding='utf-8')) + conn.executescript(fallback_schema.read_text(encoding='utf-8')) + conn.execute('PRAGMA foreign_keys = OFF;') + conn.executescript(sql_content) + conn.execute('PRAGMA foreign_keys = ON;') + fk_violations = conn.execute('PRAGMA foreign_key_check;').fetchall() + if fk_violations: + raise sqlite3.IntegrityError( + f'Foreign key check failed after tutorial data load: {fk_violations[:5]}' + ) from e # Copy mc_settings from fallback shutil.copy2(fallback_mc, target_config.parent / 'mc_settings.csv') diff --git a/temoa/components/capacity.py b/temoa/components/capacity.py index 1383e09f7..82e553126 100644 --- a/temoa/components/capacity.py +++ b/temoa/components/capacity.py @@ -18,7 +18,7 @@ from deprecated import deprecated from pyomo.environ import value -from .utils import get_capacity_factor +from .utils import get_adjusted_existing_capacity, get_capacity_factor if TYPE_CHECKING: from temoa.core.model import TemoaModel @@ -292,7 +292,9 @@ def annual_retirement_constraint( # Exact EOL. No v_capacity or v_retired_capacity for this period. if p == model.time_optimize.first(): # Must be existing capacity. Apply survival curve to existing cap - cap_begin = model.existing_capacity[r, t, v] * model.lifetime_survival_curve[r, p, t, v] + cap_begin = get_adjusted_existing_capacity(model, r, t, v) * value( + model.lifetime_survival_curve[r, p, t, v] + ) else: # Get previous capacity and continue survival curve p_prev = model.time_optimize.prev(p) @@ -545,8 +547,9 @@ def adjusted_capacity_constraint( the time when that retirement occurred (treated here as at the beginning of each period). """ + built_capacity: ExprLike if v in model.time_exist: - built_capacity = value(model.existing_capacity[r, t, v]) + built_capacity = get_adjusted_existing_capacity(model, r, t, v) else: built_capacity = model.v_new_capacity[r, t, v] diff --git a/temoa/components/limits.py b/temoa/components/limits.py index f7f5d5d9c..0145073ea 100644 --- a/temoa/components/limits.py +++ b/temoa/components/limits.py @@ -20,7 +20,11 @@ import temoa.components.geography as geography import temoa.components.technology as technology -from temoa.components.utils import Operator, get_variable_efficiency, operator_expression +from temoa.components.utils import ( + Operator, + get_variable_efficiency, + operator_expression, +) if TYPE_CHECKING: from pyomo.core import Expression @@ -130,64 +134,6 @@ def limit_tech_output_split_average_constraint_indices( } -def limit_growth_capacity_indices(model: TemoaModel) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_growth_capacity.sparse_keys() - for p in model.time_optimize - } - - -def limit_degrowth_capacity_indices( - model: TemoaModel, -) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_degrowth_capacity.sparse_keys() - for p in model.time_optimize - } - - -def limit_growth_new_capacity_indices( - model: TemoaModel, -) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_growth_new_capacity.sparse_keys() - for p in model.time_optimize - } - - -def limit_degrowth_new_capacity_indices( - model: TemoaModel, -) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_degrowth_new_capacity.sparse_keys() - for p in model.time_optimize - } - - -def limit_growth_new_capacity_delta_indices( - model: TemoaModel, -) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_growth_new_capacity_delta.sparse_keys() - for p in model.time_optimize - } - - -def limit_degrowth_new_capacity_delta_indices( - model: TemoaModel, -) -> set[tuple[Region, Period, Technology, str]]: - return { - (r, p, t, op) - for r, t, op in model.limit_degrowth_new_capacity_delta.sparse_keys() - for p in model.time_optimize - } - - def limit_seasonal_capacity_factor_constraint_indices( model: TemoaModel, ) -> set[tuple[Region, Period, Season, Technology, str]]: @@ -948,393 +894,6 @@ def limit_emission_constraint( return expr -def limit_growth_capacity_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp up rate of available capacity""" - return limit_growth_capacity(model, r, p, t, op, False) - - -def limit_degrowth_capacity_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp down rate of available capacity""" - return limit_growth_capacity(model, r, p, t, op, True) - - -def limit_growth_capacity( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str, degrowth: bool = False -) -> ExprLike: - r""" - Constrain the change of capacity available between periods. - Forces the model to ramp up and down the availability of new technologies - more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional - (rate, :math:`R_{r,t}`) terms. This can be defined for a technology group - instead of one technology, in which case, capacity available is summed over - all technologies in the group. In the first period, previous available - capacity :math:`\mathbf{CAPAVL}_{r,p,t}` is replaced by previous existing - capacity, if any can be found. - - .. math:: - :label: Limit (De)Growth Capacity - - \begin{aligned}\text{Growth:}\\ - &\mathbf{CAPAVL}_{r,p,t} - \quad \le, \ge, \text{or} = \quad - S_{r,t} + (1+R_{r,t}) \cdot \mathbf{CAPAVL}_{r,p_{prev},t} - \end{aligned} - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacity}} - - - \begin{aligned}\text{Degrowth:}\\ - &\mathbf{CAPAVL}_{r,p_{prev},t} - \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot \mathbf{CAPAVL}_{r,p,t} - \end{aligned} - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacity}} - """ - - regions = geography.gather_group_regions(model, r) - techs = technology.gather_group_techs(model, t) - - growth = model.limit_degrowth_capacity if degrowth else model.limit_growth_capacity - rate = 1 + value(growth[r, t, op][0]) - seed = value(growth[r, t, op][1]) - cap_rpt = model.v_capacity_available_by_period_and_tech - - # relevant r, p, t indices - cap_indices = {(_r, _p, _t) for _r, _p, _t in cap_rpt.keys() if _t in techs and _r in regions} - # periods the technology can have capacity in this region (sorted) - periods = sorted({_p for _r, _p, _t in cap_rpt}) - - if len(periods) == 0: - if p == model.time_optimize.first(): - msg = ( - 'Tried to set {}rowthCapacity constraint {} but there are no periods where this ' - 'technology is available in this region. Constraint skipped.' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.warning(msg) - return Constraint.Skip - - # Only warn in p0 so we dont dump multiple warnings - if p == periods[0]: - if seed == 0: - msg = ( - 'No constant term (seed) provided for {}rowthCapacity constraint {}. ' - 'No capacity will be built in any period following one with zero capacity.' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.info(msg) - gaps = [ - _p - for _p in model.time_optimize - if _p not in periods and min(periods) < _p < max(periods) - ] - if gaps: - msg = ( - 'Constructing {}rowthCapacity constraint {} and there are period gaps in which' - 'capacity cannot exist in this region ({}). Capacity in these periods ' - 'will be treated as zero which may cause infeasibility or other problems.' - ).format('Deg' if degrowth else 'G', (r, t), gaps) - logger.warning(msg) - - # sum available capacity in this period - capacity = quicksum(cap_rpt[_r, _p, _t] for _r, _p, _t in cap_indices if _p == p) - - if p == model.time_optimize.first(): - # First future period. Grab available capacity in last existing period - # Adjust in-line for past PLF because we are constraining available capacity - p_prev = model.time_exist.last() - capacity_prev = sum( - value(model.existing_capacity[_r, _t, _v]) - * min(1.0, (_v + value(model.lifetime_process[_r, _t, _v]) - p_prev) / (p - p_prev)) - for _r, _t, _v in model.existing_capacity.sparse_keys() - if _r in regions - and _t in techs - and _v + value(model.lifetime_process[_r, _t, _v]) > p_prev - ) - else: - # Otherwise, grab previous future period - p_prev = model.time_optimize.prev(p) - capacity_prev = quicksum(cap_rpt[_r, _p, _t] for _r, _p, _t in cap_indices if _p == p_prev) - - if degrowth: - expr = operator_expression(capacity_prev, Operator(op), seed + capacity * rate) - else: - expr = operator_expression(capacity, Operator(op), seed + capacity_prev * rate) - - # Check if any variables are actually included before returning - if isinstance(expr, bool): - return Constraint.Skip - return expr - - -def limit_growth_new_capacity_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp up rate of new capacity deployment""" - return limit_growth_new_capacity(model, r, p, t, op, False) - - -def limit_degrowth_new_capacity_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp down rate of new capacity deployment""" - return limit_growth_new_capacity(model, r, p, t, op, True) - - -def limit_growth_new_capacity( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str, degrowth: bool = False -) -> ExprLike: - r""" - Constrain the change of new capacity deployed between periods. - Forces the model to ramp up and down the deployment of new technologies - more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional - (rate, :math:`R_{r,t}`) terms. This can be defined for a technology group - instead of one technology, in which case, new capacity is summed over - all technologies in the group. In the first period, previous new capacity - :math:`\mathbf{NCAP}_{r,t,v_prev}` is replaced by previous existing capacity, - if any can be found. - - .. math:: - :label: Limit (De)Growth New Capacity - - \begin{aligned}\text{Growth:}\\ - &\mathbf{NCAP}_{r,t,v} - \quad \le, \ge, \text{or} = \quad - S_{r,t} + (1+R_{r,t}) \cdot \mathbf{NCAP}_{r,t,v_{prev}} - \text{ where } v=p - \end{aligned} - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacity}} - - \begin{aligned}\text{Degrowth:}\\ - &\mathbf{NCAP}_{r,t,v_{prev}} - \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot \mathbf{NCAP}_{r,t,v} - \text{ where } v=p - \end{aligned} - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacity}} - """ - - regions = geography.gather_group_regions(model, r) - techs = technology.gather_group_techs(model, t) - - growth = model.limit_degrowth_new_capacity if degrowth else model.limit_growth_new_capacity - rate = 1 + value(growth[r, t, op][0]) - seed = value(growth[r, t, op][1]) - new_cap_rtv = model.v_new_capacity - - # relevant r, t, v indices - cap_rtv = {(_r, _t, _v) for _r, _t, _v in new_cap_rtv.keys() if _t in techs and _r in regions} - # periods the technology can be built in this region (sorted) - periods = sorted({_v for _r, _t, _v in cap_rtv}) - - if len(periods) == 0: - if p == model.time_optimize.first(): - msg = ( - 'Tried to set {}rowthNewCapacity constraint {} but there are no periods where this ' - 'technology can be built in this region. Constraint skipped.' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.warning(msg) - return Constraint.Skip - - # Only warn in p0 so we dont dump multiple warnings - if p == periods[0]: - if seed == 0: - msg = ( - 'No constant term (seed) provided for {}rowthNewCapacity constraint {}. ' - 'No capacity will be built in any period following one with zero new capacity.' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.info(msg) - gaps = [ - _p - for _p in model.time_optimize - if _p not in periods and min(periods) < _p < max(periods) - ] - if gaps: - msg = ( - 'Constructing {}rowthNewCapacity constraint {} and there are period gaps in which' - 'new capacity cannot be built in this region ({}). New capacity in these periods ' - 'will be treated as zero which may cause infeasibility or other problems.' - ).format('Deg' if degrowth else 'G', (r, t), gaps) - logger.warning(msg) - - # sum new capacity in this period - new_cap = quicksum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p) - - if p == model.time_optimize.first(): - # First future period. Grab last existing vintage - p_prev = model.time_exist.last() - new_cap_prev = sum( - value(model.existing_capacity[_r, _t, _v]) - for _r, _t, _v in model.existing_capacity.sparse_keys() - if _r in regions and _t in techs and _v == p_prev - ) - else: - # Otherwise, grab previous future vintage - p_prev = model.time_optimize.prev(p) - new_cap_prev = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev) - - if degrowth: - expr = operator_expression(new_cap_prev, Operator(op), seed + new_cap * rate) - else: - expr = operator_expression(new_cap, Operator(op), seed + new_cap_prev * rate) - - # Check if any variables are actually included before returning - if isinstance(expr, bool): - return Constraint.Skip - return expr - - -def limit_growth_new_capacity_delta_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp up rate of change in new capacity deployment""" - return limit_growth_new_capacity_delta(model, r, p, t, op, False) - - -def limit_degrowth_new_capacity_delta_constraint_rule( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str -) -> ExprLike: - r"""Constrain ramp down rate of change in new capacity deployment""" - return limit_growth_new_capacity_delta(model, r, p, t, op, True) - - -def limit_growth_new_capacity_delta( - model: TemoaModel, r: Region, p: Period, t: Technology, op: str, degrowth: bool = False -) -> ExprLike: - r""" - Constrain the acceleration of new capacity deployed between periods. - Forces the model to ramp up and down the change in deployment of new technologies - more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional - (rate, :math:`R_{r,t}`) terms. It is recommended to leave the rate term empty - as it would prevent the possibility of inflection in the rate of deployment. - This constraint can be defined for a technology group instead of one technology, - in which case, new capacity is summed over all technologies in the group. In the - first period, previous new capacities are replaced by previous existing capacities, - if any can be found. - - .. math:: - :label: Limit (De)Growth New Capacity Delta - - \begin{aligned}\text{Growth:}\\ - &\mathbf{NCAP}_{r,t,v_i} - \mathbf{NCAP}_{r,t,v_{i-1}} - \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot - (\mathbf{NCAP}_{r,t,v_{i-1}} - \mathbf{NCAP}_{r,t,v_{i-2}}) - \end{aligned} - - \text{ where } v_i=p - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacityDelta}} - - \begin{aligned}\text{Degrowth:}\\ - &\mathbf{NCAP}_{r,t,v_{i-1}} - \mathbf{NCAP}_{r,t,v_{i-2}} - \quad \le, \ge, \text{or} = \quad - S_{r,t} + (1+R_{r,t}) \cdot (\mathbf{NCAP}_{r,t,v_i} - \mathbf{NCAP}_{r,t,v_{i-1}}) - \end{aligned} - - \text{ where } v_i=p - - \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacityDelta}} - """ - - regions = geography.gather_group_regions(model, r) - techs = technology.gather_group_techs(model, t) - - growth = ( - model.limit_degrowth_new_capacity_delta - if degrowth - else model.limit_growth_new_capacity_delta - ) - rate = 1 + value(growth[r, t, op][0]) - seed = value(growth[r, t, op][1]) - new_cap_rtv = model.v_new_capacity - - # relevant r, t, v indices - cap_rtv = {(_r, _t, _v) for _r, _t, _v in new_cap_rtv.keys() if _t in techs and _r in regions} - # periods the technology can be built in this region (sorted) - periods = sorted({_v for _r, _t, _v in cap_rtv}) - - if len(periods) == 0: - if p == model.time_optimize.first(): - msg = ( - 'Tried to set {}rowthNewCapacityDelta constraint {} but there are no periods where ' - 'this technology can be built in this region. Constraint skipped.' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.warning(msg) - return Constraint.Skip - - # Only warn in p0 so we dont dump multiple warnings - if p == periods[0]: - if seed == 0: - msg = ( - 'No constant term (seed) provided for {}rowthNewCapacityDelta constraint {}. ' - 'This is not recommended as deployment rates cannot inflect (change from ' - 'accelerating to decelerating or vice-versa).' - ).format('Deg' if degrowth else 'G', (r, t)) - logger.warning(msg) - gaps = [ - _p - for _p in model.time_optimize - if _p not in periods and min(periods) < _p < max(periods) - ] - if gaps: - msg = ( - 'Constructing {}rowthNewCapacityDelta constraint {} and there are period gaps in ' - 'which new capacity cannot be built in this region ({}). New capacity in these ' - 'periods will be treated as zero which may cause infeasibility or other problems.' - ).format('Deg' if degrowth else 'G', (r, t), gaps) - logger.warning(msg) - - # sum new capacity in this period - new_cap = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p) - - if p == model.time_optimize.first(): - # First planning period, pull last two existing vintages - p_prev = model.time_exist.last() - new_cap_prev = sum( - value(model.existing_capacity[_r, _t, _v]) - for _r, _t, _v in model.existing_capacity.sparse_keys() - if _r in regions and _t in techs and _v == p_prev - ) - p_prev2 = model.time_exist.prev(p_prev) - new_cap_prev2 = sum( - value(model.existing_capacity[_r, _t, _v]) - for _r, _t, _v in model.existing_capacity.sparse_keys() - if _r in regions and _t in techs and _v == p_prev2 - ) - else: - # Not the first future period. Grab previous future period - p_prev = model.time_optimize.prev(p) - new_cap_prev = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev) - if p == model.time_optimize.at(2): # apparently pyomo sets are indexed 1-based - # Second future period, grab last existing vintage - p_prev2 = model.time_exist.last() - new_cap_prev2 = sum( - value(model.existing_capacity[_r, _t, _v]) - for _r, _t, _v in model.existing_capacity.sparse_keys() - if _r in regions and _t in techs and _v == p_prev2 - ) - else: - # At least the third future period. Grab last two future vintages - p_prev2 = model.time_optimize.prev(p_prev) - new_cap_prev2 = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev2) - - nc_delta_prev = new_cap_prev - new_cap_prev2 - nc_delta = new_cap - new_cap_prev - - if degrowth: - expr = operator_expression(nc_delta_prev, Operator(op), seed + nc_delta * rate) - else: - expr = operator_expression(nc_delta, Operator(op), seed + nc_delta_prev * rate) - - # Check if any variables are actually included before returning - if isinstance(expr, bool): - return Constraint.Skip - return expr - - def limit_activity_constraint( model: TemoaModel, r: Region, p: Period, t: Technology, op: str ) -> ExprLike: diff --git a/temoa/components/technology.py b/temoa/components/technology.py index e9cc254d0..9957db979 100644 --- a/temoa/components/technology.py +++ b/temoa/components/technology.py @@ -17,6 +17,8 @@ from pyomo.environ import value +from temoa.components.utils import get_adjusted_existing_capacity + if TYPE_CHECKING: from collections.abc import Iterable @@ -52,7 +54,23 @@ def model_process_life_indices( the periods in which a process is active, distinct from TechLifeFracIndices that returns indices only for processes that EOL mid-period. """ - return model.active_activity_rptv + indices = { + (r, model.time_exist.last(), t, v) for r, t, v in model.existing_capacity.sparse_keys() + } + indices = indices | model.active_activity_rptv + + return indices + + +def lifetime_tech_indices(model: TemoaModel) -> set[tuple[Region, Technology]]: + """ + Based on the efficiency parameter's indices, this function returns the set of + process indices that may be specified in the lifetime_tech parameter. + """ + indices = {(r, t) for r, _, t, _, _ in set(model.efficiency.sparse_keys())} + indices = indices | {(r, t) for r, t, _ in model.existing_capacity.sparse_keys()} + + return indices def lifetime_process_indices(model: TemoaModel) -> set[tuple[Region, Technology, Vintage]]: @@ -60,7 +78,7 @@ def lifetime_process_indices(model: TemoaModel) -> set[tuple[Region, Technology, Based on the efficiency parameter's indices, this function returns the set of process indices that may be specified in the lifetime_process parameter. """ - indices = {(r, t, v) for r, i, t, v, o in set(model.efficiency.sparse_keys())} + indices = {(r, t, v) for r, _, t, v, _ in set(model.efficiency.sparse_keys())} indices = indices | set(model.existing_capacity.sparse_keys()) return indices @@ -424,14 +442,18 @@ def check_existing_capacity(model: TemoaModel) -> None: ) logger.warning(msg) continue - if t not in model.tech_all: + adjusted_cap = get_adjusted_existing_capacity(model, r, t, v) + if adjusted_cap <= 0.0: + # Was retired in a previous period (myopic mode) continue + p = model.time_optimize.first() life = value(model.lifetime_process[r, t, v]) - if (r, t, v) not in model.process_periods and v + life > model.time_optimize.first(): + if (r, t, v) not in model.process_periods and v + life > p: + surviving_cap = adjusted_cap * value(model.lifetime_survival_curve[r, p, t, v]) msg = ( - f'Existing capacity {r, t, v} with lifetime {life} and capacity {cap} ' - 'should extend into future periods but it is not in process periods. ' - 'Was it included in the Efficiency table?' + f'Existing capacity {r, t, v} with lifetime {life} and surviving capacity ' + f'{surviving_cap} should extend into future periods but is not an active ' + 'process. It may be missing from the Efficiency table or have too little ' + 'capacity to output and carry forward if running in myopic mode.' ) - logger.error(msg) - raise ValueError(msg) + logger.warning(msg) diff --git a/temoa/components/time.py b/temoa/components/time.py index 0877a40b6..cdbb05db4 100644 --- a/temoa/components/time.py +++ b/temoa/components/time.py @@ -184,11 +184,6 @@ def init_set_time_optimize(model: TemoaModel) -> list[int]: return sorted(model.time_future)[:-1] -def init_set_vintage_exist(model: TemoaModel) -> list[int]: - """Initializes the `vintage_exist` set.""" - return sorted(model.time_exist) - - def init_set_vintage_optimize(model: TemoaModel) -> list[int]: """Initializes the `vintage_optimize` set.""" return sorted(model.time_optimize) @@ -196,6 +191,11 @@ def init_set_vintage_optimize(model: TemoaModel) -> list[int]: def param_period_length(model: TemoaModel, p: Period) -> int: """Rule to calculate the length of each optimization period in years.""" + if model.time_exist and p == model.time_exist.last(): + # Need this for one specific use case (capacity growth constraints) + return model.time_future.first() - model.time_exist.last() + elif p in model.time_exist: + return -1 # Period length is not defined for existing periods except the last periods: list[int] = sorted(model.time_future) i: int = periods.index(p) return periods[i + 1] - periods[i] diff --git a/temoa/components/utils.py b/temoa/components/utils.py index 943b90183..daa2b421b 100644 --- a/temoa/components/utils.py +++ b/temoa/components/utils.py @@ -87,3 +87,20 @@ def get_capacity_factor( if model.is_capacity_factor_process[r, t, v]: return value(model.capacity_factor_process[r, s, d, t, v]) return value(model.capacity_factor_tech[r, s, d, t]) + + +def get_adjusted_existing_capacity( + model: TemoaModel, r: Region, t: Technology, v: Vintage +) -> float: + """ + Returns the built existing capacity adjusted for any early retirements. + + Needed for early retirements in myopic mode. Takes into account survival curves + and any early retirements that may have occurred prior to this planning step. + """ + capacity_adjustment = sum( + value(model.retired_existing_capacity[r, _p, t, v]) + / (value(model.lifetime_survival_curve[r, _p, t, v]) or 1) + for _p in model.time_exist + ) + return value(model.existing_capacity[r, t, v]) - capacity_adjustment diff --git a/temoa/core/config.py b/temoa/core/config.py index de3e34302..449024bd8 100644 --- a/temoa/core/config.py +++ b/temoa/core/config.py @@ -5,6 +5,7 @@ from pathlib import Path from temoa.core.modes import TemoaMode +from temoa.extensions.framework import normalize_extension_ids, resolve_extension_specs logger = getLogger(__name__) @@ -71,6 +72,7 @@ def __init__( output_threshold_emission: float | None = None, output_threshold_cost: float | None = None, sqlite: dict[str, object] | None = None, + extensions: list[str] | tuple[str, ...] | None = None, ): if '-' in scenario: raise ValueError( @@ -160,6 +162,9 @@ def __init__( self.output_threshold_emission = output_threshold_emission self.output_threshold_cost = output_threshold_cost self.sqlite_inputs = sqlite or {} + self.extensions = normalize_extension_ids(extensions) + # Validate extension ids eagerly so config failures happen before model build. + resolve_extension_specs(self.extensions) # SQLite performance settings # journal_mode: DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF @@ -326,6 +331,7 @@ def __repr__(self) -> str: msg += '{:>{}s}: {}\n'.format('Scenario', width, self.scenario) msg += '{:>{}s}: {}\n'.format('Scenario mode', width, self.scenario_mode.name) + msg += '{:>{}s}: {}\n'.format('Enabled extensions', width, ', '.join(self.extensions)) msg += '{:>{}s}: {}\n'.format('Config file', width, self.config_file) msg += '{:>{}s}: {}\n'.format('Data source', width, self.input_database) msg += '{:>{}s}: {}\n'.format('Output database target', width, self.output_database) diff --git a/temoa/core/model.py b/temoa/core/model.py index 6c492e2a2..10f0a77b5 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -9,6 +9,7 @@ """ import logging +from collections.abc import Sequence from typing import TYPE_CHECKING from pyomo.core import BuildCheck, Set, Var @@ -38,6 +39,7 @@ technology, time, ) +from temoa.extensions.framework import apply_model_extension_hooks, resolve_extension_specs from temoa.model_checking.validators import ( no_slash_or_pipe, region_check, @@ -99,8 +101,15 @@ class TemoaModel(AbstractModel): # this is used in several places outside this class, and this provides no-build access to it default_lifetime_tech = 40 - def __init__(self, *args: object, **kwargs: object) -> None: + def __init__( + self, + *args: object, + extensions: Sequence[str] | None = None, + **kwargs: object, + ) -> None: AbstractModel.__init__(self, *args, **kwargs) + self.enabled_extensions = tuple(extensions or ()) + self.extension_specs = resolve_extension_specs(self.enabled_extensions) ################################################ # Internally used Data Containers # @@ -212,9 +221,9 @@ def __init__(self, *args: object, **kwargs: object) -> None: ordered=True, initialize=time.init_set_time_optimize, within=self.time_future ) # Define time period vintages to track capacity installation - self.vintage_exist = Set(ordered=True, initialize=time.init_set_vintage_exist) + self.vintage_exist = Set(ordered=True) self.vintage_optimize = Set(ordered=True, initialize=time.init_set_vintage_optimize) - self.vintage_all = Set(initialize=self.time_exist | self.time_optimize) + self.vintage_all = Set(initialize=self.vintage_exist | self.time_optimize) # Perform some basic validation on the specified time periods. self.validate_time = BuildAction(rule=time.validate_time) @@ -335,7 +344,9 @@ def __init__(self, *args: object, **kwargs: object) -> None: # 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.period_length = Param( + self.time_optimize | self.time_exist, initialize=time.param_period_length + ) 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) @@ -383,6 +394,10 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.capacity_to_activity = Param(self.regional_indices, self.tech_all, default=1) self.existing_capacity = Param(self.regional_indices, self.tech_exist, self.vintage_exist) + # This is needed to handle past retirements in myopic mode. Maybe it will find other uses. + self.retired_existing_capacity = Param( + self.regional_indices, self.time_exist, self.tech_exist, self.vintage_exist, default=0 + ) # Dev Note: The below is temporarily useful for passing down to validator to find # set violations @@ -431,9 +446,8 @@ def __init__(self, *args: object, **kwargs: object) -> None: default=1, ) - self.lifetime_tech = Param( - self.regional_indices, self.tech_all, default=TemoaModel.default_lifetime_tech - ) + self.lifetime_tech_rt = Set(dimen=2, initialize=technology.lifetime_tech_indices) + self.lifetime_tech = Param(self.lifetime_tech_rt, default=TemoaModel.default_lifetime_tech) self.lifetime_process_rtv = Set(dimen=3, initialize=technology.lifetime_process_indices) self.lifetime_process = Param( @@ -443,7 +457,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.lifetime_survival_curve = Param( self.regional_indices, Integers, - self.tech_all, + self.tech_all | self.tech_exist, self.vintage_all, default=technology.get_default_survival, validate=validate_0to1, @@ -620,25 +634,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.limit_annual_capacity_factor_constraint_rtvo, validate=validate_0to1 ) - self.limit_growth_capacity = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_degrowth_capacity = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_growth_new_capacity = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_degrowth_new_capacity = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_growth_new_capacity_delta = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_degrowth_new_capacity_delta = Param( - self.regional_global_indices, self.tech_or_group, self.operator - ) - self.limit_emission_constraint_rpe = Set( within=self.regional_global_indices * self.time_optimize @@ -987,51 +982,6 @@ def __init__(self, *args: object, **kwargs: object) -> None: ['Starting LimitGrowth and Activity Constraints'], rule=progress_check ) - self.limit_growth_capacity_constraint_rpt = Set( - dimen=4, initialize=limits.limit_growth_capacity_indices - ) - self.limit_growth_capacity_constraint = Constraint( - self.limit_growth_capacity_constraint_rpt, - rule=limits.limit_growth_capacity_constraint_rule, - ) - self.limit_degrowth_capacity_constraint_rpt = Set( - dimen=4, initialize=limits.limit_degrowth_capacity_indices - ) - self.limit_degrowth_capacity_constraint = Constraint( - self.limit_degrowth_capacity_constraint_rpt, - rule=limits.limit_degrowth_capacity_constraint_rule, - ) - - self.limit_growth_new_capacity_constraint_rpt = Set( - dimen=4, initialize=limits.limit_growth_new_capacity_indices - ) - self.limit_growth_new_capacity_constraint = Constraint( - self.limit_growth_new_capacity_constraint_rpt, - rule=limits.limit_growth_new_capacity_constraint_rule, - ) - self.limit_degrowth_new_capacity_constraint_rpt = Set( - dimen=4, initialize=limits.limit_degrowth_new_capacity_indices - ) - self.limit_degrowth_new_capacity_constraint = Constraint( - self.limit_degrowth_new_capacity_constraint_rpt, - rule=limits.limit_degrowth_new_capacity_constraint_rule, - ) - - self.limit_growth_new_capacity_delta_constraint_rpt = Set( - dimen=4, initialize=limits.limit_growth_new_capacity_delta_indices - ) - self.limit_growth_new_capacity_delta_constraint = Constraint( - self.limit_growth_new_capacity_delta_constraint_rpt, - rule=limits.limit_growth_new_capacity_delta_constraint_rule, - ) - self.limit_degrowth_new_capacity_delta_constraint_rpt = Set( - dimen=4, initialize=limits.limit_degrowth_new_capacity_delta_indices - ) - self.limit_degrowth_new_capacity_delta_constraint = Constraint( - self.limit_degrowth_new_capacity_delta_constraint_rpt, - rule=limits.limit_degrowth_new_capacity_delta_constraint_rule, - ) - self.limit_activity_constraint = Constraint( self.limit_activity_constraint_rpt, rule=limits.limit_activity_constraint ) @@ -1144,6 +1094,8 @@ def __init__(self, *args: object, **kwargs: object) -> None: rule=emissions.linked_emissions_tech_constraint, ) + apply_model_extension_hooks(self, self.extension_specs) + self.progress_marker_9 = BuildAction(['Finished Constraints'], rule=progress_check) diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index e22fdf673..c02513f90 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -16,11 +16,14 @@ to add a new `LoadItem` to this manifest. """ +from collections.abc import Sequence + from temoa.core.model import TemoaModel from temoa.data_io.loader_manifest import LoadItem +from temoa.extensions.framework import append_extension_manifest_items, resolve_extension_specs -def build_manifest(model: TemoaModel) -> list[LoadItem]: +def build_manifest(model: TemoaModel, extension_ids: Sequence[str] | None = None) -> list[LoadItem]: """ Builds the manifest of all data components to be loaded into the Pyomo model. @@ -288,6 +291,14 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_period_filtered=False, # Custom loader handles all logic is_table_required=False, ), + LoadItem( + component=model.retired_existing_capacity, + table='output_retired_capacity', + columns=['region', 'period', 'tech', 'vintage', 'cap_early'], + custom_loader_name='_load_retired_existing_capacity', + is_period_filtered=False, # Custom loader handles all logic + is_table_required=False, + ), LoadItem( component=model.cost_invest, table='cost_invest', @@ -419,8 +430,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: component=model.lifetime_tech, table='lifetime_tech', columns=['region', 'tech', 'lifetime'], - validator_name='viable_rt', - validation_map=(0, 1), + custom_loader_name='_load_lifetime_tech', is_period_filtered=False, is_table_required=False, ), @@ -428,8 +438,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: component=model.lifetime_process, table='lifetime_process', columns=['region', 'tech', 'vintage', 'lifetime'], - validator_name='viable_rtv', - validation_map=(0, 1, 2), + custom_loader_name='_load_lifetime_process', is_period_filtered=False, is_table_required=False, ), @@ -437,8 +446,7 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: component=model.lifetime_survival_curve, table='lifetime_survival_curve', columns=['region', 'period', 'tech', 'vintage', 'fraction'], - validator_name='viable_rtv', - validation_map=(0, 2, 3), + custom_loader_name='_load_lifetime_survival_curve', is_period_filtered=False, is_table_required=False, ), @@ -729,4 +737,5 @@ def build_manifest(model: TemoaModel) -> list[LoadItem]: is_table_required=False, ), ] - return manifest + extension_specs = resolve_extension_specs(extension_ids) + return append_extension_manifest_items(model, manifest, extension_specs) diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index a4e2ce4d2..8bb73ba20 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -24,6 +24,7 @@ import time from collections import defaultdict from logging import getLogger +from operator import itemgetter from sqlite3 import Connection, Cursor, OperationalError from typing import TYPE_CHECKING, cast @@ -33,6 +34,12 @@ from temoa.core.model import TemoaModel from temoa.core.modes import TemoaMode from temoa.data_io.component_manifest import build_manifest +from temoa.extensions.framework import ( + assert_disabled_extension_tables_are_empty, + ensure_enabled_extension_tables_exist, + merge_regional_group_tables, + resolve_extension_specs, +) from temoa.extensions.myopic.myopic_index import MyopicIndex from temoa.model_checking import element_checker, network_model_data from temoa.model_checking.commodity_network_manager import CommodityNetworkManager @@ -43,11 +50,12 @@ from temoa.core.config import TemoaConfig from temoa.data_io.loader_manifest import LoadItem + from temoa.types.core_types import Region, Technology, Vintage logger = getLogger(__name__) # A manifest of tables that may contain region groups, used by a custom loader. -tables_with_regional_groups = { +BASE_REGIONAL_GROUP_TABLES = { 'limit_annual_capacity_factor': 'region', 'limit_emission': 'region', 'limit_seasonal_capacity_factor': 'region', @@ -58,12 +66,6 @@ 'limit_capacity_share': 'region', 'limit_new_capacity_share': 'region', 'limit_resource': 'region', - 'limit_growth_capacity': 'region', - 'limit_degrowth_capacity': 'region', - 'limit_growth_new_capacity': 'region', - 'limit_degrowth_new_capacity': 'region', - 'limit_growth_new_capacity_delta': 'region', - 'limit_degrowth_new_capacity_delta': 'region', } @@ -88,16 +90,29 @@ def __init__(self, db_connection: Connection, config: TemoaConfig) -> None: self.con = db_connection self.config = config self.myopic_index: MyopicIndex | None = None + self.extension_specs = resolve_extension_specs(self.config.extensions) + self.model = TemoaModel(extensions=self.config.extensions) + self.tables_with_regional_groups = merge_regional_group_tables( + BASE_REGIONAL_GROUP_TABLES, self.extension_specs + ) + ensure_enabled_extension_tables_exist( + self.con, + self.extension_specs, + input_database=str(self.config.input_database), + silent=self.config.silent, + ) + assert_disabled_extension_tables_are_empty(self.con, self.extension_specs) # Build the data loading manifest and a name-based map for quick lookup - model = TemoaModel() - self.manifest = build_manifest(model) + self.manifest = build_manifest(self.model, extension_ids=self.config.extensions) self.manifest_map = {item.component.name: item for item in self.manifest} # --- Data containers and filters populated during loading --- self.manager: CommodityNetworkManager | None = None self.efficiency_values: list[tuple[object, ...]] = [] self.data: dict[str, object] | None = None + self.viable_existing_rt: set[tuple[Region, Technology]] = set() + self.viable_existing_rtv: set[tuple[Region, Technology, Vintage]] = set() # --- Viable sets for source-trace filtering --- self.viable_techs: ViableSet | None = None @@ -201,7 +216,7 @@ def create_data_dict(self, myopic_index: MyopicIndex | None = None) -> dict[str, data: dict[str, object] = {} cur = self.con.cursor() - model = TemoaModel() + model = self.model # Load critical time sets first, as they index other components if myopic_index: @@ -231,6 +246,10 @@ def create_data_dict(self, myopic_index: MyopicIndex | None = None) -> dict[str, for item in self.manifest: # 1. Fetch data from the database raw_data = self._fetch_data(cur, item, myopic_index) + if item.index_length: + raw_data = [ + (*row[0 : item.index_length], row[item.index_length :]) for row in raw_data + ] # 2. Validate/filter data filtered_data = self._filter_data(raw_data, item, use_raw_data) @@ -517,7 +536,7 @@ def _load_regional_global_indices( """ Aggregates region and group names from the Region table and all Limit tables. """ - model = TemoaModel() + model = self.model cur = self.con.cursor() regions_and_groups: set[str] = set() @@ -526,7 +545,7 @@ def _load_regional_global_indices( t[0] for t in cur.execute('SELECT region FROM main.region').fetchall() ) - for table, field_name in tables_with_regional_groups.items(): + for table, field_name in self.tables_with_regional_groups.items(): if self.table_exists(table): regions_and_groups.update( t[0] for t in cur.execute(f'SELECT {field_name} FROM main.{table}').fetchall() @@ -629,6 +648,120 @@ def _load_existing_capacity( if rows_to_load: tech_exist_data = sorted({(row[1],) for row in rows_to_load}) self._load_component_data(data, model.tech_exist, tech_exist_data) + vintage_exist_data = sorted({(row[2],) for row in rows_to_load}) + self._load_component_data(data, model.vintage_exist, vintage_exist_data) + + # Collect existing capacity data indices + self.viable_existing_techs = {row[1] for row in rows_to_load} + self.viable_existing_rt = {(row[0], row[1]) for row in rows_to_load} + self.viable_existing_rtv = {(row[0], row[1], row[2]) for row in rows_to_load} + + def _load_retired_existing_capacity( + self, + data: dict[str, object], + raw_data: Sequence[tuple[object, ...]], + filtered_data: Sequence[tuple[object, ...]], + ) -> None: + """ + Only needed in myopic to bring past early retirement decisions forward + """ + if not self.table_exists('output_retired_capacity'): + logger.info( + "Table 'output_retired_capacity' not found. Skipping loading " + 'of retired existing capacity.' + ) + return + + model = TemoaModel() + cur = self.con.cursor() + mi = self.myopic_index + + if not mi: + # for now, we only use this in myopic mode + return + + rows_to_load = [] + prev_period_res = cur.execute( + 'SELECT MAX(period) FROM time_period WHERE period < ?', (mi.base_year,) + ).fetchone() + prev_period = prev_period_res[0] if prev_period_res else -1 + rows_to_load = cur.execute( + 'SELECT region, period, tech, vintage, cap_early FROM output_retired_capacity WHERE ' + 'period <= ? AND scenario = ? AND cap_early > 0 ', + (prev_period, self.config.scenario), + ).fetchall() + + self._load_component_data(data, model.retired_existing_capacity, rows_to_load) + + # --- Lifetime components --- + def _load_lifetime_tech( + self, + data: dict[str, object], + raw_data: Sequence[tuple[object, ...]], + filtered_data: Sequence[tuple[object, ...]], + ) -> None: + """Loads the lifetime_tech component.""" + model = TemoaModel() + cur = self.con.cursor() + rows_to_load = cur.execute('SELECT region, tech, lifetime FROM lifetime_tech').fetchall() + rt_getter = itemgetter(0, 1) + if self.viable_rt: + valid_rt = self.viable_rt.members | self.viable_existing_rt + rows_to_load = [item for item in rows_to_load if rt_getter(item) in valid_rt] + self._load_component_data(data, model.lifetime_tech, rows_to_load) + + def _load_lifetime_process( + self, + data: dict[str, object], + raw_data: Sequence[tuple[object, ...]], + filtered_data: Sequence[tuple[object, ...]], + ) -> None: + """Loads the lifetime_process component.""" + model = TemoaModel() + cur = self.con.cursor() + mi = self.myopic_index + + if mi: + rows_to_load = cur.execute( + 'SELECT region, tech, vintage, lifetime FROM lifetime_process WHERE vintage <= ?', + (mi.last_demand_year,), + ).fetchall() + else: + rows_to_load = cur.execute( + 'SELECT region, tech, vintage, lifetime FROM lifetime_process' + ).fetchall() + rtv_getter = itemgetter(0, 1, 2) + if self.viable_rtv: + valid_rtv = self.viable_rtv.member_tuples | self.viable_existing_rtv + rows_to_load = [item for item in rows_to_load if rtv_getter(item) in valid_rtv] + self._load_component_data(data, model.lifetime_process, rows_to_load) + + def _load_lifetime_survival_curve( + self, + data: dict[str, object], + raw_data: Sequence[tuple[object, ...]], + filtered_data: Sequence[tuple[object, ...]], + ) -> None: + """Loads the lifetime_survival_curve component.""" + model = TemoaModel() + cur = self.con.cursor() + mi = self.myopic_index + + if mi: + rows_to_load = cur.execute( + 'SELECT region, period, tech, vintage, fraction FROM lifetime_survival_curve ' + 'WHERE vintage <= ?', + (mi.last_demand_year,), + ).fetchall() + else: + rows_to_load = cur.execute( + 'SELECT region, period, tech, vintage, fraction FROM lifetime_survival_curve' + ).fetchall() + rtv_getter = itemgetter(0, 2, 3) + if self.viable_rtv: + valid_rtv = self.viable_rtv.member_tuples | self.viable_existing_rtv + rows_to_load = [item for item in rows_to_load if rtv_getter(item) in valid_rtv] + self._load_component_data(data, model.lifetime_survival_curve, rows_to_load) # --- Singleton and Configuration-based Components --- def _load_global_discount_rate( diff --git a/temoa/data_io/loader_manifest.py b/temoa/data_io/loader_manifest.py index ad6ce930d..5723d9e96 100644 --- a/temoa/data_io/loader_manifest.py +++ b/temoa/data_io/loader_manifest.py @@ -50,6 +50,7 @@ class LoadItem: component: ComponentType table: str columns: list[str] + index_length: int | None = None validator_name: str | None = None validation_map: tuple[int, ...] = field(default_factory=tuple) where_clause: str | None = None diff --git a/temoa/db_schema/temoa_schema_v4.sql b/temoa/db_schema/temoa_schema_v4.sql index 77b146356..69eef34a5 100644 --- a/temoa/db_schema/temoa_schema_v4.sql +++ b/temoa/db_schema/temoa_schema_v4.sql @@ -389,78 +389,6 @@ CREATE TABLE IF NOT EXISTS operator 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'); -CREATE TABLE IF NOT EXISTS limit_growth_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE IF NOT EXISTS limit_degrowth_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE IF NOT EXISTS limit_growth_new_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE IF NOT EXISTS limit_growth_new_capacity_delta -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity_delta -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); CREATE TABLE IF NOT EXISTS limit_storage_level_fraction ( region TEXT, diff --git a/temoa/extensions/framework.py b/temoa/extensions/framework.py new file mode 100644 index 000000000..7239da04e --- /dev/null +++ b/temoa/extensions/framework.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +from pathlib import Path +from dataclasses import dataclass, field +from sqlite3 import Connection +from typing import TYPE_CHECKING + +from collections.abc import Callable + +if TYPE_CHECKING: + from collections.abc import Mapping, Sequence + + from temoa.core.model import TemoaModel + from temoa.data_io.loader_manifest import LoadItem + +ModelHook = Callable[['TemoaModel'], None] +ManifestHook = Callable[['TemoaModel'], list['LoadItem']] + + +@dataclass(frozen=True) +class ExtensionSpec: + """Declarative metadata and hooks for an optional modeling extension.""" + + extension_id: str + owned_tables: tuple[str, ...] = () + regional_group_tables: dict[str, str] = field(default_factory=dict) + register_model_components: ModelHook | None = None + build_manifest_items: ManifestHook | None = None + schema_sql_path: str | None = None + fail_if_tables_populated_when_disabled: bool = False + + +def normalize_extension_ids(extension_ids: Sequence[str] | None) -> tuple[str, ...]: + """Normalize configured extension ids while preserving user-provided order.""" + if not extension_ids: + return () + + normalized: list[str] = [] + seen: set[str] = set() + for ext_id in extension_ids: + if not isinstance(ext_id, str): + raise ValueError(f'Extension ids must be strings. Received: {type(ext_id).__name__}') + cleaned = ext_id.strip().lower() + if not cleaned: + continue + if cleaned not in seen: + normalized.append(cleaned) + seen.add(cleaned) + + return tuple(normalized) + + +def get_known_extension_specs() -> dict[str, ExtensionSpec]: + """Return all extension specs known to this installation.""" + from temoa.extensions.growth_rates.extension import GROWTH_RATES_EXTENSION + from temoa.extensions.integer_capacity.extension import INTEGER_CAPACITY_EXTENSION + + specs = [GROWTH_RATES_EXTENSION, INTEGER_CAPACITY_EXTENSION] + return {spec.extension_id: spec for spec in specs} + + +def resolve_extension_specs(extension_ids: Sequence[str] | None) -> tuple[ExtensionSpec, ...]: + """Validate enabled extension ids and return corresponding specs in user order.""" + normalized_ids = normalize_extension_ids(extension_ids) + known = get_known_extension_specs() + unknown = [ext_id for ext_id in normalized_ids if ext_id not in known] + if unknown: + known_ids = ', '.join(sorted(known)) + unknown_ids = ', '.join(sorted(unknown)) + raise ValueError( + f'Unknown extension id(s): {unknown_ids}. Known extension ids: {known_ids}.' + ) + + return tuple(known[ext_id] for ext_id in normalized_ids) + + +def apply_model_extension_hooks(model: TemoaModel, specs: Sequence[ExtensionSpec]) -> None: + """Attach extension-owned model components to a model instance.""" + for spec in specs: + if spec.register_model_components is not None: + spec.register_model_components(model) + + +def append_extension_manifest_items( + model: TemoaModel, manifest: list[LoadItem], specs: Sequence[ExtensionSpec] +) -> list[LoadItem]: + """Append extension-specific manifest items to the base manifest.""" + merged = list(manifest) + for spec in specs: + if spec.build_manifest_items is not None: + merged.extend(spec.build_manifest_items(model)) + return merged + + +def merge_regional_group_tables( + base_tables: Mapping[str, str], specs: Sequence[ExtensionSpec] +) -> dict[str, str]: + """Merge base regional-group table map with extension-contributed entries.""" + merged = dict(base_tables) + for spec in specs: + for table_name, field_name in spec.regional_group_tables.items(): + existing = merged.get(table_name) + if existing is not None and existing != field_name: + raise ValueError( + f"Regional-group table '{table_name}' has conflicting field mappings: " + f"'{existing}' vs '{field_name}' from extension '{spec.extension_id}'." + ) + merged[table_name] = field_name + return merged + + +def assert_disabled_extension_tables_are_empty( + con: Connection, enabled_specs: Sequence[ExtensionSpec] +) -> None: + """Fail if disabled extensions with strict guards own tables populated with data.""" + enabled_ids = {spec.extension_id for spec in enabled_specs} + for spec in get_known_extension_specs().values(): + if spec.extension_id in enabled_ids: + continue + if not spec.fail_if_tables_populated_when_disabled: + continue + + populated: list[str] = [] + for table in spec.owned_tables: + if _table_has_rows(con, table): + populated.append(table) + + if populated: + table_list = ', '.join(sorted(populated)) + raise RuntimeError( + f"Extension '{spec.extension_id}' is not enabled, but extension-owned table(s) " + f'contain data: {table_list}. Enable the extension or remove those rows.' + ) + + +def ensure_enabled_extension_tables_exist( + con: Connection, + enabled_specs: Sequence[ExtensionSpec], + *, + input_database: str, + silent: bool, +) -> None: + """Ensure enabled extensions have required tables, offering to append schema if missing.""" + for spec in enabled_specs: + missing_tables = [table for table in spec.owned_tables if not _table_exists(con, table)] + if not missing_tables: + continue + + missing_list = ', '.join(sorted(missing_tables)) + if not spec.schema_sql_path: + raise RuntimeError( + f"Extension '{spec.extension_id}' is enabled, but required table(s) are missing: " + f'{missing_list}. No schema SQL path is registered for this extension.' + ) + + should_apply = False + if not silent: + prompt = ( + f"Extension '{spec.extension_id}' is enabled but missing table(s): {missing_list}. " + f"Append schema from '{spec.schema_sql_path}' to input database '{input_database}' now? " + '[y/N]: ' + ) + response = input(prompt).strip().lower() + should_apply = response in {'y', 'yes'} + + if not should_apply: + raise RuntimeError( + f"Extension '{spec.extension_id}' is enabled, but required table(s) are missing: " + f"{missing_list}. Re-run and accept the prompt, or append schema manually from " + f"'{spec.schema_sql_path}' to '{input_database}'." + ) + + _append_extension_schema(con, spec) + still_missing = [table for table in spec.owned_tables if not _table_exists(con, table)] + if still_missing: + still_missing_list = ', '.join(sorted(still_missing)) + raise RuntimeError( + f"Schema append for extension '{spec.extension_id}' completed but table(s) are still " + f'missing: {still_missing_list}.' + ) + + +def _table_has_rows(con: Connection, table_name: str) -> bool: + cur = con.cursor() + table_exists = cur.execute( + "SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?", (table_name,) + ).fetchone() + if not table_exists: + return False + + query = f'SELECT 1 FROM main.{table_name} LIMIT 1' + return cur.execute(query).fetchone() is not None + + +def _table_exists(con: Connection, table_name: str) -> bool: + cur = con.cursor() + exists = cur.execute( + "SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?", (table_name,) + ).fetchone() + return bool(exists) + + +def _append_extension_schema(con: Connection, spec: ExtensionSpec) -> None: + if spec.schema_sql_path is None: + raise RuntimeError(f"Extension '{spec.extension_id}' has no schema SQL path configured.") + + schema_path = Path(spec.schema_sql_path) + if not schema_path.is_file(): + raise FileNotFoundError( + f"Schema SQL file for extension '{spec.extension_id}' not found: {schema_path}" + ) + + sql = schema_path.read_text(encoding='utf-8') + con.executescript(sql) + con.commit() diff --git a/temoa/extensions/growth_rates/__init__.py b/temoa/extensions/growth_rates/__init__.py new file mode 100644 index 000000000..7156dc7f8 --- /dev/null +++ b/temoa/extensions/growth_rates/__init__.py @@ -0,0 +1,3 @@ +from temoa.extensions.growth_rates.extension import GROWTH_RATES_EXTENSION + +__all__ = ['GROWTH_RATES_EXTENSION'] diff --git a/temoa/extensions/growth_rates/components/__init__.py b/temoa/extensions/growth_rates/components/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/growth_rates/components/growth_capacity.py b/temoa/extensions/growth_rates/components/growth_capacity.py new file mode 100644 index 000000000..14a15ca64 --- /dev/null +++ b/temoa/extensions/growth_rates/components/growth_capacity.py @@ -0,0 +1,123 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from pyomo.environ import Constraint, quicksum, value + +import temoa.components.geography as geography +import temoa.components.technology as technology +from temoa.components.utils import Operator, get_adjusted_existing_capacity, operator_expression + +if TYPE_CHECKING: + from temoa.extensions.growth_rates.core.model import GrowthRatesModel + from temoa.types import ExprLike, Period, Region, Technology + + +def limit_growth_capacity_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_growth_capacity.sparse_keys() + for p in model.time_optimize + } + + +def limit_degrowth_capacity_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_degrowth_capacity.sparse_keys() + for p in model.time_optimize + } + + +def limit_growth_capacity_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_capacity(model, r, p, t, op, False) + + +def limit_degrowth_capacity_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_capacity(model, r, p, t, op, True) + + +def limit_growth_capacity( + model: GrowthRatesModel, + r: Region, + p: Period, + t: Technology, + op: str, + degrowth: bool = False, +) -> ExprLike: + r""" + Constrain the change of capacity available between periods. + Forces the model to ramp up and down the availability of new technologies + more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional + (rate, :math:`R_{r,t}`) terms. This can be defined for a technology group + instead of one technology, in which case, capacity available is summed over + all technologies in the group. In the first period, previous available + capacity :math:`\mathbf{CAPAVL}_{r,p,t}` is replaced by previous existing + capacity, if any can be found. + + .. math:: + :label: Limit (De)Growth Capacity + + \begin{aligned}\text{Growth:}\\ + &\mathbf{CAPAVL}_{r,p,t} + \quad \le, \ge, \text{or} = \quad + S_{r,t} + (1+R_{r,t}) \cdot \mathbf{CAPAVL}_{r,p_{prev},t} + \end{aligned} + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacity}} + + + \begin{aligned}\text{Degrowth:}\\ + &\mathbf{CAPAVL}_{r,p_{prev},t} + \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot \mathbf{CAPAVL}_{r,p,t} + \end{aligned} + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacity}} + """ + + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + + growth = model.limit_degrowth_capacity if degrowth else model.limit_growth_capacity + rate = 1 + value(growth[r, t, op][0]) + seed = value(growth[r, t, op][1]) + cap_rpt = model.v_capacity_available_by_period_and_tech + + cap_indices = {(_r, _p, _t) for _r, _p, _t in cap_rpt.keys() if _t in techs and _r in regions} + periods = sorted({_p for _r, _p, _t in cap_rpt}) + + if len(periods) == 0: + return Constraint.Skip + + capacity = quicksum(cap_rpt[_r, _p, _t] for _r, _p, _t in cap_indices if _p == p) + + if p == model.time_optimize.first(): + p_prev = model.time_exist.last() + capacity_prev = sum( + get_adjusted_existing_capacity(model, _r, _t, _v) + * value(model.process_life_frac[_r, p_prev, _t, _v]) + for _r, _t, _v in model.existing_capacity.sparse_keys() + if _r in regions + and _t in techs + and _v + value(model.lifetime_process[_r, _t, _v]) > p_prev + ) + else: + p_prev = model.time_optimize.prev(p) + capacity_prev = quicksum(cap_rpt[_r, _p, _t] for _r, _p, _t in cap_indices if _p == p_prev) + + if degrowth: + expr = operator_expression(capacity_prev, Operator(op), seed + capacity * rate) + else: + expr = operator_expression(capacity, Operator(op), seed + capacity_prev * rate) + + if isinstance(expr, bool): + return Constraint.Skip + return expr diff --git a/temoa/extensions/growth_rates/components/growth_new_capacity.py b/temoa/extensions/growth_rates/components/growth_new_capacity.py new file mode 100644 index 000000000..e0115be0b --- /dev/null +++ b/temoa/extensions/growth_rates/components/growth_new_capacity.py @@ -0,0 +1,121 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from pyomo.environ import Constraint, quicksum, value + +import temoa.components.geography as geography +import temoa.components.technology as technology +from temoa.components.utils import Operator, operator_expression + +if TYPE_CHECKING: + from temoa.extensions.growth_rates.core.model import GrowthRatesModel + from temoa.types import ExprLike, Period, Region, Technology + + +def limit_growth_new_capacity_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_growth_new_capacity.sparse_keys() + for p in model.time_optimize + } + + +def limit_degrowth_new_capacity_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_degrowth_new_capacity.sparse_keys() + for p in model.time_optimize + } + + +def limit_growth_new_capacity_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_new_capacity(model, r, p, t, op, False) + + +def limit_degrowth_new_capacity_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_new_capacity(model, r, p, t, op, True) + + +def limit_growth_new_capacity( + model: GrowthRatesModel, + r: Region, + p: Period, + t: Technology, + op: str, + degrowth: bool = False, +) -> ExprLike: + r""" + Constrain the change of new capacity deployed between periods. + Forces the model to ramp up and down the deployment of new technologies + more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional + (rate, :math:`R_{r,t}`) terms. This can be defined for a technology group + instead of one technology, in which case, new capacity is summed over + all technologies in the group. In the first period, previous new capacity + :math:`\mathbf{NCAP}_{r,t,v_prev}` is replaced by previous existing capacity, + if any can be found. + + .. math:: + :label: Limit (De)Growth New Capacity + + \begin{aligned}\text{Growth:}\\ + &\mathbf{NCAP}_{r,t,v} + \quad \le, \ge, \text{or} = \quad + S_{r,t} + (1+R_{r,t}) \cdot \mathbf{NCAP}_{r,t,v_{prev}} + \text{ where } v=p + \end{aligned} + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacity}} + + \begin{aligned}\text{Degrowth:}\\ + &\mathbf{NCAP}_{r,t,v_{prev}} + \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot \mathbf{NCAP}_{r,t,v} + \text{ where } v=p + \end{aligned} + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacity}} + """ + + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + + growth = model.limit_degrowth_new_capacity if degrowth else model.limit_growth_new_capacity + rate = 1 + value(growth[r, t, op][0]) + seed = value(growth[r, t, op][1]) + new_cap_rtv = model.v_new_capacity + + cap_rtv = {(_r, _t, _v) for _r, _t, _v in new_cap_rtv.keys() if _t in techs and _r in regions} + periods = sorted({_v for _r, _t, _v in cap_rtv}) + + if len(periods) == 0: + return Constraint.Skip + + new_cap = quicksum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p) + + if p == model.time_optimize.first(): + p_prev = model.time_exist.last() + new_cap_prev = sum( + value(model.existing_capacity[_r, _t, _v]) + for _r, _t, _v in model.existing_capacity.sparse_keys() + if _r in regions and _t in techs and _v == p_prev + ) + else: + p_prev = model.time_optimize.prev(p) + new_cap_prev = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev) + + if degrowth: + expr = operator_expression(new_cap_prev, Operator(op), seed + new_cap * rate) + else: + expr = operator_expression(new_cap, Operator(op), seed + new_cap_prev * rate) + + if isinstance(expr, bool): + return Constraint.Skip + return expr diff --git a/temoa/extensions/growth_rates/components/growth_new_capacity_delta.py b/temoa/extensions/growth_rates/components/growth_new_capacity_delta.py new file mode 100644 index 000000000..c06b12901 --- /dev/null +++ b/temoa/extensions/growth_rates/components/growth_new_capacity_delta.py @@ -0,0 +1,148 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from pyomo.environ import Constraint, value + +import temoa.components.geography as geography +import temoa.components.technology as technology +from temoa.components.utils import Operator, operator_expression + +if TYPE_CHECKING: + from temoa.extensions.growth_rates.core.model import GrowthRatesModel + from temoa.types import ExprLike, Period, Region, Technology + + +def limit_growth_new_capacity_delta_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_growth_new_capacity_delta.sparse_keys() + for p in model.time_optimize + } + + +def limit_degrowth_new_capacity_delta_indices( + model: GrowthRatesModel, +) -> set[tuple[Region, Period, Technology, str]]: + return { + (r, p, t, op) + for r, t, op in model.limit_degrowth_new_capacity_delta.sparse_keys() + for p in model.time_optimize + } + + +def limit_growth_new_capacity_delta_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_new_capacity_delta(model, r, p, t, op, False) + + +def limit_degrowth_new_capacity_delta_constraint_rule( + model: GrowthRatesModel, r: Region, p: Period, t: Technology, op: str +) -> ExprLike: + return limit_growth_new_capacity_delta(model, r, p, t, op, True) + + +def limit_growth_new_capacity_delta( + model: GrowthRatesModel, + r: Region, + p: Period, + t: Technology, + op: str, + degrowth: bool = False, +) -> ExprLike: + r""" + Constrain the acceleration of new capacity deployed between periods. + Forces the model to ramp up and down the change in deployment of new technologies + more smoothly. Has constant (seed, :math:`S_{r,t}`) and proportional + (rate, :math:`R_{r,t}`) terms. It is recommended to leave the rate term empty + as it would prevent the possibility of inflection in the rate of deployment. + This constraint can be defined for a technology group instead of one technology, + in which case, new capacity is summed over all technologies in the group. In the + first period, previous new capacities are replaced by previous existing capacities, + if any can be found. + + .. math:: + :label: Limit (De)Growth New Capacity Delta + + \begin{aligned}\text{Growth:}\\ + &\mathbf{NCAP}_{r,t,v_i} - \mathbf{NCAP}_{r,t,v_{i-1}} + \quad \le, \ge, \text{or} = \quad S_{r,t} + (1+R_{r,t}) \cdot + (\mathbf{NCAP}_{r,t,v_{i-1}} - \mathbf{NCAP}_{r,t,v_{i-2}}) + \end{aligned} + + \text{ where } v_i=p + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_growth\_capacityDelta}} + + \begin{aligned}\text{Degrowth:}\\ + &\mathbf{NCAP}_{r,t,v_{i-1}} - \mathbf{NCAP}_{r,t,v_{i-2}} + \quad \le, \ge, \text{or} = \quad + S_{r,t} + (1+R_{r,t}) \cdot (\mathbf{NCAP}_{r,t,v_i} - \mathbf{NCAP}_{r,t,v_{i-1}}) + \end{aligned} + + \text{ where } v_i=p + + \qquad \forall \{r, p, t\} \in \Theta_{\text{limit\_degrowth\_capacityDelta}} + """ + + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + + growth = ( + model.limit_degrowth_new_capacity_delta + if degrowth + else model.limit_growth_new_capacity_delta + ) + rate = 1 + value(growth[r, t, op][0]) + seed = value(growth[r, t, op][1]) + new_cap_rtv = model.v_new_capacity + + cap_rtv = {(_r, _t, _v) for _r, _t, _v in new_cap_rtv.keys() if _t in techs and _r in regions} + periods = sorted({_v for _r, _t, _v in cap_rtv}) + + if len(periods) == 0: + return Constraint.Skip + + new_cap = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p) + + if p == model.time_optimize.first(): + p_prev = model.time_exist.last() + new_cap_prev = sum( + value(model.existing_capacity[_r, _t, _v]) + for _r, _t, _v in model.existing_capacity.sparse_keys() + if _r in regions and _t in techs and _v == p_prev + ) + p_prev2 = model.time_exist.prev(p_prev) + new_cap_prev2 = sum( + value(model.existing_capacity[_r, _t, _v]) + for _r, _t, _v in model.existing_capacity.sparse_keys() + if _r in regions and _t in techs and _v == p_prev2 + ) + else: + p_prev = model.time_optimize.prev(p) + new_cap_prev = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev) + if p == model.time_optimize.at(2): + p_prev2 = model.time_exist.last() + new_cap_prev2 = sum( + value(model.existing_capacity[_r, _t, _v]) + for _r, _t, _v in model.existing_capacity.sparse_keys() + if _r in regions and _t in techs and _v == p_prev2 + ) + else: + p_prev2 = model.time_optimize.prev(p_prev) + new_cap_prev2 = sum(new_cap_rtv[_r, _t, _v] for _r, _t, _v in cap_rtv if _v == p_prev2) + + nc_delta_prev = new_cap_prev - new_cap_prev2 + nc_delta = new_cap - new_cap_prev + + if degrowth: + expr = operator_expression(nc_delta_prev, Operator(op), seed + nc_delta * rate) + else: + expr = operator_expression(nc_delta, Operator(op), seed + nc_delta_prev * rate) + + if isinstance(expr, bool): + return Constraint.Skip + return expr diff --git a/temoa/extensions/growth_rates/core/__init__.py b/temoa/extensions/growth_rates/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/growth_rates/core/model.py b/temoa/extensions/growth_rates/core/model.py new file mode 100644 index 000000000..30d846d9f --- /dev/null +++ b/temoa/extensions/growth_rates/core/model.py @@ -0,0 +1,115 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from pyomo.environ import Any, Constraint, Param, Set + +from temoa.extensions.growth_rates.components import ( + growth_capacity, + growth_new_capacity, + growth_new_capacity_delta, +) + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + + class GrowthRatesModel(TemoaModel): + """TemoaModel extended with growth-rates components. + + This subtype exists only for static type checking. At runtime the + growth-rates components are attached to the core ``TemoaModel`` + instance by :func:`register_model_components`. + """ + + # Params + limit_growth_capacity: Param + limit_degrowth_capacity: Param + limit_growth_new_capacity: Param + limit_degrowth_new_capacity: Param + limit_growth_new_capacity_delta: Param + limit_degrowth_new_capacity_delta: Param + + # Constraint index sets + limit_growth_capacity_constraint_rpt: Set + limit_degrowth_capacity_constraint_rpt: Set + limit_growth_new_capacity_constraint_rpt: Set + limit_degrowth_new_capacity_constraint_rpt: Set + limit_growth_new_capacity_delta_constraint_rpt: Set + limit_degrowth_new_capacity_delta_constraint_rpt: Set + + # Constraints + limit_growth_capacity_constraint: Constraint + limit_degrowth_capacity_constraint: Constraint + limit_growth_new_capacity_constraint: Constraint + limit_degrowth_new_capacity_constraint: Constraint + limit_growth_new_capacity_delta_constraint: Constraint + limit_degrowth_new_capacity_delta_constraint: Constraint + + +def register_model_components(model: TemoaModel) -> None: + """Register growth rates model components on the core Temoa model.""" + m = cast('GrowthRatesModel', model) + + m.limit_growth_capacity = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + m.limit_degrowth_capacity = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + m.limit_growth_new_capacity = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + m.limit_degrowth_new_capacity = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + m.limit_growth_new_capacity_delta = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + m.limit_degrowth_new_capacity_delta = Param( + m.regional_global_indices, m.tech_or_group, m.operator, within=Any + ) + + m.limit_growth_capacity_constraint_rpt = Set( + dimen=4, initialize=growth_capacity.limit_growth_capacity_indices + ) + m.limit_growth_capacity_constraint = Constraint( + m.limit_growth_capacity_constraint_rpt, + rule=growth_capacity.limit_growth_capacity_constraint_rule, + ) + m.limit_degrowth_capacity_constraint_rpt = Set( + dimen=4, initialize=growth_capacity.limit_degrowth_capacity_indices + ) + m.limit_degrowth_capacity_constraint = Constraint( + m.limit_degrowth_capacity_constraint_rpt, + rule=growth_capacity.limit_degrowth_capacity_constraint_rule, + ) + + m.limit_growth_new_capacity_constraint_rpt = Set( + dimen=4, initialize=growth_new_capacity.limit_growth_new_capacity_indices + ) + m.limit_growth_new_capacity_constraint = Constraint( + m.limit_growth_new_capacity_constraint_rpt, + rule=growth_new_capacity.limit_growth_new_capacity_constraint_rule, + ) + m.limit_degrowth_new_capacity_constraint_rpt = Set( + dimen=4, initialize=growth_new_capacity.limit_degrowth_new_capacity_indices + ) + m.limit_degrowth_new_capacity_constraint = Constraint( + m.limit_degrowth_new_capacity_constraint_rpt, + rule=growth_new_capacity.limit_degrowth_new_capacity_constraint_rule, + ) + + m.limit_growth_new_capacity_delta_constraint_rpt = Set( + dimen=4, initialize=growth_new_capacity_delta.limit_growth_new_capacity_delta_indices + ) + m.limit_growth_new_capacity_delta_constraint = Constraint( + m.limit_growth_new_capacity_delta_constraint_rpt, + rule=growth_new_capacity_delta.limit_growth_new_capacity_delta_constraint_rule, + ) + m.limit_degrowth_new_capacity_delta_constraint_rpt = Set( + dimen=4, initialize=growth_new_capacity_delta.limit_degrowth_new_capacity_delta_indices + ) + m.limit_degrowth_new_capacity_delta_constraint = Constraint( + m.limit_degrowth_new_capacity_delta_constraint_rpt, + rule=growth_new_capacity_delta.limit_degrowth_new_capacity_delta_constraint_rule, + ) diff --git a/temoa/extensions/growth_rates/data_manifest.py b/temoa/extensions/growth_rates/data_manifest.py new file mode 100644 index 000000000..d81b1d355 --- /dev/null +++ b/temoa/extensions/growth_rates/data_manifest.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from temoa.data_io.loader_manifest import LoadItem + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + from temoa.extensions.growth_rates.core.model import GrowthRatesModel + + +def build_manifest_items(model: TemoaModel) -> list[LoadItem]: + """Return LoadItems for growth/degrowth constraints.""" + m = cast('GrowthRatesModel', model) + return [ + LoadItem( + component=m.limit_growth_capacity, + table='limit_growth_capacity', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + LoadItem( + component=m.limit_growth_new_capacity, + table='limit_growth_new_capacity', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + LoadItem( + component=m.limit_growth_new_capacity_delta, + table='limit_growth_new_capacity_delta', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + LoadItem( + component=m.limit_degrowth_capacity, + table='limit_degrowth_capacity', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + LoadItem( + component=m.limit_degrowth_new_capacity, + table='limit_degrowth_new_capacity', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + LoadItem( + component=m.limit_degrowth_new_capacity_delta, + table='limit_degrowth_new_capacity_delta', + columns=['region', 'tech_or_group', 'operator', 'rate', 'seed'], + index_length=3, + validator_name='viable_rt', + validation_map=(0, 1), + is_period_filtered=False, + is_table_required=False, + ), + ] diff --git a/temoa/extensions/growth_rates/extension.py b/temoa/extensions/growth_rates/extension.py new file mode 100644 index 000000000..5c148b612 --- /dev/null +++ b/temoa/extensions/growth_rates/extension.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from pathlib import Path + +from temoa.extensions.framework import ExtensionSpec +from temoa.extensions.growth_rates.core.model import register_model_components +from temoa.extensions.growth_rates.data_manifest import build_manifest_items + + +GROWTH_RATES_EXTENSION = ExtensionSpec( + extension_id='growth_rates', + owned_tables=( + 'limit_growth_capacity', + 'limit_degrowth_capacity', + 'limit_growth_new_capacity', + 'limit_degrowth_new_capacity', + 'limit_growth_new_capacity_delta', + 'limit_degrowth_new_capacity_delta', + ), + regional_group_tables={ + 'limit_growth_capacity': 'region', + 'limit_degrowth_capacity': 'region', + 'limit_growth_new_capacity': 'region', + 'limit_degrowth_new_capacity': 'region', + 'limit_growth_new_capacity_delta': 'region', + 'limit_degrowth_new_capacity_delta': 'region', + }, + register_model_components=register_model_components, + build_manifest_items=build_manifest_items, + schema_sql_path=str(Path(__file__).parents[0] / 'tables.sql'), + fail_if_tables_populated_when_disabled=True, +) diff --git a/temoa/extensions/growth_rates/tables.sql b/temoa/extensions/growth_rates/tables.sql new file mode 100644 index 000000000..e2fece833 --- /dev/null +++ b/temoa/extensions/growth_rates/tables.sql @@ -0,0 +1,72 @@ +CREATE TABLE IF NOT EXISTS limit_growth_capacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE IF NOT EXISTS limit_degrowth_capacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE IF NOT EXISTS limit_growth_new_capacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE IF NOT EXISTS limit_growth_new_capacity_delta +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE IF NOT EXISTS limit_degrowth_new_capacity_delta +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); diff --git a/temoa/extensions/integer_capacity/__init__.py b/temoa/extensions/integer_capacity/__init__.py new file mode 100644 index 000000000..51f6b3186 --- /dev/null +++ b/temoa/extensions/integer_capacity/__init__.py @@ -0,0 +1,3 @@ +from temoa.extensions.integer_capacity.extension import INTEGER_CAPACITY_EXTENSION + +__all__ = ['INTEGER_CAPACITY_EXTENSION'] diff --git a/temoa/extensions/integer_capacity/components/__init__.py b/temoa/extensions/integer_capacity/components/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/integer_capacity/components/integer_capacity.py b/temoa/extensions/integer_capacity/components/integer_capacity.py new file mode 100644 index 000000000..f2d22cc8b --- /dev/null +++ b/temoa/extensions/integer_capacity/components/integer_capacity.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import logging +logger = logging.getLogger(__name__) + +from pyomo.environ import Constraint, quicksum, value + +import temoa.components.geography as geography +import temoa.components.technology as technology + +if TYPE_CHECKING: + from temoa.extensions.integer_capacity.core.model import IntegerCapacityModel + from temoa.types import ExprLike, Period, Region, Technology, Vintage + + +def limit_integer_new_capacity_indices( + model: IntegerCapacityModel, +) -> set[tuple[Region, Technology, Vintage]]: + indices = { + (r, t, v) + for r, t in model.limit_integer_new_capacity.sparse_keys() + for v in model.vintage_optimize + } + return indices + + +def limit_integer_new_capacity_constraint_rule( + model: IntegerCapacityModel, r: Region, t: Technology, v: Vintage +) -> ExprLike: + r""" + The limit_integer_new_capacity constraint requires the total new capacity + for a technology (or technology group) in a region to be discrete, equal + to some integer multiple of the specified capacity. + + .. math:: + :label: limit_integer_new_capacity + + \textbf{NCAP}_{r, t, v} = LINC_{r, t} \cdot \textbf{INCAP}_{r, v, t} + + \forall \{r, t, v\} \in \Theta_{\text{limit\_integer\_new\_capacity}} + """ + + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + unit_cap = value(model.limit_integer_new_capacity[r, t]) + + new_capacity = quicksum( + model.v_new_capacity[_r, _t, v] + for _r in regions + for _t in techs + if (_r, _t, v) in model.process_periods + ) + expr = new_capacity == unit_cap * model.v_integer_new_capacity[r, t, v] + if isinstance(expr, bool): + return Constraint.Skip + return expr + + +def limit_integer_net_capacity_indices( + model: IntegerCapacityModel, +) -> set[tuple[Region, Period, Technology]]: + indices = { + (r, p, t) + for r, t in model.limit_integer_net_capacity.sparse_keys() + for p in model.time_optimize + } + return indices + + +def limit_integer_net_capacity_constraint_rule( + model: IntegerCapacityModel, r: Region, p: Period, t: Technology +) -> ExprLike: + r""" + The limit_integer_net_capacity constraint requires the total available capacity + for a technology (or technology group) in a region to be discrete, equal + to some integer multiple of the specified capacity. + + .. math:: + :label: limit_integer_net_capacity + + \textbf{CAPAVL}_{r, p, t} = LIC_{r, t} \cdot \textbf{ICAP}_{r, p, t} + + \forall \{r, p, t\} \in \Theta_{\text{limit\_integer\_net\_capacity}} + """ + + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + capacity = value(model.limit_integer_net_capacity[r, t]) + + net_capacity = quicksum( + model.v_capacity_available_by_period_and_tech[_r, p, _t] + for _r in regions + for _t in techs + if (_r, p, _t) in model.v_capacity_available_by_period_and_tech + ) + expr = net_capacity == capacity * model.v_integer_net_capacity[r, p, t] + if isinstance(expr, bool): + return Constraint.Skip + return expr diff --git a/temoa/extensions/integer_capacity/core/__init__.py b/temoa/extensions/integer_capacity/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/integer_capacity/core/model.py b/temoa/extensions/integer_capacity/core/model.py new file mode 100644 index 000000000..b0aa6b0be --- /dev/null +++ b/temoa/extensions/integer_capacity/core/model.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from pyomo.environ import Any, Integers, Binary, Constraint, Param, Set, Var + +from temoa.extensions.integer_capacity.components import integer_capacity + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + + class IntegerCapacityModel(TemoaModel): + + limit_integer_new_capacity: Param + limit_integer_new_capacity_constraint_rtv: Set + limit_integer_new_capacity_constraint: Constraint + v_integer_new_capacity: Var + + limit_integer_net_capacity: Param + limit_integer_net_capacity_constraint_rpt: Set + limit_integer_net_capacity_constraint: Constraint + v_integer_net_capacity: Var + + +def register_model_components(model: TemoaModel) -> None: + m = cast('IntegerCapacityModel', model) + + m.limit_integer_new_capacity = Param( + m.regional_global_indices, m.tech_or_group, within=Any + ) + m.limit_integer_new_capacity_constraint_rtv = Set( + dimen=3, initialize=integer_capacity.limit_integer_new_capacity_indices + ) + m.v_integer_new_capacity = Var( + m.limit_integer_new_capacity_constraint_rtv, within=Integers, bounds=(0, None) + ) + m.limit_integer_new_capacity_constraint = Constraint( + m.limit_integer_new_capacity_constraint_rtv, + rule=integer_capacity.limit_integer_new_capacity_constraint_rule, + ) + + + m.limit_integer_net_capacity = Param( + m.regional_global_indices, m.tech_or_group, within=Any + ) + m.limit_integer_net_capacity_constraint_rpt = Set( + dimen=3, initialize=integer_capacity.limit_integer_net_capacity_indices + ) + m.v_integer_net_capacity = Var( + m.limit_integer_net_capacity_constraint_rpt, within=Integers, bounds=(0, None) + ) + m.limit_integer_net_capacity_constraint = Constraint( + m.limit_integer_net_capacity_constraint_rpt, + rule=integer_capacity.limit_integer_net_capacity_constraint_rule, + ) diff --git a/temoa/extensions/integer_capacity/data_manifest.py b/temoa/extensions/integer_capacity/data_manifest.py new file mode 100644 index 000000000..0cb8227fb --- /dev/null +++ b/temoa/extensions/integer_capacity/data_manifest.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from temoa.data_io.loader_manifest import LoadItem + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + from temoa.extensions.integer_capacity.core.model import IntegerCapacityModel + + +def build_manifest_items(model: TemoaModel) -> list[LoadItem]: + m = cast('IntegerCapacityModel', model) + return [ + LoadItem( + component=m.limit_integer_new_capacity, + table='limit_integer_new_capacity', + columns=['region', 'tech_or_group', 'capacity'], + validator_name='viable_rt', + validation_map=(0, 1), + is_table_required=False, + is_period_filtered=False, + ), + LoadItem( + component=m.limit_integer_net_capacity, + table='limit_integer_net_capacity', + columns=['region', 'tech_or_group', 'capacity'], + validator_name='viable_rt', + validation_map=(0, 1), + is_table_required=False, + is_period_filtered=False, + ), + ] diff --git a/temoa/extensions/integer_capacity/extension.py b/temoa/extensions/integer_capacity/extension.py new file mode 100644 index 000000000..d17570c41 --- /dev/null +++ b/temoa/extensions/integer_capacity/extension.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from pathlib import Path + +from temoa.extensions.framework import ExtensionSpec +from temoa.extensions.integer_capacity.core.model import register_model_components +from temoa.extensions.integer_capacity.data_manifest import build_manifest_items + +INTEGER_CAPACITY_EXTENSION = ExtensionSpec( + extension_id='integer_capacity', + owned_tables=('limit_integer_new_capacity', 'limit_integer_net_capacity'), + regional_group_tables={ + 'limit_integer_new_capacity': 'region', + 'limit_integer_net_capacity': 'region' + }, + register_model_components=register_model_components, + build_manifest_items=build_manifest_items, + schema_sql_path=str(Path(__file__).parents[0] / 'tables.sql'), + fail_if_tables_populated_when_disabled=True, +) diff --git a/temoa/extensions/integer_capacity/tables.sql b/temoa/extensions/integer_capacity/tables.sql new file mode 100644 index 000000000..503f598c0 --- /dev/null +++ b/temoa/extensions/integer_capacity/tables.sql @@ -0,0 +1,16 @@ +CREATE TABLE IF NOT EXISTS limit_integer_new_capacity( + region TEXT, + tech_or_group TEXT, + capacity REAL NOT NULL DEFAULT 0, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group) +); +CREATE TABLE IF NOT EXISTS limit_integer_net_capacity( + region TEXT, + tech_or_group TEXT, + capacity REAL NOT NULL DEFAULT 0, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group) +); diff --git a/temoa/extensions/method_of_morris/morris.py b/temoa/extensions/method_of_morris/morris.py index 77d770f1c..4bb14ddcb 100644 --- a/temoa/extensions/method_of_morris/morris.py +++ b/temoa/extensions/method_of_morris/morris.py @@ -38,7 +38,7 @@ def evaluate(param_names: dict[int, list[Any]], param_values: Any, raise ValueError(f'Unrecognized parameter: {names[0]}') dp = DataPortal(data_dict={None: data}) - instance = run_actions.build_instance(loaded_portal=dp) + instance = run_actions.build_instance(loaded_portal=dp, extensions=config.extensions) mdl, res = run_actions.solve_instance(instance=instance, solver_name=config.solver_name) status = run_actions.check_solve_status(res) if not status: diff --git a/temoa/extensions/method_of_morris/morris_evaluate.py b/temoa/extensions/method_of_morris/morris_evaluate.py index 21b03febf..1460b7757 100644 --- a/temoa/extensions/method_of_morris/morris_evaluate.py +++ b/temoa/extensions/method_of_morris/morris_evaluate.py @@ -67,7 +67,11 @@ def evaluate(param_info: dict[int, list[Any]], mm_sample: Any, data: dict[str, A logger.debug('\n '.join(log_entry)) dp = DataPortal(data_dict={None: data}) - instance = run_actions.build_instance(loaded_portal=dp, silent=True) + instance = run_actions.build_instance( + loaded_portal=dp, + silent=True, + extensions=config.extensions, + ) mdl, res = run_actions.solve_instance( instance=instance, solver_name=config.solver_name, silent=True ) diff --git a/temoa/extensions/modeling_to_generate_alternatives/mga_sequencer.py b/temoa/extensions/modeling_to_generate_alternatives/mga_sequencer.py index 83b228fec..080d06974 100644 --- a/temoa/extensions/modeling_to_generate_alternatives/mga_sequencer.py +++ b/temoa/extensions/modeling_to_generate_alternatives/mga_sequencer.py @@ -164,7 +164,10 @@ def start(self) -> None: hybrid_loader = HybridLoader(db_connection=self.con, config=self.config) data_portal: DataPortal = hybrid_loader.load_data_portal(myopic_index=None) instance: TemoaModel = build_instance( - loaded_portal=data_portal, model_name=self.config.scenario, silent=self.config.silent + loaded_portal=data_portal, + model_name=self.config.scenario, + silent=self.config.silent, + extensions=self.config.extensions, ) if self.config.price_check: good_prices = price_checker(instance) diff --git a/temoa/extensions/myopic/myopic_sequencer.py b/temoa/extensions/myopic/myopic_sequencer.py index fbee15c45..e671c3759 100644 --- a/temoa/extensions/myopic/myopic_sequencer.py +++ b/temoa/extensions/myopic/myopic_sequencer.py @@ -252,6 +252,7 @@ def start(self) -> None: keep_lp_file=self.config.save_lp_file, lp_path=self.config.output_path / ''.join(('LP', str(idx.base_year))), # base year folder + extensions=self.config.extensions, ) # 8. Run checks... diff --git a/temoa/extensions/single_vector_mga/sv_mga_sequencer.py b/temoa/extensions/single_vector_mga/sv_mga_sequencer.py index 8498390bf..937aeb65c 100644 --- a/temoa/extensions/single_vector_mga/sv_mga_sequencer.py +++ b/temoa/extensions/single_vector_mga/sv_mga_sequencer.py @@ -79,6 +79,7 @@ def start(self) -> None: silent=self.config.silent, keep_lp_file=self.config.save_lp_file, lp_path=lp_path, + extensions=self.config.extensions, ) if self.config.price_check: good_prices = price_checker(instance) diff --git a/temoa/extensions/stochastics/scenario_creator.py b/temoa/extensions/stochastics/scenario_creator.py index 757fa2a70..3dc0b6591 100644 --- a/temoa/extensions/stochastics/scenario_creator.py +++ b/temoa/extensions/stochastics/scenario_creator.py @@ -96,7 +96,7 @@ def scenario_creator(scenario_name: str, **kwargs: Any) -> Any: # 3. Build instance data_portal = HybridLoader.data_portal_from_data(data_dict) - instance = build_instance(data_portal, silent=True) + instance = build_instance(data_portal, silent=True, extensions=temoa_config.extensions) # 4. Attach root node (Stage 1) periods = sorted(instance.time_optimize) diff --git a/temoa/extensions/template/__init__.py b/temoa/extensions/template/__init__.py new file mode 100644 index 000000000..fb2119770 --- /dev/null +++ b/temoa/extensions/template/__init__.py @@ -0,0 +1,21 @@ +"""Template extension package. + +TEMPLATE: This is a copy-from scaffold for building a new optional Temoa +modeling extension. It is intentionally NOT registered in +``temoa.extensions.framework.get_known_extension_specs``, so it is inert: +importing it works and it type-checks, but it cannot be enabled until you +register it. + +To create a real extension: + 1. Copy this whole folder to ``temoa/extensions//``. + 2. Rename the ``extension_id``, tables, params, and constraints. + 3. Register the spec in ``get_known_extension_specs`` (see framework.py). + 4. Add your tables to the database schema / ``tables.sql``. + 5. Enable it via config: ``extensions = [""]``. + +See ``docs/source/extensions.rst`` for the full guide. +""" + +from temoa.extensions.template.extension import EXAMPLE_EXTENSION + +__all__ = ['EXAMPLE_EXTENSION'] diff --git a/temoa/extensions/template/components/__init__.py b/temoa/extensions/template/components/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/template/components/example_limit.py b/temoa/extensions/template/components/example_limit.py new file mode 100644 index 000000000..a00570bce --- /dev/null +++ b/temoa/extensions/template/components/example_limit.py @@ -0,0 +1,62 @@ +"""Example constraint family for the template extension. + +TEMPLATE: A component module holds the index-set function(s) and constraint +rule(s) for a single family of constraints, mirroring the modules under +``temoa/components``. Group related constraints together; create one module per +family. + +This example caps the new capacity built in each period for a technology (or +technology group) in a region. Replace it with your own logic. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from pyomo.environ import Constraint, quicksum, value + +import temoa.components.geography as geography +import temoa.components.technology as technology + +if TYPE_CHECKING: + from temoa.extensions.template.core.model import ExampleModel + from temoa.types import ExprLike, Period, Region, Technology + + +def example_new_capacity_limit_indices( + model: ExampleModel, +) -> set[tuple[Region, Period, Technology]]: + """Build the sparse (region, period, tech-or-group) index for the constraint. + + TEMPLATE: Annotate ``model`` with the extension subtype (``ExampleModel``) so + the extension-owned param ``example_new_capacity_limit`` and its + ``sparse_keys()`` method are visible to the type checker. + """ + return { + (r, p, t) + for r, t in model.example_new_capacity_limit.sparse_keys() + for p in model.time_optimize + } + + +def example_new_capacity_limit_constraint_rule( + model: ExampleModel, r: Region, p: Period, t: Technology +) -> ExprLike: + """Cap total new capacity built in period ``p`` for region/group ``r``/``t``.""" + regions = geography.gather_group_regions(model, r) + techs = technology.gather_group_techs(model, t) + + limit = value(model.example_new_capacity_limit[r, t]) + + new_cap_rtv = model.v_new_capacity + new_cap = quicksum( + new_cap_rtv[_r, _t, _v] + for _r, _t, _v in new_cap_rtv.keys() + if _r in regions and _t in techs and _v == p + ) + + if isinstance(new_cap, (int, float)): + # No decision variables in this period/region/group: nothing to constrain. + return Constraint.Skip + + return new_cap <= limit diff --git a/temoa/extensions/template/core/__init__.py b/temoa/extensions/template/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/temoa/extensions/template/core/model.py b/temoa/extensions/template/core/model.py new file mode 100644 index 000000000..e66a92916 --- /dev/null +++ b/temoa/extensions/template/core/model.py @@ -0,0 +1,71 @@ +"""Type-checking model subtype and component registration for the template extension. + +TEMPLATE: This file plays the same role as ``temoa/core/model.py`` does for the +core model: it declares the extension-owned model components (so the type +checker knows about them) and attaches them to a live ``TemoaModel`` instance. + +Two things live here: + 1. ``ExampleModel`` - a ``TYPE_CHECKING``-only subtype of ``TemoaModel`` that + declares every Param/Set/Constraint this extension adds. It exists purely + for static typing; nothing instantiates it. + 2. ``register_model_components`` - the runtime hook that attaches those + components to the core model. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from pyomo.environ import Any, Constraint, Param, Set + +from temoa.extensions.template.components import example_limit + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + + class ExampleModel(TemoaModel): + """TemoaModel extended with template-extension components. + + TEMPLATE: Declare one annotation per component you create in + ``register_model_components`` below. Inheriting from ``TemoaModel`` means + all core sets/params/vars (e.g. ``time_optimize``, ``v_new_capacity``) + are already visible to the type checker here and in your component + modules. + """ + + # Params (loaded from the database via data_manifest.py) + example_new_capacity_limit: Param + + # Constraint index sets + example_new_capacity_limit_constraint_rpt: Set + + # Constraints + example_new_capacity_limit_constraint: Constraint + + +def register_model_components(model: TemoaModel) -> None: + """Attach template-extension components to the core Temoa model. + + TEMPLATE: Keep the public signature as ``model: TemoaModel`` so this stays + assignable to ``ExtensionSpec.register_model_components`` (a + ``Callable[[TemoaModel], None]``). Narrowing the parameter to ``ExampleModel`` + would be a contravariance error in mypy. Instead, ``cast`` once and operate on + the typed alias ``m`` below. + """ + m = cast('ExampleModel', model) + + # Param: a per-(region, tech-or-group) cap on cumulative new capacity. + m.example_new_capacity_limit = Param( + m.regional_global_indices, m.tech_or_group, within=Any + ) + + # Sparse index set for the constraint, built from the param's populated keys. + m.example_new_capacity_limit_constraint_rpt = Set( + dimen=3, initialize=example_limit.example_new_capacity_limit_indices + ) + + # The constraint itself. + m.example_new_capacity_limit_constraint = Constraint( + m.example_new_capacity_limit_constraint_rpt, + rule=example_limit.example_new_capacity_limit_constraint_rule, + ) diff --git a/temoa/extensions/template/data_manifest.py b/temoa/extensions/template/data_manifest.py new file mode 100644 index 000000000..e9c8ac02a --- /dev/null +++ b/temoa/extensions/template/data_manifest.py @@ -0,0 +1,44 @@ +"""Data-loading manifest for the template extension. + +TEMPLATE: ``build_manifest_items`` returns one ``LoadItem`` per database table +this extension reads. The loader uses each item to query, validate, and populate +the matching Pyomo component declared in core/model.py. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from temoa.data_io.loader_manifest import LoadItem + +if TYPE_CHECKING: + from temoa.core.model import TemoaModel + from temoa.extensions.template.core.model import ExampleModel + + +def build_manifest_items(model: TemoaModel) -> list[LoadItem]: + """Return the LoadItems for the template extension. + + TEMPLATE: As with ``register_model_components``, keep the public parameter + typed as ``TemoaModel`` (to match ``ExtensionSpec.build_manifest_items``) and + ``cast`` to the extension subtype so the extension-owned components type-check. + """ + m = cast('ExampleModel', model) + return [ + LoadItem( + # The Pyomo component to populate. + component=m.example_new_capacity_limit, + # Source table name. + table='example_new_capacity_limit', + # Columns to select; for a Param the final column is the value. + columns=['region', 'tech_or_group', 'value'], + # Number of leading columns that form the index (here: region, tech). + index_length=2, + # Source-trace validator on the loader (filters to viable r/t pairs). + validator_name='viable_rt', + # Which index columns to validate (region=0, tech=1). + validation_map=(0, 1), + # Extension tables are optional inputs, so do not require the table. + is_table_required=False, + ), + ] diff --git a/temoa/extensions/template/extension.py b/temoa/extensions/template/extension.py new file mode 100644 index 000000000..9c8509d85 --- /dev/null +++ b/temoa/extensions/template/extension.py @@ -0,0 +1,34 @@ +"""Declarative spec that wires the template extension into Temoa. + +TEMPLATE: ``ExtensionSpec`` is pure metadata plus hook functions. Temoa reads it +to know which tables the extension owns, how to guard them, which model +components to attach, and how to load the extension's data. +""" + +from __future__ import annotations + +from pathlib import Path + +from temoa.extensions.framework import ExtensionSpec +from temoa.extensions.template.core.model import register_model_components +from temoa.extensions.template.data_manifest import build_manifest_items + +EXAMPLE_EXTENSION = ExtensionSpec( + # Unique, lowercase id. This is what users put in ``extensions = [...]``. + extension_id='template', + # Database tables owned exclusively by this extension. + owned_tables=('example_new_capacity_limit',), + # Tables whose ``region`` column may contain a regional group name. Maps + # table -> the column that holds the region/group. Merged into the loader's + # regional-group handling. + regional_group_tables={'example_new_capacity_limit': 'region'}, + # Hook: attach model components to the core model (see core/model.py). + register_model_components=register_model_components, + # Hook: describe how to load this extension's data (see data_manifest.py). + build_manifest_items=build_manifest_items, + # Schema applied (with consent) when enabled but tables are missing. + schema_sql_path=str(Path(__file__).parents[0] / 'tables.sql'), + # If True, loading fails when this extension is DISABLED but its tables hold + # data, preventing silently-ignored inputs. + fail_if_tables_populated_when_disabled=True, +) diff --git a/temoa/extensions/template/tables.sql b/temoa/extensions/template/tables.sql new file mode 100644 index 000000000..bc8e3a75d --- /dev/null +++ b/temoa/extensions/template/tables.sql @@ -0,0 +1,14 @@ +-- TEMPLATE: Schema for the template extension's owned tables. +-- One CREATE TABLE per entry in ``owned_tables`` (see extension.py). Use +-- ``IF NOT EXISTS`` so the schema can be appended to an existing database when +-- the extension is enabled but its tables are missing. + +CREATE TABLE IF NOT EXISTS example_new_capacity_limit +( + region TEXT, + tech_or_group TEXT, + value REAL NOT NULL DEFAULT 0, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group) +); diff --git a/temoa/tutorial_assets/config_sample.toml b/temoa/tutorial_assets/config_sample.toml index 6b522212d..df3d7b20a 100644 --- a/temoa/tutorial_assets/config_sample.toml +++ b/temoa/tutorial_assets/config_sample.toml @@ -18,6 +18,12 @@ scenario = "zulu" # [perfect_foresight, MGA, myopic, method_of_morris, build_only, check, monte_carlo] scenario_mode = "perfect_foresight" +# Optional extensions list +# Use this to enable modular model features that are not part of the base core model. +# Example: extensions = ["unit_commitment", "growth_rates"] +# Leave empty for default core-only behavior. +extensions = [] + # Input database (Mandatory) input_database = "utopia.sqlite" diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index a58fc9910..1814f34f9 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -1,1478 +1,449 @@ -BEGIN TRANSACTION; -CREATE TABLE capacity_credit -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER, - credit REAL, - notes TEXT, - PRIMARY KEY (region, period, tech, vintage), - CHECK (credit >= 0 AND credit <= 1) -); -CREATE TABLE capacity_factor_process -( - region TEXT, - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER, - factor REAL, - notes TEXT, - PRIMARY KEY (region, season, tod, tech, vintage), - CHECK (factor >= 0 AND factor <= 1) -); -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, - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - tech TEXT - REFERENCES technology (tech), - factor REAL, - notes TEXT, - PRIMARY KEY (region, season, tod, tech), - CHECK (factor >= 0 AND factor <= 1) -); -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, - tech TEXT - REFERENCES technology (tech), - c2a REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech) -); -INSERT INTO "capacity_to_activity" VALUES('utopia','E01',31.54,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','E21',31.54,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','E31',31.54,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','E51',31.54,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','E70',31.54,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','RHE',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','RHO',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','RL1',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','SRE',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','TXD',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','TXE',1.0,'PJ / (GW * year)',''); -INSERT INTO "capacity_to_activity" VALUES('utopia','TXG',1.0,'PJ / (GW * year)',''); -CREATE TABLE commodity -( - name TEXT - PRIMARY KEY, - flag TEXT - REFERENCES commodity_type (label), - description TEXT, - units TEXT -); -INSERT INTO "commodity" VALUES('ethos','s','# dummy commodity to supply inputs','PJ'); -INSERT INTO "commodity" VALUES('DSL','p','# diesel','PJ'); -INSERT INTO "commodity" VALUES('ELC','p','# electricity','PJ'); -INSERT INTO "commodity" VALUES('FEQ','p','# fossil equivalent','PJ'); -INSERT INTO "commodity" VALUES('GSL','p','# gasoline','PJ'); -INSERT INTO "commodity" VALUES('HCO','p','# coal','PJ'); -INSERT INTO "commodity" VALUES('HYD','p','# water','PJ'); -INSERT INTO "commodity" VALUES('OIL','p','# crude oil','PJ'); -INSERT INTO "commodity" VALUES('URN','p','# uranium','PJ'); -INSERT INTO "commodity" VALUES('co2','e','#CO2 emissions','Mt'); -INSERT INTO "commodity" VALUES('nox','e','#NOX emissions','Mt'); -INSERT INTO "commodity" VALUES('RH','d','# residential heating','PJ'); -INSERT INTO "commodity" VALUES('RL','d','# residential lighting','PJ'); -INSERT INTO "commodity" VALUES('TX','d','# transportation','PJ'); -CREATE TABLE commodity_type -( - label TEXT - PRIMARY KEY, - description TEXT -); -INSERT INTO "commodity_type" VALUES('w','waste commodity'); -INSERT INTO "commodity_type" VALUES('wa','waste annual commodity'); -INSERT INTO "commodity_type" VALUES('wp','waste physical commodity'); -INSERT INTO "commodity_type" VALUES('a','annual commodity'); -INSERT INTO "commodity_type" VALUES('s','source commodity'); -INSERT INTO "commodity_type" VALUES('p','physical commodity'); -INSERT INTO "commodity_type" VALUES('e','emissions commodity'); -INSERT INTO "commodity_type" VALUES('d','demand commodity'); -CREATE TABLE construction_input -( - region TEXT, - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - value REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, input_comm, tech, vintage) -); -CREATE TABLE cost_emission -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - emis_comm TEXT NOT NULL - REFERENCES commodity (name), - cost REAL NOT NULL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, emis_comm) -); -CREATE TABLE cost_fixed -( - region TEXT NOT NULL, - period INTEGER NOT NULL - REFERENCES time_period (period), - tech TEXT NOT NULL - REFERENCES technology (tech), - vintage INTEGER NOT NULL - REFERENCES time_period (period), - cost REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, tech, vintage) -); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E01',1960,40.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E01',1970,40.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E01',1980,40.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E01',1990,40.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E01',1970,70.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E01',1980,70.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E01',1990,70.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E01',2000,70.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E01',1980,100.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E01',1990,100.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E01',2000,100.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E01',2010,100.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E21',2000,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E21',2000,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E21',2010,500.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E31',2000,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E31',2000,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E31',2010,75.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E51',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E51',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E51',2010,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E70',1960,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E70',1970,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E70',1970,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'E70',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E70',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'E70',2010,30.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'RHO',1970,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'RHO',1980,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'RHO',1980,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'RHO',2000,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'RHO',2000,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'RHO',2010,1.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'RL1',1980,9.46,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'RL1',1990,9.46,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'RL1',2000,9.46,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'RL1',2010,9.46,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXD',1970,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXD',1980,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXD',1990,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXD',1980,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXD',1990,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXD',2000,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXD',2000,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXD',2010,52.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXE',1990,100.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXE',1990,90.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXE',2000,90.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXE',2000,80.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXE',2010,80.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXG',1970,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXG',1980,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',1990,'TXG',1990,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXG',1980,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXG',1990,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2000,'TXG',2000,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXG',2000,48.0,'Mdollar / (PJ^2 / GW / year)',''); -INSERT INTO "cost_fixed" VALUES('utopia',2010,'TXG',2010,48.0,'Mdollar / (PJ^2 / GW / year)',''); -CREATE TABLE cost_invest -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - cost REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech, vintage) -); -INSERT INTO "cost_invest" VALUES('utopia','E01',1990,2000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E01',2000,1300.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E01',2010,1200.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E21',1990,5000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E21',2000,5000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E21',2010,5000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E31',1990,3000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E31',2000,3000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E31',2010,3000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E51',1990,900.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E51',2000,900.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E51',2010,900.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E70',1990,1000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E70',2000,1000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','E70',2010,1000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHE',1990,90.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHE',2000,90.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHE',2010,90.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHO',1990,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHO',2000,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','RHO',2010,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','SRE',1990,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','SRE',2000,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','SRE',2010,100.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXD',1990,1044.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXD',2000,1044.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXD',2010,1044.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXE',1990,2000.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXE',2000,1750.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXE',2010,1500.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXG',1990,1044.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXG',2000,1044.0,'Mdollar / (PJ^2 / GW)',''); -INSERT INTO "cost_invest" VALUES('utopia','TXG',2010,1044.0,'Mdollar / (PJ^2 / GW)',''); -CREATE TABLE cost_variable -( - region TEXT NOT NULL, - period INTEGER NOT NULL - REFERENCES time_period (period), - tech TEXT NOT NULL - REFERENCES technology (tech), - vintage INTEGER NOT NULL - REFERENCES time_period (period), - cost REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, tech, vintage) -); -INSERT INTO "cost_variable" VALUES('utopia',1990,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E01',1960,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E01',1970,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E01',1980,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E01',1990,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E01',1970,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E01',1980,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E01',1990,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E01',2000,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E01',1980,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E01',1990,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E01',2000,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E01',2010,0.3,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E21',1990,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E21',1990,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E21',1990,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E21',2000,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E21',2000,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E21',2010,1.5,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E70',1960,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E70',1970,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E70',1980,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'E70',1990,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E70',1970,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E70',1980,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E70',1990,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'E70',2000,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E70',1980,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E70',1990,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E70',2000,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'E70',2010,0.4,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',1990,'SRE',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'SRE',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2000,'SRE',2000,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'SRE',1990,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'SRE',2000,10.0,'Mdollar / (PJ)',''); -INSERT INTO "cost_variable" VALUES('utopia',2010,'SRE',2010,10.0,'Mdollar / (PJ)',''); -CREATE TABLE demand -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - commodity TEXT - REFERENCES commodity (name), - demand REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, commodity) -); -INSERT INTO "demand" VALUES('utopia',1990,'RH',25.2,'PJ',''); -INSERT INTO "demand" VALUES('utopia',2000,'RH',37.8,'PJ',''); -INSERT INTO "demand" VALUES('utopia',2010,'RH',56.7,'PJ',''); -INSERT INTO "demand" VALUES('utopia',1990,'RL',5.6,'PJ',''); -INSERT INTO "demand" VALUES('utopia',2000,'RL',8.4,'PJ',''); -INSERT INTO "demand" VALUES('utopia',2010,'RL',12.6,'PJ',''); -INSERT INTO "demand" VALUES('utopia',1990,'TX',5.2,'PJ',''); -INSERT INTO "demand" VALUES('utopia',2000,'TX',7.8,'PJ',''); -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 time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - demand_name TEXT - REFERENCES commodity (name), - dsd REAL, - notes TEXT, - PRIMARY KEY (region, period, 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,''); -CREATE TABLE efficiency -( - region TEXT, - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - efficiency REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, input_comm, tech, vintage, output_comm), - CHECK (efficiency > 0) -); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPDSL1',1990,'DSL',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPGSL1',1990,'GSL',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPHCO1',1990,'HCO',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPOIL1',1990,'OIL',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPURN1',1990,'URN',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPFEQ',1990,'FEQ',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','ethos','IMPHYD',1990,'HYD',1.0,'PJ / (PJ)',''); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',1960,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',1970,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',1980,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HCO','E01',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','FEQ','E21',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','FEQ','E21',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','FEQ','E21',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','URN','E21',1990,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); -INSERT INTO "efficiency" VALUES('utopia','URN','E21',2000,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); -INSERT INTO "efficiency" VALUES('utopia','URN','E21',2010,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); -INSERT INTO "efficiency" VALUES('utopia','HYD','E31',1980,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HYD','E31',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HYD','E31',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','HYD','E31',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',1960,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',1970,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',1980,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',1990,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',2000,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','DSL','E70',2010,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); -INSERT INTO "efficiency" VALUES('utopia','ELC','E51',1980,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); -INSERT INTO "efficiency" VALUES('utopia','ELC','E51',1990,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); -INSERT INTO "efficiency" VALUES('utopia','ELC','E51',2000,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); -INSERT INTO "efficiency" VALUES('utopia','ELC','E51',2010,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RHE',1990,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RHE',2000,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RHE',2010,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','RHO',1970,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','RHO',1980,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','RHO',1990,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','RHO',2000,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','RHO',2010,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RL1',1980,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RL1',1990,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RL1',2000,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','RL1',2010,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',1990,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',2000,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',2010,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',1990,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',2000,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','OIL','SRE',2010,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); -INSERT INTO "efficiency" VALUES('utopia','DSL','TXD',1970,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','TXD',1980,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','TXD',1990,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','TXD',2000,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','DSL','TXD',2010,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','TXE',1990,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','TXE',2000,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','ELC','TXE',2010,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',1970,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',1980,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',1990,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',2000,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -INSERT INTO "efficiency" VALUES('utopia','GSL','TXG',2010,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); -CREATE TABLE efficiency_variable -( - region TEXT, - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - efficiency REAL, - notes TEXT, - PRIMARY KEY (region, season, tod, input_comm, tech, vintage, output_comm), - CHECK (efficiency > 0) -); -CREATE TABLE emission_activity -( - region TEXT, - emis_comm TEXT - REFERENCES commodity (name), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - activity REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, emis_comm, input_comm, tech, vintage, output_comm) -); -INSERT INTO "emission_activity" VALUES('utopia','co2','ethos','IMPDSL1',1990,'DSL',0.075,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','co2','ethos','IMPGSL1',1990,'GSL',0.075,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','co2','ethos','IMPHCO1',1990,'HCO',8.9e-02,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','co2','ethos','IMPOIL1',1990,'OIL',0.075,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1970,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1980,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1990,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',2000,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',2010,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1970,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1980,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1990,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',2000,'TX',1.0,'Mt / (PJ)',''); -INSERT INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',2010,'TX',1.0,'Mt / (PJ)',''); -CREATE TABLE emission_embodied -( - region TEXT, - emis_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - value REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, emis_comm, tech, vintage) -); -CREATE TABLE emission_end_of_life -( - region TEXT, - emis_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - value REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, emis_comm, tech, vintage) -); -CREATE TABLE end_of_life_output -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - value REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech, vintage, output_comm) -); -CREATE TABLE existing_capacity -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - capacity REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech, vintage) -); -INSERT INTO "existing_capacity" VALUES('utopia','E01',1960,0.175,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E01',1970,0.175,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E01',1980,0.15,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E31',1980,0.1,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E51',1980,0.5,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E70',1960,0.05,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E70',1970,0.05,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','E70',1980,0.2,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','RHO',1970,12.5,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','RHO',1980,12.5,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','RL1',1980,5.6,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','TXD',1970,0.4,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','TXD',1980,0.2,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','TXG',1970,3.1,'GW',''); -INSERT INTO "existing_capacity" VALUES('utopia','TXG',1980,1.5,'GW',''); -CREATE TABLE lifetime_process -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - lifetime REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech, vintage) -); -INSERT INTO "lifetime_process" VALUES('utopia','RL1',1980,20.0,'year','#forexistingcap'); -INSERT INTO "lifetime_process" VALUES('utopia','TXD',1970,30.0,'year','#forexistingcap'); -INSERT INTO "lifetime_process" VALUES('utopia','TXD',1980,30.0,'year','#forexistingcap'); -INSERT INTO "lifetime_process" VALUES('utopia','TXG',1970,30.0,'year','#forexistingcap'); -INSERT INTO "lifetime_process" VALUES('utopia','TXG',1980,30.0,'year','#forexistingcap'); -CREATE TABLE lifetime_survival_curve -( - region TEXT NOT NULL, - period INTEGER NOT NULL, - tech TEXT NOT NULL - REFERENCES technology (tech), - vintage INTEGER NOT NULL - REFERENCES time_period (period), - fraction REAL, - notes TEXT, - PRIMARY KEY (region, period, tech, vintage) -); -CREATE TABLE lifetime_tech -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - lifetime REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech) -); -INSERT INTO "lifetime_tech" VALUES('utopia','E01',40.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','E21',40.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','E31',100.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','E51',100.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','E70',40.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','RHE',30.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','RHO',30.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','RL1',10.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','SRE',50.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','TXD',15.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','TXE',15.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','TXG',15.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPDSL1',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPGSL1',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPHCO1',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPOIL1',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPURN1',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPHYD',1000.0,'year',''); -INSERT INTO "lifetime_tech" VALUES('utopia','IMPFEQ',1000.0,'year',''); -CREATE TABLE limit_activity -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - activity REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, tech_or_group, operator) -); -CREATE TABLE limit_activity_share -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - sub_group TEXT, - super_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - share REAL, - notes TEXT, - PRIMARY KEY (region, period, sub_group, super_group, operator) -); -CREATE TABLE limit_annual_capacity_factor -( - region TEXT, - tech_or_group TEXT, - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - factor REAL, - notes TEXT, - PRIMARY KEY (region, tech_or_group, vintage, output_comm, operator), - CHECK (factor >= 0 AND factor <= 1) -); -CREATE TABLE limit_capacity -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - capacity REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, tech_or_group, operator) -); -INSERT INTO "limit_capacity" VALUES('utopia',1990,'E31','ge',0.13,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2000,'E31','ge',0.13,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2010,'E31','ge',0.13,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',1990,'SRE','ge',0.1,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',1990,'E31','le',0.13,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2000,'E31','le',0.17,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2010,'E31','le',2.1e-01,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',1990,'RHE','le',0.0,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',1990,'TXD','le',0.6,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2000,'TXD','le',1.76,'GW',''); -INSERT INTO "limit_capacity" VALUES('utopia',2010,'TXD','le',4.76,'GW',''); -CREATE TABLE limit_capacity_share -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - sub_group TEXT, - super_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - share REAL, - notes TEXT, - PRIMARY KEY (region, period, sub_group, super_group, operator) -); -CREATE TABLE limit_degrowth_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_degrowth_new_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_degrowth_new_capacity_delta -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_emission -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - emis_comm TEXT - REFERENCES commodity (name), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - value REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, period, emis_comm, operator) -); -CREATE TABLE limit_growth_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_growth_new_capacity -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_growth_new_capacity_delta -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - rate REAL NOT NULL DEFAULT 0, - seed REAL NOT NULL DEFAULT 0, - seed_units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_new_capacity -( - region TEXT, - tech_or_group TEXT, - vintage INTEGER - REFERENCES time_period (period), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - new_cap REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, vintage, operator) -); -CREATE TABLE limit_new_capacity_share -( - region TEXT, - sub_group TEXT, - super_group TEXT, - vintage INTEGER - REFERENCES time_period (period), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - share REAL, - notes TEXT, - PRIMARY KEY (region, sub_group, super_group, vintage, operator) -); -CREATE TABLE limit_resource -( - region TEXT, - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - cum_act REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech_or_group, operator) -); -CREATE TABLE limit_seasonal_capacity_factor -( - region TEXT - REFERENCES region (region), - season TEXT - REFERENCES time_season (season), - tech_or_group TEXT, - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - factor REAL, - notes TEXT, - PRIMARY KEY(region, season, tech_or_group, operator) -); -CREATE TABLE limit_storage_level_fraction -( - region TEXT, - season TEXT, - tod TEXT - REFERENCES time_of_day (tod), - tech TEXT - REFERENCES technology (tech), - operator TEXT NOT NULL DEFAULT "le" - 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 -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - proportion REAL, - notes TEXT, - PRIMARY KEY (region, period, input_comm, tech, operator) -); -CREATE TABLE limit_tech_input_split_annual -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - proportion REAL, - notes TEXT, - PRIMARY KEY (region, period, input_comm, tech, operator) -); -CREATE TABLE limit_tech_output_split -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - tech TEXT - REFERENCES technology (tech), - output_comm TEXT - REFERENCES commodity (name), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - proportion REAL, - notes TEXT, - PRIMARY KEY (region, period, tech, output_comm, operator) -); -INSERT INTO "limit_tech_output_split" VALUES('utopia',1990,'SRE','DSL','ge',0.7,''); -INSERT INTO "limit_tech_output_split" VALUES('utopia',2000,'SRE','DSL','ge',0.7,''); -INSERT INTO "limit_tech_output_split" VALUES('utopia',2010,'SRE','DSL','ge',0.7,''); -INSERT INTO "limit_tech_output_split" VALUES('utopia',1990,'SRE','GSL','ge',0.3,''); -INSERT INTO "limit_tech_output_split" VALUES('utopia',2000,'SRE','GSL','ge',0.3,''); -INSERT INTO "limit_tech_output_split" VALUES('utopia',2010,'SRE','GSL','ge',0.3,''); -CREATE TABLE limit_tech_output_split_annual -( - region TEXT, - period INTEGER - REFERENCES time_period (period), - tech TEXT - REFERENCES technology (tech), - output_comm TEXT - REFERENCES commodity (name), - operator TEXT NOT NULL DEFAULT "le" - REFERENCES operator (operator), - proportion REAL, - notes TEXT, - PRIMARY KEY (region, period, tech, output_comm, operator) -); -CREATE TABLE linked_tech -( - primary_region TEXT, - primary_tech TEXT - REFERENCES technology (tech), - emis_comm TEXT - REFERENCES commodity (name), - driven_tech TEXT - REFERENCES technology (tech), - notes TEXT, - PRIMARY KEY (primary_region, primary_tech, emis_comm) -); -CREATE TABLE loan_lifetime_process -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - lifetime REAL, - units TEXT, - notes TEXT, - PRIMARY KEY (region, tech, vintage) -); -CREATE TABLE loan_rate -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - rate REAL, - notes TEXT, - PRIMARY KEY (region, tech, vintage) -); -CREATE TABLE metadata -( - element TEXT, - value INT, - notes TEXT, - PRIMARY KEY (element) -); -INSERT INTO "metadata" VALUES('DB_MAJOR',4,''); -INSERT INTO "metadata" VALUES('DB_MINOR',0,''); -CREATE TABLE metadata_real -( - element TEXT, - value REAL, - notes TEXT, - - PRIMARY KEY (element) -); -INSERT INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); -INSERT INTO "metadata_real" VALUES('global_discount_rate',0.05,''); -CREATE TABLE myopic_efficiency -( - base_year integer, - region text, - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - efficiency real, - lifetime integer, - PRIMARY KEY (region, input_comm, tech, vintage, output_comm) -); -CREATE TABLE operator -( - operator TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "operator" VALUES('e','equal to'); -INSERT INTO "operator" VALUES('le','less than or equal to'); -INSERT INTO "operator" VALUES('ge','greater than or equal to'); -CREATE TABLE output_built_capacity -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - capacity REAL, - units TEXT, - PRIMARY KEY (region, scenario, tech, vintage) -); -CREATE TABLE output_cost -( - scenario TEXT, - region TEXT, - sector TEXT REFERENCES sector_label (sector), - period INTEGER REFERENCES time_period (period), - tech TEXT REFERENCES technology (tech), - vintage INTEGER REFERENCES time_period (period), - d_invest REAL, - d_fixed REAL, - d_var REAL, - d_emiss REAL, - invest REAL, - fixed REAL, - var REAL, - emiss REAL, - units TEXT, - PRIMARY KEY (scenario, region, period, tech, vintage), - FOREIGN KEY (vintage) REFERENCES time_period (period), - FOREIGN KEY (tech) REFERENCES technology (tech) -); -CREATE TABLE output_curtailment -( - scenario TEXT, - region TEXT, - sector TEXT, - period INTEGER - REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - curtailment REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) -); -CREATE TABLE output_dual_variable -( - scenario TEXT, - constraint_name TEXT, - dual REAL, - PRIMARY KEY (constraint_name, scenario) -); -CREATE TABLE output_emission -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - emis_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - emission REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, emis_comm, tech, vintage) -); -CREATE TABLE output_flow_in -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - flow REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) -); -CREATE TABLE output_flow_out -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - season TEXT - REFERENCES time_season (season), - tod TEXT - REFERENCES time_of_day (tod), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - flow REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) -); -CREATE TABLE output_flow_out_summary -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - input_comm TEXT - REFERENCES commodity (name), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - output_comm TEXT - REFERENCES commodity (name), - flow REAL, - PRIMARY KEY (scenario, region, period, input_comm, tech, vintage, output_comm) -); -CREATE TABLE output_net_capacity -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - capacity REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, tech, vintage) -); -CREATE TABLE output_objective -( - scenario TEXT, - objective_name TEXT, - total_system_cost REAL -); -CREATE TABLE output_retired_capacity -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - period INTEGER - REFERENCES time_period (period), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER - REFERENCES time_period (period), - cap_eol REAL, - cap_early REAL, - units TEXT, - PRIMARY KEY (region, scenario, period, tech, vintage) -); -CREATE TABLE output_storage_level -( - scenario TEXT, - region TEXT, - sector TEXT - REFERENCES sector_label (sector), - 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), - level REAL, - units TEXT, - PRIMARY KEY (scenario, region, period, season, tod, tech, vintage) -); -CREATE TABLE planning_reserve_margin -( - region TEXT - PRIMARY KEY - REFERENCES region (region), - margin REAL, - notes TEXT -); -CREATE TABLE ramp_down_hourly -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - rate REAL, - notes TEXT, - PRIMARY KEY (region, tech) -); -CREATE TABLE ramp_up_hourly -( - region TEXT, - tech TEXT - REFERENCES technology (tech), - rate REAL, - notes TEXT, - PRIMARY KEY (region, tech) -); -CREATE TABLE region -( - region TEXT - PRIMARY KEY, - notes TEXT -); -INSERT INTO "region" VALUES('utopia',NULL); -CREATE TABLE reserve_capacity_derate -( - region TEXT, - season TEXT - REFERENCES time_season (season), - tech TEXT - REFERENCES technology (tech), - vintage INTEGER, - factor REAL, - notes TEXT, - PRIMARY KEY (region, season, tech, vintage), - CHECK (factor >= 0 AND factor <= 1) -); -CREATE TABLE rps_requirement -( - region TEXT NOT NULL - REFERENCES region (region), - period INTEGER NOT NULL - REFERENCES time_period (period), - tech_group TEXT NOT NULL - REFERENCES tech_group (group_name), - requirement REAL NOT NULL, - notes TEXT -); -CREATE TABLE sector_label -( - sector TEXT PRIMARY KEY, - notes TEXT -); -INSERT INTO "sector_label" VALUES('supply',NULL); -INSERT INTO "sector_label" VALUES('electric',NULL); -INSERT INTO "sector_label" VALUES('transport',NULL); -INSERT INTO "sector_label" VALUES('commercial',NULL); -INSERT INTO "sector_label" VALUES('residential',NULL); -INSERT INTO "sector_label" VALUES('industrial',NULL); -CREATE TABLE storage_duration -( - region TEXT, - tech TEXT, - duration REAL, - notes TEXT, - PRIMARY KEY (region, tech) -); -CREATE TABLE tech_group -( - group_name TEXT - PRIMARY KEY, - notes TEXT -); -CREATE TABLE tech_group_member -( - group_name TEXT - REFERENCES tech_group (group_name), - tech TEXT - REFERENCES technology (tech), - PRIMARY KEY (group_name, tech) -); -CREATE TABLE technology -( - tech TEXT NOT NULL PRIMARY KEY, - flag TEXT NOT NULL, - sector TEXT, - category TEXT, - sub_category TEXT, - unlim_cap INTEGER NOT NULL DEFAULT 0, - annual INTEGER NOT NULL DEFAULT 0, - reserve INTEGER NOT NULL DEFAULT 0, - curtail INTEGER NOT NULL DEFAULT 0, - retire INTEGER NOT NULL DEFAULT 0, - flex INTEGER NOT NULL DEFAULT 0, - exchange INTEGER NOT NULL DEFAULT 0, - seas_stor INTEGER NOT NULL DEFAULT 0, - description TEXT, - FOREIGN KEY (flag) REFERENCES technology_type (label) -); -INSERT INTO "technology" VALUES('IMPDSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported diesel'); -INSERT INTO "technology" VALUES('IMPGSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported gasoline'); -INSERT INTO "technology" VALUES('IMPHCO1','p','supply','coal','',1,0,0,0,0,0,0,0,' imported coal'); -INSERT INTO "technology" VALUES('IMPOIL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported crude oil'); -INSERT INTO "technology" VALUES('IMPURN1','p','supply','nuclear','',1,0,0,0,0,0,0,0,' imported uranium'); -INSERT INTO "technology" VALUES('IMPFEQ','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported fossil equivalent'); -INSERT INTO "technology" VALUES('IMPHYD','p','supply','hydro','',1,0,0,0,0,0,0,0,' imported water -- doesnt exist in Utopia'); -INSERT INTO "technology" VALUES('E01','pb','electric','coal','',0,0,0,0,0,0,0,0,' coal power plant'); -INSERT INTO "technology" VALUES('E21','pb','electric','nuclear','',0,0,0,0,0,0,0,0,' nuclear power plant'); -INSERT INTO "technology" VALUES('E31','pb','electric','hydro','',0,0,0,0,0,0,0,0,' hydro power'); -INSERT INTO "technology" VALUES('E51','ps','electric','electric','',0,0,0,0,0,0,0,0,' electric storage'); -INSERT INTO "technology" VALUES('E70','p','electric','petroleum','',0,0,0,0,0,0,0,0,' diesel power plant'); -INSERT INTO "technology" VALUES('RHE','p','residential','electric','',0,0,0,0,0,0,0,0,' electric residential heating'); -INSERT INTO "technology" VALUES('RHO','p','residential','petroleum','',0,0,0,0,0,0,0,0,' diesel residential heating'); -INSERT INTO "technology" VALUES('RL1','p','residential','electric','',0,0,0,0,0,0,0,0,' residential lighting'); -INSERT INTO "technology" VALUES('SRE','p','supply','petroleum','',0,0,0,0,0,0,0,0,' crude oil processor'); -INSERT INTO "technology" VALUES('TXD','p','transport','petroleum','',0,0,0,0,0,0,0,0,' diesel powered vehicles'); -INSERT INTO "technology" VALUES('TXE','p','transport','electric','',0,0,0,0,0,0,0,0,' electric powered vehicles'); -INSERT INTO "technology" VALUES('TXG','p','transport','petroleum','',0,0,0,0,0,0,0,0,' gasoline powered vehicles'); -CREATE TABLE technology_type -( - label TEXT - PRIMARY KEY, - description TEXT -); -INSERT INTO "technology_type" VALUES('p','production technology'); -INSERT INTO "technology_type" VALUES('pb','baseload production technology'); -INSERT INTO "technology_type" VALUES('ps','storage production technology'); -CREATE TABLE time_of_day -( - sequence INTEGER UNIQUE, - tod TEXT - PRIMARY KEY, - hours REAL NOT NULL DEFAULT 1, - 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); -CREATE TABLE time_period -( - sequence INTEGER UNIQUE, - period INTEGER - PRIMARY KEY, - flag TEXT - REFERENCES time_period_type (label) -); -INSERT INTO "time_period" VALUES(1,1960,'e'); -INSERT INTO "time_period" VALUES(2,1970,'e'); -INSERT INTO "time_period" VALUES(3,1980,'e'); -INSERT INTO "time_period" VALUES(4,1990,'f'); -INSERT INTO "time_period" VALUES(5,2000,'f'); -INSERT INTO "time_period" VALUES(6,2010,'f'); -INSERT INTO "time_period" VALUES(7,2020,'f'); -CREATE TABLE time_period_type -( - label TEXT - PRIMARY KEY, - description TEXT -); -INSERT INTO "time_period_type" VALUES('e','existing vintages'); -INSERT INTO "time_period_type" VALUES('f','future'); -CREATE TABLE time_season -( - sequence INTEGER UNIQUE, - season TEXT, - segment_fraction REAL NOT NULL, - notes TEXT, - 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); -INSERT INTO "time_season" VALUES(2,'winter',0.5,NULL); -CREATE TABLE time_season_sequential -( - sequence INTEGER UNIQUE, - seas_seq TEXT, - season TEXT REFERENCES time_season(season), - segment_fraction REAL NOT NULL, - notes TEXT, - PRIMARY KEY (seas_seq), - CHECK (segment_fraction >= 0 AND segment_fraction <= 1) -); -CREATE INDEX region_tech_vintage ON myopic_efficiency (region, tech, vintage); +BEGIN TRANSACTION; +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)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','E51',31.54,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','E70',31.54,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','RHE',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','RHO',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','RL1',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','SRE',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','TXD',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','TXE',1.0,'PJ / (GW * year)',''); +REPLACE INTO "capacity_to_activity" VALUES('utopia','TXG',1.0,'PJ / (GW * year)',''); +REPLACE INTO "commodity" VALUES('ethos','s','# dummy commodity to supply inputs','PJ'); +REPLACE INTO "commodity" VALUES('DSL','p','# diesel','PJ'); +REPLACE INTO "commodity" VALUES('ELC','p','# electricity','PJ'); +REPLACE INTO "commodity" VALUES('FEQ','p','# fossil equivalent','PJ'); +REPLACE INTO "commodity" VALUES('GSL','p','# gasoline','PJ'); +REPLACE INTO "commodity" VALUES('HCO','p','# coal','PJ'); +REPLACE INTO "commodity" VALUES('HYD','p','# water','PJ'); +REPLACE INTO "commodity" VALUES('OIL','p','# crude oil','PJ'); +REPLACE INTO "commodity" VALUES('URN','p','# uranium','PJ'); +REPLACE INTO "commodity" VALUES('co2','e','#CO2 emissions','Mt'); +REPLACE INTO "commodity" VALUES('nox','e','#NOX emissions','Mt'); +REPLACE INTO "commodity" VALUES('RH','d','# residential heating','PJ'); +REPLACE INTO "commodity" VALUES('RL','d','# residential lighting','PJ'); +REPLACE INTO "commodity" VALUES('TX','d','# transportation','PJ'); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E01',1960,40.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E01',1970,40.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E01',1980,40.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E01',1990,40.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E01',1970,70.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E01',1980,70.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E01',1990,70.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E01',2000,70.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E01',1980,100.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E01',1990,100.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E01',2000,100.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E01',2010,100.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E21',1990,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E21',2000,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E21',2000,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E21',2010,500.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E31',2000,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E31',1980,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E31',1990,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E31',2000,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E31',2010,75.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E51',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E51',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E51',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E51',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E51',2010,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E70',1960,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E70',1970,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E70',1970,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'E70',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E70',1980,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E70',1990,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E70',2000,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'E70',2010,30.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'RHO',1970,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'RHO',1980,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'RHO',1980,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'RHO',2000,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'RHO',1990,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'RHO',2000,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'RHO',2010,1.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'RL1',1980,9.46,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'RL1',1990,9.46,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'RL1',2000,9.46,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'RL1',2010,9.46,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXD',1970,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXD',1980,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXD',1990,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXD',1980,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXD',1990,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXD',2000,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXD',2000,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXD',2010,52.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXE',1990,100.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXE',1990,90.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXE',2000,90.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXE',2000,80.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXE',2010,80.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXG',1970,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXG',1980,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',1990,'TXG',1990,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXG',1980,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXG',1990,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2000,'TXG',2000,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXG',2000,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_fixed" VALUES('utopia',2010,'TXG',2010,48.0,'Mdollar / (PJ^2 / GW / year)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E01',1990,2000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E01',2000,1300.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E01',2010,1200.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E21',1990,5000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E21',2000,5000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E21',2010,5000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E31',1990,3000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E31',2000,3000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E31',2010,3000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E51',1990,900.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E51',2000,900.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E51',2010,900.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E70',1990,1000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E70',2000,1000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','E70',2010,1000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHE',1990,90.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHE',2000,90.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHE',2010,90.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHO',1990,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHO',2000,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','RHO',2010,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','SRE',1990,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','SRE',2000,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','SRE',2010,100.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXD',1990,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXD',2000,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXD',2010,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXE',1990,2000.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXE',2000,1750.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXE',2010,1500.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXG',1990,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXG',2000,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_invest" VALUES('utopia','TXG',2010,1044.0,'Mdollar / (PJ^2 / GW)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'IMPDSL1',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'IMPGSL1',1990,15.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'IMPHCO1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'IMPOIL1',1990,8.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'IMPURN1',1990,2.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E01',1960,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E01',1970,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E01',1980,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E01',1990,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E01',1970,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E01',1980,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E01',1990,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E01',2000,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E01',1980,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E01',1990,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E01',2000,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E01',2010,0.3,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E21',1990,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E21',1990,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E21',1990,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E21',2000,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E21',2000,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E21',2010,1.5,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E70',1960,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E70',1970,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E70',1980,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'E70',1990,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E70',1970,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E70',1980,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E70',1990,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'E70',2000,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E70',1980,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E70',1990,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E70',2000,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'E70',2010,0.4,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',1990,'SRE',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'SRE',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2000,'SRE',2000,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'SRE',1990,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'SRE',2000,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "cost_variable" VALUES('utopia',2010,'SRE',2010,10.0,'Mdollar / (PJ)',''); +REPLACE INTO "demand" VALUES('utopia',1990,'RH',25.2,'PJ',''); +REPLACE INTO "demand" VALUES('utopia',2000,'RH',37.8,'PJ',''); +REPLACE INTO "demand" VALUES('utopia',2010,'RH',56.7,'PJ',''); +REPLACE INTO "demand" VALUES('utopia',1990,'RL',5.6,'PJ',''); +REPLACE INTO "demand" VALUES('utopia',2000,'RL',8.4,'PJ',''); +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 "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)',''); +REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPOIL1',1990,'OIL',1.0,'PJ / (PJ)',''); +REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPURN1',1990,'URN',1.0,'PJ / (PJ)',''); +REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPFEQ',1990,'FEQ',1.0,'PJ / (PJ)',''); +REPLACE INTO "efficiency" VALUES('utopia','ethos','IMPHYD',1990,'HYD',1.0,'PJ / (PJ)',''); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',1960,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',1970,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',1980,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HCO','E01',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','FEQ','E21',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','FEQ','E21',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','FEQ','E21',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','URN','E21',1990,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); +REPLACE INTO "efficiency" VALUES('utopia','URN','E21',2000,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); +REPLACE INTO "efficiency" VALUES('utopia','URN','E21',2010,'ELC',0.4,'PJ / (PJ)','# 1/2.5'); +REPLACE INTO "efficiency" VALUES('utopia','HYD','E31',1980,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HYD','E31',1990,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HYD','E31',2000,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','HYD','E31',2010,'ELC',0.32,'PJ / (PJ)','# 1/3.125'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',1960,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',1970,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',1980,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',1990,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',2000,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','E70',2010,'ELC',0.294,'PJ / (PJ)','# 1/3.4'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','E51',1980,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','E51',1990,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','E51',2000,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','E51',2010,'ELC',0.72,'PJ / (PJ)','# 1/1.3889'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RHE',1990,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RHE',2000,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RHE',2010,'RH',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','RHO',1970,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','RHO',1980,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','RHO',1990,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','RHO',2000,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','RHO',2010,'RH',0.7,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RL1',1980,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RL1',1990,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RL1',2000,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','RL1',2010,'RL',1.0,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',1990,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',2000,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',2010,'DSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',1990,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',2000,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','OIL','SRE',2010,'GSL',1.0,'PJ / (PJ)','# direct translation from PRC_INP2, PRC_OUT'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','TXD',1970,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','TXD',1980,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','TXD',1990,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','TXD',2000,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','DSL','TXD',2010,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','TXE',1990,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','TXE',2000,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','ELC','TXE',2010,'TX',0.827,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','GSL','TXG',1970,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','GSL','TXG',1980,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','GSL','TXG',1990,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','GSL','TXG',2000,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "efficiency" VALUES('utopia','GSL','TXG',2010,'TX',0.231,'PJ / (PJ)','# direct translation from DMD_EFF'); +REPLACE INTO "emission_activity" VALUES('utopia','co2','ethos','IMPDSL1',1990,'DSL',0.075,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','co2','ethos','IMPGSL1',1990,'GSL',0.075,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','co2','ethos','IMPHCO1',1990,'HCO',8.9e-02,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','co2','ethos','IMPOIL1',1990,'OIL',0.075,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1970,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1980,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',1990,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',2000,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','DSL','TXD',2010,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1970,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1980,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',1990,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',2000,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "emission_activity" VALUES('utopia','nox','GSL','TXG',2010,'TX',1.0,'Mt / (PJ)',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E01',1960,0.175,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E01',1970,0.175,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E01',1980,0.15,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E31',1980,0.1,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E51',1980,0.5,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E70',1960,0.05,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E70',1970,0.05,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','E70',1980,0.2,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','RHO',1970,12.5,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','RHO',1980,12.5,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','RL1',1980,5.6,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','TXD',1970,0.4,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','TXD',1980,0.2,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','TXG',1970,3.1,'GW',''); +REPLACE INTO "existing_capacity" VALUES('utopia','TXG',1980,1.5,'GW',''); +REPLACE INTO "lifetime_process" VALUES('utopia','RL1',1980,20.0,'year','#forexistingcap'); +REPLACE INTO "lifetime_process" VALUES('utopia','TXD',1970,30.0,'year','#forexistingcap'); +REPLACE INTO "lifetime_process" VALUES('utopia','TXD',1980,30.0,'year','#forexistingcap'); +REPLACE INTO "lifetime_process" VALUES('utopia','TXG',1970,30.0,'year','#forexistingcap'); +REPLACE INTO "lifetime_process" VALUES('utopia','TXG',1980,30.0,'year','#forexistingcap'); +REPLACE INTO "lifetime_tech" VALUES('utopia','E01',40.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','E21',40.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','E31',100.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','E51',100.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','E70',40.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','RHE',30.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','RHO',30.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','RL1',10.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','SRE',50.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','TXD',15.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','TXE',15.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','TXG',15.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPDSL1',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPGSL1',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPHCO1',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPOIL1',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPURN1',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPHYD',1000.0,'year',''); +REPLACE INTO "lifetime_tech" VALUES('utopia','IMPFEQ',1000.0,'year',''); +REPLACE INTO "limit_capacity" VALUES('utopia',1990,'E31','ge',0.13,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2000,'E31','ge',0.13,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2010,'E31','ge',0.13,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',1990,'SRE','ge',0.1,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',1990,'E31','le',0.13,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2000,'E31','le',0.17,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2010,'E31','le',2.1e-01,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',1990,'RHE','le',0.0,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',1990,'TXD','le',0.6,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2000,'TXD','le',1.76,'GW',''); +REPLACE INTO "limit_capacity" VALUES('utopia',2010,'TXD','le',4.76,'GW',''); +REPLACE INTO "limit_tech_output_split" VALUES('utopia',1990,'SRE','DSL','ge',0.7,''); +REPLACE INTO "limit_tech_output_split" VALUES('utopia',2000,'SRE','DSL','ge',0.7,''); +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_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); +REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,''); +REPLACE INTO "region" VALUES('utopia',NULL); +REPLACE INTO "sector_label" VALUES('supply',NULL); +REPLACE INTO "sector_label" VALUES('electric',NULL); +REPLACE INTO "sector_label" VALUES('transport',NULL); +REPLACE INTO "sector_label" VALUES('commercial',NULL); +REPLACE INTO "sector_label" VALUES('residential',NULL); +REPLACE INTO "sector_label" VALUES('industrial',NULL); +REPLACE INTO "technology" VALUES('IMPDSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported diesel'); +REPLACE INTO "technology" VALUES('IMPGSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported gasoline'); +REPLACE INTO "technology" VALUES('IMPHCO1','p','supply','coal','',1,0,0,0,0,0,0,0,' imported coal'); +REPLACE INTO "technology" VALUES('IMPOIL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported crude oil'); +REPLACE INTO "technology" VALUES('IMPURN1','p','supply','nuclear','',1,0,0,0,0,0,0,0,' imported uranium'); +REPLACE INTO "technology" VALUES('IMPFEQ','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported fossil equivalent'); +REPLACE INTO "technology" VALUES('IMPHYD','p','supply','hydro','',1,0,0,0,0,0,0,0,' imported water -- doesnt exist in Utopia'); +REPLACE INTO "technology" VALUES('E01','pb','electric','coal','',0,0,0,0,0,0,0,0,' coal power plant'); +REPLACE INTO "technology" VALUES('E21','pb','electric','nuclear','',0,0,0,0,0,0,0,0,' nuclear power plant'); +REPLACE INTO "technology" VALUES('E31','pb','electric','hydro','',0,0,0,0,0,0,0,0,' hydro power'); +REPLACE INTO "technology" VALUES('E51','ps','electric','electric','',0,0,0,0,0,0,0,0,' electric storage'); +REPLACE INTO "technology" VALUES('E70','p','electric','petroleum','',0,0,0,0,0,0,0,0,' diesel power plant'); +REPLACE INTO "technology" VALUES('RHE','p','residential','electric','',0,0,0,0,0,0,0,0,' electric residential heating'); +REPLACE INTO "technology" VALUES('RHO','p','residential','petroleum','',0,0,0,0,0,0,0,0,' diesel residential heating'); +REPLACE INTO "technology" VALUES('RL1','p','residential','electric','',0,0,0,0,0,0,0,0,' residential lighting'); +REPLACE INTO "technology" VALUES('SRE','p','supply','petroleum','',0,0,0,0,0,0,0,0,' crude oil processor'); +REPLACE INTO "technology" VALUES('TXD','p','transport','petroleum','',0,0,0,0,0,0,0,0,' diesel powered vehicles'); +REPLACE INTO "technology" VALUES('TXE','p','transport','electric','',0,0,0,0,0,0,0,0,' electric powered vehicles'); +REPLACE INTO "technology" VALUES('TXG','p','transport','petroleum','',0,0,0,0,0,0,0,0,' gasoline powered vehicles'); +REPLACE INTO "time_of_day" (sequence, tod, hours) VALUES(1,'day',16); +REPLACE 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'); +REPLACE INTO "time_period" VALUES(4,1990,'f'); +REPLACE INTO "time_period" VALUES(5,2000,'f'); +REPLACE INTO "time_period" VALUES(6,2010,'f'); +REPLACE INTO "time_period" VALUES(7,2020,'f'); +REPLACE INTO "time_season" VALUES(0,'inter',0.25,NULL); +REPLACE INTO "time_season" VALUES(1,'summer',0.25,NULL); +REPLACE INTO "time_season" VALUES(2,'winter',0.5,NULL); COMMIT; diff --git a/tests/conftest.py b/tests/conftest.py index 3f813d5b8..5714aa84e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,6 +10,7 @@ from temoa._internal.temoa_sequencer import TemoaSequencer from temoa.core.config import TemoaConfig from temoa.core.model import TemoaModel +from temoa.extensions.framework import get_known_extension_specs logger = logging.getLogger(__name__) @@ -57,6 +58,13 @@ def _build_test_db( # Force FK OFF again as schema file might turn it on at the end con.execute('PRAGMA foreign_keys = OFF') + # 1b. Load extension-owned tables so data scripts can populate them. + # Extension tables are not part of the central schema, so apply each + # known extension's schema (CREATE TABLE IF NOT EXISTS) here. + for spec in get_known_extension_specs().values(): + if spec.schema_sql_path: + con.executescript(Path(spec.schema_sql_path).read_text(encoding='utf-8')) + # 2. Load data scripts for script_path in data_scripts: with open(script_path) as f: @@ -88,6 +96,7 @@ def refresh_databases() -> None: ('mediumville.sql', 'mediumville.sqlite'), ('seasonal_storage.sql', 'seasonal_storage.sqlite'), ('survival_curve.sql', 'survival_curve.sqlite'), + ('myopic_capacities.sql', 'myopic_capacities.sqlite'), ('annualised_demand.sql', 'annualised_demand.sqlite'), # Feature tests (separate for temporal consistency) ('emissions.sql', 'emissions.sqlite'), @@ -207,6 +216,11 @@ def system_test_run( silent=True, ) + # Allow parametrized tests to override myopic settings per case. + myopic_overrides = request.param.get('myopic') + if myopic_overrides is not None: + config.myopic_inputs = {**(config.myopic_inputs or {}), **myopic_overrides} + sequencer = TemoaSequencer(config=config) sequencer.start() diff --git a/tests/legacy_test_values.py b/tests/legacy_test_values.py index af31669c3..3fb7d2e13 100644 --- a/tests/legacy_test_values.py +++ b/tests/legacy_test_values.py @@ -68,7 +68,8 @@ class ExpectedVals(Enum): # added 2025/06/12 prior to addition of dynamic reserve margin # reduced 2025/06/16 after fixing bug in db ExpectedVals.OBJ_VALUE: 7035.7275, - ExpectedVals.EFF_DOMAIN_SIZE: 2800, + # halved after realising mediumville had an unused existing time period + ExpectedVals.EFF_DOMAIN_SIZE: 1400, ExpectedVals.EFF_INDEX_SIZE: 18, # increased after reviving RampSeason constraints # reduced 2025/07/25 by 24 after annualising demands diff --git a/tests/test_cli.py b/tests/test_cli.py index 19144fd40..5ba1fa1ee 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -12,7 +12,7 @@ # Path to the configuration file template we will use for tests. TESTING_CONFIGS_DIR = Path(__file__).parent / 'testing_configs' -UTOPIA_SQL_FIXTURE = Path(__file__).parent.parent / 'temoa' / 'tutorial_assets' / 'utopia.sql' +UTOPIA_SQL_FIXTURE = Path(__file__).parent / 'testing_data' / 'utopia_v3.sql' UTOPIA_CONFIG_TEMPLATE = TESTING_CONFIGS_DIR / 'config_utopia.toml' diff --git a/tests/test_extensions.py b/tests/test_extensions.py new file mode 100644 index 000000000..e283dd929 --- /dev/null +++ b/tests/test_extensions.py @@ -0,0 +1,95 @@ +"""Tests for the optional model extensions and their wiring into TemoaModel.""" + +from __future__ import annotations + +from pathlib import Path + +import pytest +from pyomo.environ import Constraint + +from temoa.core.model import TemoaModel +from temoa.extensions.framework import ( + get_known_extension_specs, + resolve_extension_specs, +) + +# Parametrize over every registered extension so new extensions are covered +# automatically without listing their components here. +EXTENSION_IDS = sorted(get_known_extension_specs()) + + +def _component_map(model: TemoaModel) -> dict[str, object]: + """Map of component name -> component object declared on a model.""" + return {component.name: component for component in model.component_objects()} + + +# Cache abstract models so each extension is only built once per test session. +_abstract_models: dict[str | None, TemoaModel] = {} + + +def _model_with(extension_id: str | None) -> TemoaModel: + if extension_id not in _abstract_models: + extensions = [extension_id] if extension_id else None + _abstract_models[extension_id] = TemoaModel(extensions=extensions) + return _abstract_models[extension_id] + + +def _added_components(extension_id: str) -> dict[str, object]: + """Components present with the extension enabled but absent without it.""" + base = _component_map(_model_with(None)) + enabled = _component_map(_model_with(extension_id)) + return {name: comp for name, comp in enabled.items() if name not in base} + + +@pytest.mark.parametrize('extension_id', EXTENSION_IDS) +def test_extension_registered(extension_id: str) -> None: + """The extension is discoverable by its id and resolves to its spec.""" + spec = get_known_extension_specs()[extension_id] + assert spec.extension_id == extension_id + assert resolve_extension_specs([extension_id]) == (spec,) + + +@pytest.mark.parametrize('extension_id', EXTENSION_IDS) +def test_extension_spec_fields(extension_id: str) -> None: + """The spec declares consistent region-group columns and a registration hook.""" + spec = get_known_extension_specs()[extension_id] + # Region-group tables must refer to declared owned tables via string columns. + assert set(spec.regional_group_tables) <= set(spec.owned_tables) + assert all(isinstance(column, str) and column for column in spec.regional_group_tables.values()) + # Every extension attaches model components; data loading is optional. + assert spec.register_model_components is not None + + +@pytest.mark.parametrize('extension_id', EXTENSION_IDS) +def test_extension_schema_matches_owned_tables(extension_id: str) -> None: + """If the extension ships a schema, it defines every owned table. + + Extensions that only add components feeding from existing tables own no + tables and need not provide a schema file. + """ + spec = get_known_extension_specs()[extension_id] + if spec.schema_sql_path is None: + # No schema means the extension introduces no tables of its own. + assert not spec.owned_tables + return + schema_path = Path(spec.schema_sql_path) + assert schema_path.is_file() + schema_sql = schema_path.read_text(encoding='utf-8') + for table in spec.owned_tables: + assert table in schema_sql + + +@pytest.mark.parametrize('extension_id', EXTENSION_IDS) +def test_extension_adds_components(extension_id: str) -> None: + """Enabling the extension attaches new model components, including constraints.""" + added = _added_components(extension_id) + assert added, f'{extension_id} should attach components to the model' + assert any(isinstance(component, Constraint) for component in added.values()), ( + f'{extension_id} should contribute at least one constraint' + ) + + +def test_unknown_extension_id_rejected() -> None: + """Resolving an unregistered extension id raises a descriptive error.""" + with pytest.raises(ValueError, match='Unknown extension id'): + resolve_extension_specs(['not_a_real_extension']) diff --git a/tests/test_full_runs.py b/tests/test_full_runs.py index 45ca7d1bf..c71f9b4c8 100644 --- a/tests/test_full_runs.py +++ b/tests/test_full_runs.py @@ -5,7 +5,7 @@ import logging import sqlite3 from pathlib import Path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, TypedDict import pytest from pyomo.core import Constraint, Var @@ -37,6 +37,37 @@ stochastic_files = [{'name': 'stochastic utopia', 'filename': 'config_utopia_stochastic.toml'}] +class MyopicSettings(TypedDict): + view_depth: int + step_size: int + evolving: bool + + +class MyopicStressCase(TypedDict): + name: str + filename: str + myopic: MyopicSettings + + +myopic_stress_tests: list[MyopicStressCase] = [ + { + 'name': ( + f'myopic capacities | {"evolving" if evolving else "non-evolving"}' + f' | view={view_depth} step={step_size}' + ), + 'filename': 'config_myopic_capacities.toml', + 'myopic': { + 'view_depth': view_depth, + 'step_size': step_size, + 'evolving': evolving, + }, + } + for evolving in (False, True) + for view_depth in [1, 3, 6] + for step_size in range(1, view_depth + 1, 2) +] + + @pytest.mark.parametrize( 'system_test_run', argvalues=legacy_config_files, @@ -129,6 +160,33 @@ def test_myopic_utopia( ) +@pytest.mark.parametrize( + 'system_test_run', + argvalues=myopic_stress_tests, + indirect=True, + ids=[d['name'] for d in myopic_stress_tests], +) +def test_myopic_stress_tests( + system_test_run: tuple[str, SolverResults | None, TemoaModel | None, TemoaSequencer], +) -> None: + """ + The idea of these is that they should be tightly constrained so that if anything + is wrong the model will fail to find a feasible solution. Use lots of equality constraints + """ + _, _, _, sequencer = system_test_run + import contextlib + + with contextlib.closing(sqlite3.connect(sequencer.config.output_database)) as con: + cur = con.cursor() + res = cur.execute('SELECT SUM(total_system_cost) FROM main.output_objective').fetchone() + obj = res[0] + # This part is just a very rough check on the objective function. Constraints inside the + # model are extremely tight so any other changes will lead to infeasibility + assert obj == pytest.approx(32, abs=1), ( + 'objective function value did not match expected for myopic stress test' + ) + + @pytest.mark.parametrize( 'system_test_run', argvalues=stochastic_files, diff --git a/tests/testing_configs/config_myopic_capacities.toml b/tests/testing_configs/config_myopic_capacities.toml new file mode 100644 index 000000000..db2d11539 --- /dev/null +++ b/tests/testing_configs/config_myopic_capacities.toml @@ -0,0 +1,24 @@ +scenario = "test myopic capacities" +scenario_mode = "myopic" +extensions= ["growth_rates"] +input_database = "tests/testing_outputs/myopic_capacities.sqlite" +output_database = "tests/testing_outputs/myopic_capacities.sqlite" +neos = false +solver_name = "appsi_highs" +save_excel = true +save_duals = true +save_lp_file = false +time_sequencing = "seasonal_timeslices" +days_per_period = 365 +reserve_margin = "static" + +[MGA] +slack = 0.1 +iterations = 4 +weight = "integer" + +[myopic] +view_depth = 1 +step_size = 1 +evolving = false +evolution_script = '' diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 9df6b3f7a..2f253a8ce 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -181,7 +181,6 @@ 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',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'); REPLACE INTO "time_period_type" VALUES('e','existing vintages'); diff --git a/tests/testing_data/mediumville_sets.json b/tests/testing_data/mediumville_sets.json index 82bf63afd..acc5b16ea 100644 --- a/tests/testing_data/mediumville_sets.json +++ b/tests/testing_data/mediumville_sets.json @@ -31,6 +31,7 @@ "flow_in_storage_rpsditvo": "ff680754a218ee843941e77bd07cbc5e5afd74e2b7b29a76ea86621624e8c0fd", "flow_var_annual_rpitvo": "6f5c569787fbf1e0a4076011f75fcd50a840bac85bb57b026f4fc5682739f888", "flow_var_rpsditvo": "e8c35c3b7b1f0c0e10e6f53e94d0c6b8a884c0dd048675cbeb9e7df33794161b", + "lifetime_tech_rt": "6786f2e9acdccce907ebad50d2ea70481bff72a749253e78168d29b480b07f65", "lifetime_process_rtv": "212639322f29aa7687eb9962fb9d74ef60961d720a2a753e2af53473b9e1648f", "limit_activity_constraint_rpt": "90461349933d0b32167abdca242233004b66212b57ed57213dce6f6818203963", "limit_activity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", @@ -38,13 +39,7 @@ "limit_annual_capacity_factor_constraint_rtvo": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_capacity_constraint_rpt": "118826dabd14af75ae09adbd5bdbba750528b3d59907cbfba3690223ffc7def7", "limit_capacity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_emission_constraint_rpe": "9bf30514ecc261370f67cd0c2e18194f45ff14c15764d274cc342a5a27eaf2a0", - "limit_growth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_constraint_rtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_share_constraint_rggv": "296e4148565f752973655692bae04ebf50877bd13fe9cec8f9563f347a61d885", "limit_resource_constraint_rt": "b9b44ae8bc9642da0a81202877bd69f0b35ce193e31590dd3325ac0828edb5cf", @@ -101,7 +96,7 @@ "tech_uncap": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "tech_upramping": "ddcf6ff7665c2a8acc4dff1b43655fae1b5a265135cbee18cec638df4e954346", "tech_with_capacity": "24f75b6f705a36033456d02638e7c50667908c45c474151fb8490666d928c63f", - "time_exist": "91a2461c25439830d94bf4b3d3a3b020343f75e74561a913b1f972b2ac42e943", + "time_exist": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "time_future": "6b150df8e12ac4dd15396b52f304c7935a41d2cc4da498186552819973171389", "time_manual": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "time_of_day": "f9bbfe9130c510cba59a13e8b385b4d0206196abbdfe8032b995502bb7215f76", @@ -109,7 +104,7 @@ "time_season": "1e413891065e24bbf66543d4747ff12b1c65bf23c4ff9857b0bf0520eccd7f21", "time_season_sequential": "1e413891065e24bbf66543d4747ff12b1c65bf23c4ff9857b0bf0520eccd7f21", "time_sequencing": "91f69c8abab9959c1f8c90f5aaa56db29bccc67e37d12673ab41c54e4179d7ca", - "vintage_all": "947dd08ad4812a98649b4306e4a0ca1b51374d86f1a8e27c3a8af3b189bcc0f6", - "vintage_exist": "91a2461c25439830d94bf4b3d3a3b020343f75e74561a913b1f972b2ac42e943", + "vintage_all": "9c9380fb50cd4f4f9e2032bd9a18645ae4fc1d30335672c62c897bcb9e099ba5", + "vintage_exist": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "vintage_optimize": "9c9380fb50cd4f4f9e2032bd9a18645ae4fc1d30335672c62c897bcb9e099ba5" } diff --git a/tests/testing_data/myopic_capacities.sql b/tests/testing_data/myopic_capacities.sql new file mode 100644 index 000000000..f561e073f --- /dev/null +++ b/tests/testing_data/myopic_capacities.sql @@ -0,0 +1,242 @@ +REPLACE INTO metadata VALUES('DB_MAJOR',4,''); +REPLACE INTO metadata VALUES('DB_MINOR',0,''); +REPLACE INTO metadata_real VALUES('global_discount_rate',0.05000000000000000277,'Discount Rate for future costs'); +REPLACE INTO metadata_real VALUES('default_loan_rate',0.05000000000000000277,'Default Loan Rate if not specified in loan_rate table'); +REPLACE INTO sector_label VALUES('energy',NULL); +REPLACE INTO commodity VALUES('source','s',NULL,NULL); +REPLACE INTO commodity VALUES('demand','d',NULL,NULL); +REPLACE INTO commodity_type VALUES('p','physical commodity'); +REPLACE INTO commodity_type VALUES('a','annual commodity'); +REPLACE INTO commodity_type VALUES('e','emissions commodity'); +REPLACE INTO commodity_type VALUES('d','demand commodity'); +REPLACE INTO commodity_type VALUES('s','source commodity'); +REPLACE INTO commodity_type VALUES('w','waste commodity'); +REPLACE INTO commodity_type VALUES('wa','waste annual commodity'); +REPLACE INTO commodity_type VALUES('wp','waste physical commodity'); +REPLACE INTO cost_fixed VALUES('region',2025,'tech_ancient',1994,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2025,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2030,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2035,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2040,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2025,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2030,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2035,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2040,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2045,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2030,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2035,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2040,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2045,'tech_future',2045,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_future',2050,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2035,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2040,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2045,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_future',2045,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2040,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2045,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2045,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_fixed VALUES('region',2050,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_future',2045,1.0,NULL,NULL); +REPLACE INTO cost_invest VALUES('region','tech_future',2050,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2025,'tech_ancient',1994,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2025,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2030,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2035,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2040,'tech_old',2010,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2025,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2030,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2035,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2040,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2045,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_current',2025,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2030,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2035,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2040,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2045,'tech_future',2045,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_future',2050,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2035,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2040,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2045,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_future',2045,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2040,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2045,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_future',2040,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2045,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_future',2035,1.0,NULL,NULL); +REPLACE INTO cost_variable VALUES('region',2050,'tech_future',2030,1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2025,'demand',1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2030,'demand',1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2035,'demand',1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2040,'demand',1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2045,'demand',1.0,NULL,NULL); +REPLACE INTO demand VALUES('region',2050,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_old',2010,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_current',2025,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_future',2030,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_future',2035,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_future',2040,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_future',2045,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_future',2050,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_ancient',1994,'demand',1.0,NULL,NULL); +REPLACE INTO efficiency VALUES('region','source','tech_retire',2010,'demand',1.0,NULL,NULL); +REPLACE INTO existing_capacity VALUES('region','tech_ancient',1990,3.0,NULL,NULL); +REPLACE INTO existing_capacity VALUES('region','tech_old',2010,0.6999999999999999556,NULL,NULL); +REPLACE INTO existing_capacity VALUES('region','tech_ancient',1994,3.0,NULL,NULL); +REPLACE INTO existing_capacity VALUES('region','tech_retire',2010,1.0,NULL,NULL); +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 lifetime_tech VALUES('region','tech_retire',35.0,NULL,NULL); +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 limit_growth_capacity VALUES('region','tech_ancient','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_capacity VALUES('region','tech_old','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_capacity VALUES('region','tech_current','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_capacity VALUES('region','tech_future','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_capacity VALUES('region','tech_ancient','le',1.0,2.0,NULL,NULL); +REPLACE INTO limit_degrowth_capacity VALUES('region','tech_old','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_capacity VALUES('region','tech_current','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_capacity VALUES('region','tech_future','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity VALUES('region','tech_ancient','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity VALUES('region','tech_old','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity VALUES('region','tech_current','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity VALUES('region','tech_future','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity VALUES('region','tech_ancient','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity VALUES('region','tech_old','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity VALUES('region','tech_current','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity VALUES('region','tech_future','le',1.0,1.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity_delta VALUES('region','tech_ancient','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity_delta VALUES('region','tech_old','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity_delta VALUES('region','tech_current','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_growth_new_capacity_delta VALUES('region','tech_future','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity_delta VALUES('region','tech_ancient','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity_delta VALUES('region','tech_old','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity_delta VALUES('region','tech_current','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_degrowth_new_capacity_delta VALUES('region','tech_future','le',0.0,2.0,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2025,'tech_ancient','e',0.04800000000000000099,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2025,'tech_current','e',0.6520000000000000239,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2030,'tech_current','e',0.5823319839999999692,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2035,'tech_current','e',0.4500000000000000111,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2040,'tech_current','e',0.25,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2030,'tech_future','e',0.2964180160000000063,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2035,'tech_future','e',0.5100000000000000088,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2040,'tech_future','e',0.7349999999999999867,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2045,'tech_future','e',1.0,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2050,'tech_future','e',1.0,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2025,'tech_old','e',0.2999910000000000076,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2030,'tech_old','e',0.1212499999999999967,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2035,'tech_old','e',0.04000000000000000083,NULL,NULL); +REPLACE INTO limit_activity VALUES('region',2040,'tech_old','e',0.01499999999999999945,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2025,'tech_ancient','e',0.04800000000000000099,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2025,'tech_current','e',0.6520000000000000239,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2030,'tech_current','e',0.5823319839999999692,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2035,'tech_current','e',0.4500000000000000111,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2040,'tech_current','e',0.25,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2045,'tech_current','e',0.0,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2050,'tech_current','e',0.0,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2030,'tech_future','e',0.2964180160000000063,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2035,'tech_future','e',0.5100000000000000088,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2040,'tech_future','e',0.7349999999999999867,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2045,'tech_future','e',1.0,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2050,'tech_future','e',1.0,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2025,'tech_old','e',0.2999999999999999889,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2025,'tech_retire','e',9.000000000000000228e-06,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2030,'tech_old','e',0.1212499999999999967,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2035,'tech_old','e',0.04000000000000000083,NULL,NULL); +REPLACE INTO limit_capacity VALUES('region',2040,'tech_old','e',0.01499999999999999945,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_current',2025,'e',0.659919028340081093,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_future',2030,'e',0.3000182348178138114,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_future',2035,'e',0.232573854939435165,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_future',2040,'e',0.2884229446031822408,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_future',2045,'e',0.4110596210476472612,NULL,NULL); +REPLACE INTO limit_new_capacity VALUES('region','tech_future',2050,'e',0.2251165192346591404,NULL,NULL); +REPLACE INTO region VALUES('region',NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',1990,'tech_ancient',1990,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2025,'tech_ancient',1990,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2010,'tech_old',2010,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2015,'tech_old',2010,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2020,'tech_old',2010,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2025,'tech_old',2010,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2030,'tech_old',2010,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2035,'tech_old',2010,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_old',2010,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2025,'tech_current',2025,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2030,'tech_current',2025,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2035,'tech_current',2025,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2040,'tech_current',2025,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_current',2025,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_current',2025,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2060,'tech_current',2025,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2030,'tech_future',2030,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2035,'tech_future',2030,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2040,'tech_future',2030,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_future',2030,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_future',2030,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2055,'tech_future',2030,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2065,'tech_future',2030,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2035,'tech_future',2035,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2040,'tech_future',2035,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_future',2035,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_future',2035,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2055,'tech_future',2035,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2060,'tech_future',2035,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2070,'tech_future',2035,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2040,'tech_future',2040,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_future',2040,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_future',2040,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2055,'tech_future',2040,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2060,'tech_future',2040,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2065,'tech_future',2040,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2075,'tech_future',2040,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2045,'tech_future',2045,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_future',2045,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2055,'tech_future',2045,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2060,'tech_future',2045,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2065,'tech_future',2045,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2070,'tech_future',2045,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2080,'tech_future',2045,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2050,'tech_future',2050,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2055,'tech_future',2050,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2060,'tech_future',2050,0.8800000000000001154,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2065,'tech_future',2050,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2070,'tech_future',2050,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2075,'tech_future',2050,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2085,'tech_future',2050,0.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',1994,'tech_ancient',1994,1.0,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',1999,'tech_ancient',1994,0.969999999999999974,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2004,'tech_ancient',1994,0.8800000000000000044,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2009,'tech_ancient',1994,0.6199999999999999956,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2014,'tech_ancient',1994,0.2700000000000000177,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2019,'tech_ancient',1994,0.08000000000000000166,NULL); +REPLACE INTO lifetime_survival_curve VALUES('region',2029,'tech_ancient',1994,0.0,NULL); +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',24.0,NULL); +REPLACE INTO time_period VALUES(-3,1990,'e'); +REPLACE INTO time_period VALUES(-2,1994,'e'); +REPLACE INTO time_period VALUES(-1,2010,'e'); +REPLACE INTO time_period VALUES(0,2025,'f'); +REPLACE INTO time_period VALUES(1,2030,'f'); +REPLACE INTO time_period VALUES(2,2035,'f'); +REPLACE INTO time_period VALUES(3,2040,'f'); +REPLACE INTO time_period VALUES(4,2045,'f'); +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 technology VALUES('tech_ancient','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_old','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_current','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_future','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_retire','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); +REPLACE INTO time_season VALUES(0,'s',1.0,NULL); diff --git a/tests/testing_data/test_system_sets.json b/tests/testing_data/test_system_sets.json index 35cd0b4cf..f5a33a549 100644 --- a/tests/testing_data/test_system_sets.json +++ b/tests/testing_data/test_system_sets.json @@ -31,6 +31,7 @@ "flow_in_storage_rpsditvo": "8c97fbeacbca1a772ba04f63d0a82f7703500f83c0dc602114b17c64ad4d2e28", "flow_var_annual_rpitvo": "f98f5f41c5cba8ce2a894734abbc5e90310b695bee3c24c52acd8b4800c5ab85", "flow_var_rpsditvo": "784d98e451a8dcf0122f475c2e229162d99e403bdea85f7c608a3d86e850db44", + "lifetime_tech_rt": "984cc175a7aa58e77bb626e3237ca9bf625f5d9b15250870bef1cddc5f57f642", "lifetime_process_rtv": "5033502364848a3a3f295f1b3d051531ecd5c1e5f8bbaecd61afcd18181225ab", "limit_activity_constraint_rpt": "2561103e7e6dd3dee3ba5832290ab5e933f4af08661dff4f2e661b6f4ffefc86", "limit_activity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", @@ -38,13 +39,7 @@ "limit_annual_capacity_factor_constraint_rtvo": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_capacity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_emission_constraint_rpe": "6f11e4ee041970584903d5afba7ee1147824b233260422564fdf0c701e9fabde", - "limit_growth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_constraint_rtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_share_constraint_rggv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_resource_constraint_rt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", @@ -63,7 +58,7 @@ "new_capacity_var_rtv": "bc0ec9e7f812410cb2af924cbc99a31c6e99cd95fc2de26193daad38f33cc132", "operator": "74d830836f1399fb336a0432dde7d7bd36cffa3ff76b1c42d7945350cfb9bf91", "ordered_season_sequential": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "process_life_frac_rptv": "5501652d0145dbf7c2e8c006aabd3dbb85ca64ed5caf1d8f45a1957274af81ca", + "process_life_frac_rptv": "d1b75ede9f90899b1c1cbc56489bf9d12c52abc6c0466eb5fe4dccaf6f3be800", "ramp_down_day_constraint_rpsdtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "ramp_down_season_constraint_rpsstv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "ramp_up_day_constraint_rpsdtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", diff --git a/tests/testing_data/utopia_sets.json b/tests/testing_data/utopia_sets.json index 628c177da..6d9adc1a5 100644 --- a/tests/testing_data/utopia_sets.json +++ b/tests/testing_data/utopia_sets.json @@ -31,6 +31,7 @@ "flow_in_storage_rpsditvo": "99eb864a26adcb6633c95462649bca3ef7096f67682702915d7769b54b5de386", "flow_var_annual_rpitvo": "4053866a304af0a6b9a1d293ddaf358dfee5b170dcb01d41e6bc52437908a98a", "flow_var_rpsditvo": "350739a59b14969da094cf1c95524134b9c9acd0989710456a8dcc6596d0a401", + "lifetime_tech_rt": "7b3703e1f021594993a54c55427a599ed03fc512cf34826b7a7670eb93edfb9a", "lifetime_process_rtv": "2cfc288b15f25957dfc70f6396d97ad655ecbed91c5a11582329749f1fb3dbd7", "limit_activity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_activity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", @@ -38,13 +39,7 @@ "limit_annual_capacity_factor_constraint_rtvo": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_capacity_constraint_rpt": "5a43de033187da68c612c5bcef6a76edb6ab9806464b6d865e46d289ccbbd815", "limit_capacity_share_constraint_rpgg": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_degrowth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_emission_constraint_rpe": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "limit_growth_new_capacity_delta_constraint_rpt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_constraint_rtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_new_capacity_share_constraint_rggv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "limit_resource_constraint_rt": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", @@ -63,7 +58,7 @@ "new_capacity_var_rtv": "d4f1cc8b432075001befddab648d54d1f82a29099236948845393a193b6add5b", "operator": "74d830836f1399fb336a0432dde7d7bd36cffa3ff76b1c42d7945350cfb9bf91", "ordered_season_sequential": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", - "process_life_frac_rptv": "37ad263f78986f4d38c63278a0d1a5a85b3eb8b833e8bfabbbea254eaf3a3efb", + "process_life_frac_rptv": "63d17957ee2bebf664ffa6a39cea5e16ec65ad07db1df24dcea6b15bb9ebf589", "ramp_down_day_constraint_rpsdtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "ramp_down_season_constraint_rpsstv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", "ramp_up_day_constraint_rpsdtv": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", diff --git a/tests/testing_data/utopia_v3.sql b/tests/testing_data/utopia_v3.sql new file mode 100644 index 000000000..c480d93b6 --- /dev/null +++ b/tests/testing_data/utopia_v3.sql @@ -0,0 +1,1558 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE MetaData +( + element TEXT, + value INT, + notes TEXT, + PRIMARY KEY (element) +); +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, + value REAL, + notes TEXT, + + PRIMARY KEY (element) +); +INSERT INTO MetaDataReal VALUES('default_loan_rate',0.05000000000000000277,'Default Loan Rate if not specified in LoanRate table'); +INSERT INTO MetaDataReal VALUES('global_discount_rate',0.05000000000000000277,''); +CREATE TABLE OutputDualVariable +( + scenario TEXT, + constraint_name TEXT, + dual REAL, + PRIMARY KEY (constraint_name, scenario) +); +CREATE TABLE OutputObjective +( + scenario TEXT, + objective_name TEXT, + total_system_cost REAL +); +CREATE TABLE SeasonLabel +( + season TEXT PRIMARY KEY, + notes TEXT +); +INSERT INTO SeasonLabel VALUES('inter',NULL); +INSERT INTO SeasonLabel VALUES('summer',NULL); +INSERT INTO SeasonLabel VALUES('winter',NULL); +CREATE TABLE SectorLabel +( + sector TEXT PRIMARY KEY, + notes TEXT +); +INSERT INTO SectorLabel VALUES('supply',NULL); +INSERT INTO SectorLabel VALUES('electric',NULL); +INSERT INTO SectorLabel VALUES('transport',NULL); +INSERT INTO SectorLabel VALUES('commercial',NULL); +INSERT INTO SectorLabel VALUES('residential',NULL); +INSERT INTO SectorLabel VALUES('industrial',NULL); +CREATE TABLE CapacityCredit +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER, + credit REAL, + notes TEXT, + PRIMARY KEY (region, period, tech, vintage), + CHECK (credit >= 0 AND credit <= 1) +); +CREATE TABLE CapacityFactorProcess +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER, + factor REAL, + notes TEXT, + PRIMARY KEY (region, period, season, tod, tech, vintage), + CHECK (factor >= 0 AND factor <= 1) +); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'inter','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'inter','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'winter','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'winter','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'summer','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2000,'summer','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'inter','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'inter','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'winter','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'winter','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'summer','day','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'summer','night','E31',2000,0.2752999999999999892,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'inter','day','E31',2010,0.2756000000000000116,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'inter','night','E31',2010,0.2756000000000000116,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'winter','day','E31',2010,0.2756000000000000116,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'winter','night','E31',2010,0.2756000000000000116,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'summer','day','E31',2010,0.2756000000000000116,''); +INSERT INTO CapacityFactorProcess VALUES('utopia',2010,'summer','night','E31',2010,0.2756000000000000116,''); +CREATE TABLE CapacityFactorTech +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + tech TEXT + REFERENCES Technology (tech), + factor REAL, + notes TEXT, + PRIMARY KEY (region, period, season, tod, tech), + CHECK (factor >= 0 AND factor <= 1) +); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'inter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'winter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',1990,'summer','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'inter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'winter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2000,'summer','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','day','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','night','E01',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','day','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','night','E21',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','day','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','night','E31',0.2750000000000000222,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','day','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','night','E51',0.1700000000000000122,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'inter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'winter','night','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','day','E70',0.8000000000000000444,''); +INSERT INTO CapacityFactorTech VALUES('utopia',2010,'summer','night','E70',0.8000000000000000444,''); +CREATE TABLE CapacityToActivity +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + c2a REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +INSERT INTO CapacityToActivity VALUES('utopia','E01',31.53999999999999915,''); +INSERT INTO CapacityToActivity VALUES('utopia','E21',31.53999999999999915,''); +INSERT INTO CapacityToActivity VALUES('utopia','E31',31.53999999999999915,''); +INSERT INTO CapacityToActivity VALUES('utopia','E51',31.53999999999999915,''); +INSERT INTO CapacityToActivity VALUES('utopia','E70',31.53999999999999915,''); +INSERT INTO CapacityToActivity VALUES('utopia','RHE',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','RHO',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','RL1',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','SRE',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','TXD',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','TXE',1.0,''); +INSERT INTO CapacityToActivity VALUES('utopia','TXG',1.0,''); +CREATE TABLE Commodity +( + name TEXT + PRIMARY KEY, + flag TEXT + REFERENCES CommodityType (label), + description TEXT +); +INSERT INTO Commodity VALUES('ethos','s','# dummy commodity to supply inputs (makes graph easier to read)'); +INSERT INTO Commodity VALUES('DSL','p','# diesel'); +INSERT INTO Commodity VALUES('ELC','p','# electricity'); +INSERT INTO Commodity VALUES('FEQ','p','# fossil equivalent'); +INSERT INTO Commodity VALUES('GSL','p','# gasoline'); +INSERT INTO Commodity VALUES('HCO','p','# coal'); +INSERT INTO Commodity VALUES('HYD','p','# water'); +INSERT INTO Commodity VALUES('OIL','p','# crude oil'); +INSERT INTO Commodity VALUES('URN','p','# uranium'); +INSERT INTO Commodity VALUES('co2','e','#CO2 emissions'); +INSERT INTO Commodity VALUES('nox','e','#NOX emissions'); +INSERT INTO Commodity VALUES('RH','d','# residential heating'); +INSERT INTO Commodity VALUES('RL','d','# residential lighting'); +INSERT INTO Commodity VALUES('TX','d','# transportation'); +CREATE TABLE CommodityType +( + label TEXT + PRIMARY KEY, + description TEXT +); +INSERT INTO CommodityType VALUES('w','waste commodity'); +INSERT INTO CommodityType VALUES('wa','waste annual commodity'); +INSERT INTO CommodityType VALUES('wp','waste physical commodity'); +INSERT INTO CommodityType VALUES('a','annual commodity'); +INSERT INTO CommodityType VALUES('s','source commodity'); +INSERT INTO CommodityType VALUES('p','physical commodity'); +INSERT INTO CommodityType VALUES('e','emissions commodity'); +INSERT INTO CommodityType VALUES('d','demand commodity'); +CREATE TABLE ConstructionInput +( + region TEXT, + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + value REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, input_comm, tech, vintage) +); +CREATE TABLE CostEmission +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + emis_comm TEXT NOT NULL + REFERENCES Commodity (name), + cost REAL NOT NULL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, emis_comm) +); +CREATE TABLE CostFixed +( + region TEXT NOT NULL, + period INTEGER NOT NULL + REFERENCES TimePeriod (period), + tech TEXT NOT NULL + REFERENCES Technology (tech), + vintage INTEGER NOT NULL + REFERENCES TimePeriod (period), + cost REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, tech, vintage) +); +INSERT INTO CostFixed VALUES('utopia',1990,'E01',1960,40.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E01',1970,40.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E01',1980,40.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E01',1990,40.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E01',1970,70.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E01',1980,70.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E01',1990,70.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E01',2000,70.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E01',1980,100.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E01',1990,100.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E01',2000,100.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E01',2010,100.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E21',1990,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E21',1990,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E21',1990,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E21',2000,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E21',2000,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E21',2010,500.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E31',1980,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E31',1990,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E31',1980,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E31',1990,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E31',2000,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E31',1980,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E31',1990,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E31',2000,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E31',2010,75.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E51',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E51',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E51',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E51',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E51',2000,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E51',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E51',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E51',2000,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E51',2010,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E70',1960,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E70',1970,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E70',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'E70',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E70',1970,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E70',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E70',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'E70',2000,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E70',1980,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E70',1990,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E70',2000,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'E70',2010,30.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'RHO',1970,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'RHO',1980,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'RHO',1990,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'RHO',1980,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'RHO',1990,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'RHO',2000,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'RHO',1990,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'RHO',2000,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'RHO',2010,1.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'RL1',1980,9.46000000000000086,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'RL1',1990,9.46000000000000086,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'RL1',2000,9.46000000000000086,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'RL1',2010,9.46000000000000086,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXD',1970,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXD',1980,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXD',1990,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXD',1980,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXD',1990,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXD',2000,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXD',2000,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXD',2010,52.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXE',1990,100.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXE',1990,90.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXE',2000,90.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXE',2000,80.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXE',2010,80.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXG',1970,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXG',1980,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',1990,'TXG',1990,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXG',1980,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXG',1990,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2000,'TXG',2000,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXG',2000,48.0,'',''); +INSERT INTO CostFixed VALUES('utopia',2010,'TXG',2010,48.0,'',''); +CREATE TABLE CostInvest +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + cost REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech, vintage) +); +INSERT INTO CostInvest VALUES('utopia','E01',1990,2000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E01',2000,1300.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E01',2010,1200.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E21',1990,5000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E21',2000,5000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E21',2010,5000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E31',1990,3000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E31',2000,3000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E31',2010,3000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E51',1990,900.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E51',2000,900.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E51',2010,900.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E70',1990,1000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E70',2000,1000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','E70',2010,1000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHE',1990,90.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHE',2000,90.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHE',2010,90.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHO',1990,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHO',2000,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','RHO',2010,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','SRE',1990,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','SRE',2000,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','SRE',2010,100.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXD',1990,1044.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXD',2000,1044.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXD',2010,1044.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXE',1990,2000.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXE',2000,1750.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXE',2010,1500.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXG',1990,1044.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXG',2000,1044.0,'',''); +INSERT INTO CostInvest VALUES('utopia','TXG',2010,1044.0,'',''); +CREATE TABLE CostVariable +( + region TEXT NOT NULL, + period INTEGER NOT NULL + REFERENCES TimePeriod (period), + tech TEXT NOT NULL + REFERENCES Technology (tech), + vintage INTEGER NOT NULL + REFERENCES TimePeriod (period), + cost REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, tech, vintage) +); +INSERT INTO CostVariable VALUES('utopia',1990,'IMPDSL1',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'IMPDSL1',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'IMPDSL1',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'IMPGSL1',1990,15.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'IMPGSL1',1990,15.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'IMPGSL1',1990,15.0,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'IMPHCO1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'IMPHCO1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'IMPHCO1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'IMPOIL1',1990,8.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'IMPOIL1',1990,8.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'IMPOIL1',1990,8.0,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'IMPURN1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'IMPURN1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'IMPURN1',1990,2.0,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E01',1960,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E01',1970,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E01',1980,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E01',1990,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E01',1970,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E01',1980,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E01',1990,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E01',2000,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E01',1980,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E01',1990,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E01',2000,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E01',2010,0.2999999999999999889,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E21',1990,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E21',1990,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E21',1990,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E21',2000,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E21',2000,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E21',2010,1.5,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E70',1960,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E70',1970,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E70',1980,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'E70',1990,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E70',1970,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E70',1980,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E70',1990,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'E70',2000,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E70',1980,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E70',1990,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E70',2000,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'E70',2010,0.4000000000000000222,'',''); +INSERT INTO CostVariable VALUES('utopia',1990,'SRE',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'SRE',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2000,'SRE',2000,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'SRE',1990,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'SRE',2000,10.0,'',''); +INSERT INTO CostVariable VALUES('utopia',2010,'SRE',2010,10.0,'',''); +CREATE TABLE Demand +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + commodity TEXT + REFERENCES Commodity (name), + demand REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, commodity) +); +INSERT INTO Demand VALUES('utopia',1990,'RH',25.19999999999999929,'',''); +INSERT INTO Demand VALUES('utopia',2000,'RH',37.79999999999999715,'',''); +INSERT INTO Demand VALUES('utopia',2010,'RH',56.69999999999999574,'',''); +INSERT INTO Demand VALUES('utopia',1990,'RL',5.599999999999999645,'',''); +INSERT INTO Demand VALUES('utopia',2000,'RL',8.400000000000000355,'',''); +INSERT INTO Demand VALUES('utopia',2010,'RL',12.59999999999999965,'',''); +INSERT INTO Demand VALUES('utopia',1990,'TX',5.200000000000000177,'',''); +INSERT INTO Demand VALUES('utopia',2000,'TX',7.799999999999999823,'',''); +INSERT INTO Demand VALUES('utopia',2010,'TX',11.68999999999999951,'',''); +CREATE TABLE DemandSpecificDistribution +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + demand_name TEXT + REFERENCES Commodity (name), + dsd REAL, + notes TEXT, + PRIMARY KEY (region, period, season, tod, demand_name), + CHECK (dsd >= 0 AND dsd <= 1) +); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'inter','day','RH',0.1199999999999999956,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'inter','night','RH',0.05999999999999999778,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'winter','day','RH',0.5466999999999999638,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'winter','night','RH',0.2732999999999999874,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'inter','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'inter','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'summer','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'summer','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'winter','day','RL',0.5,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',1990,'winter','night','RL',0.1000000000000000055,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'inter','day','RH',0.1199999999999999956,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'inter','night','RH',0.05999999999999999778,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'winter','day','RH',0.5466999999999999638,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'winter','night','RH',0.2732999999999999874,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'inter','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'inter','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'summer','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'summer','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'winter','day','RL',0.5,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2000,'winter','night','RL',0.1000000000000000055,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'inter','day','RH',0.1199999999999999956,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'inter','night','RH',0.05999999999999999778,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'winter','day','RH',0.5466999999999999638,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'winter','night','RH',0.2732999999999999874,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'inter','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'inter','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'summer','day','RL',0.1499999999999999945,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'summer','night','RL',0.05000000000000000277,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'winter','day','RL',0.5,''); +INSERT INTO DemandSpecificDistribution VALUES('utopia',2010,'winter','night','RL',0.1000000000000000055,''); +CREATE TABLE EndOfLifeOutput +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + value REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech, vintage, output_comm) +); +CREATE TABLE Efficiency +( + region TEXT, + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + efficiency REAL, + notes TEXT, + PRIMARY KEY (region, input_comm, tech, vintage, output_comm), + CHECK (efficiency > 0) +); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPDSL1',1990,'DSL',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPGSL1',1990,'GSL',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPHCO1',1990,'HCO',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPOIL1',1990,'OIL',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPURN1',1990,'URN',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPFEQ',1990,'FEQ',1.0,''); +INSERT INTO Efficiency VALUES('utopia','ethos','IMPHYD',1990,'HYD',1.0,''); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',1960,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',1970,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',1980,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',1990,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',2000,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HCO','E01',2010,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','FEQ','E21',1990,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','FEQ','E21',2000,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','FEQ','E21',2010,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','URN','E21',1990,'ELC',0.4000000000000000222,'# 1/2.5'); +INSERT INTO Efficiency VALUES('utopia','URN','E21',2000,'ELC',0.4000000000000000222,'# 1/2.5'); +INSERT INTO Efficiency VALUES('utopia','URN','E21',2010,'ELC',0.4000000000000000222,'# 1/2.5'); +INSERT INTO Efficiency VALUES('utopia','HYD','E31',1980,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HYD','E31',1990,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HYD','E31',2000,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','HYD','E31',2010,'ELC',0.3200000000000000066,'# 1/3.125'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',1960,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',1970,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',1980,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',1990,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',2000,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','DSL','E70',2010,'ELC',0.2939999999999999836,'# 1/3.4'); +INSERT INTO Efficiency VALUES('utopia','ELC','E51',1980,'ELC',0.7199999999999999734,'# 1/1.3889'); +INSERT INTO Efficiency VALUES('utopia','ELC','E51',1990,'ELC',0.7199999999999999734,'# 1/1.3889'); +INSERT INTO Efficiency VALUES('utopia','ELC','E51',2000,'ELC',0.7199999999999999734,'# 1/1.3889'); +INSERT INTO Efficiency VALUES('utopia','ELC','E51',2010,'ELC',0.7199999999999999734,'# 1/1.3889'); +INSERT INTO Efficiency VALUES('utopia','ELC','RHE',1990,'RH',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RHE',2000,'RH',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RHE',2010,'RH',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','RHO',1970,'RH',0.6999999999999999556,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','RHO',1980,'RH',0.6999999999999999556,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','RHO',1990,'RH',0.6999999999999999556,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','RHO',2000,'RH',0.6999999999999999556,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','RHO',2010,'RH',0.6999999999999999556,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RL1',1980,'RL',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RL1',1990,'RL',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RL1',2000,'RL',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','RL1',2010,'RL',1.0,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',1990,'DSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',2000,'DSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',2010,'DSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',1990,'GSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',2000,'GSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','OIL','SRE',2010,'GSL',1.0,'# direct translation from PRC_INP2, PRC_OUT'); +INSERT INTO Efficiency VALUES('utopia','DSL','TXD',1970,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','TXD',1980,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','TXD',1990,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','TXD',2000,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','DSL','TXD',2010,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','TXE',1990,'TX',0.8269999999999999574,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','TXE',2000,'TX',0.8269999999999999574,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','ELC','TXE',2010,'TX',0.8269999999999999574,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','GSL','TXG',1970,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','GSL','TXG',1980,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','GSL','TXG',1990,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','GSL','TXG',2000,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +INSERT INTO Efficiency VALUES('utopia','GSL','TXG',2010,'TX',0.2310000000000000108,'# direct translation from DMD_EFF'); +CREATE TABLE EfficiencyVariable +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + efficiency REAL, + notes TEXT, + PRIMARY KEY (region, period, season, tod, input_comm, tech, vintage, output_comm), + CHECK (efficiency > 0) +); +CREATE TABLE EmissionActivity +( + region TEXT, + emis_comm TEXT + REFERENCES Commodity (name), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + activity REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, emis_comm, input_comm, tech, vintage, output_comm) +); +INSERT INTO EmissionActivity VALUES('utopia','co2','ethos','IMPDSL1',1990,'DSL',0.07499999999999999723,'',''); +INSERT INTO EmissionActivity VALUES('utopia','co2','ethos','IMPGSL1',1990,'GSL',0.07499999999999999723,'',''); +INSERT INTO EmissionActivity VALUES('utopia','co2','ethos','IMPHCO1',1990,'HCO',0.0889999999999999819,'',''); +INSERT INTO EmissionActivity VALUES('utopia','co2','ethos','IMPOIL1',1990,'OIL',0.07499999999999999723,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','DSL','TXD',1970,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','DSL','TXD',1980,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','DSL','TXD',1990,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','DSL','TXD',2000,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','DSL','TXD',2010,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','GSL','TXG',1970,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','GSL','TXG',1980,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','GSL','TXG',1990,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','GSL','TXG',2000,'TX',1.0,'',''); +INSERT INTO EmissionActivity VALUES('utopia','nox','GSL','TXG',2010,'TX',1.0,'',''); +CREATE TABLE EmissionEmbodied +( + region TEXT, + emis_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + value REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, emis_comm, tech, vintage) +); +CREATE TABLE EmissionEndOfLife +( + region TEXT, + emis_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + value REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, emis_comm, tech, vintage) +); +CREATE TABLE ExistingCapacity +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + capacity REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech, vintage) +); +INSERT INTO ExistingCapacity VALUES('utopia','E01',1960,0.1749999999999999889,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E01',1970,0.1749999999999999889,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E01',1980,0.1499999999999999945,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E31',1980,0.1000000000000000055,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E51',1980,0.5,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E70',1960,0.05000000000000000277,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E70',1970,0.05000000000000000277,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','E70',1980,0.2000000000000000111,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','RHO',1970,12.5,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','RHO',1980,12.5,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','RL1',1980,5.599999999999999645,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','TXD',1970,0.4000000000000000222,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','TXD',1980,0.2000000000000000111,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','TXG',1970,3.100000000000000088,'',''); +INSERT INTO ExistingCapacity VALUES('utopia','TXG',1980,1.5,'',''); +CREATE TABLE TechGroup +( + group_name TEXT + PRIMARY KEY, + notes TEXT +); +CREATE TABLE LoanLifetimeProcess +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + lifetime REAL, + notes TEXT, + PRIMARY KEY (region, tech, vintage) +); +CREATE TABLE LoanRate +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + rate REAL, + notes TEXT, + PRIMARY KEY (region, tech, vintage) +); +CREATE TABLE LifetimeProcess +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + lifetime REAL, + notes TEXT, + PRIMARY KEY (region, tech, vintage) +); +INSERT INTO LifetimeProcess VALUES('utopia','RL1',1980,20.0,'#forexistingcap'); +INSERT INTO LifetimeProcess VALUES('utopia','TXD',1970,30.0,'#forexistingcap'); +INSERT INTO LifetimeProcess VALUES('utopia','TXD',1980,30.0,'#forexistingcap'); +INSERT INTO LifetimeProcess VALUES('utopia','TXG',1970,30.0,'#forexistingcap'); +INSERT INTO LifetimeProcess VALUES('utopia','TXG',1980,30.0,'#forexistingcap'); +CREATE TABLE LifetimeTech +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + lifetime REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +INSERT INTO LifetimeTech VALUES('utopia','E01',40.0,''); +INSERT INTO LifetimeTech VALUES('utopia','E21',40.0,''); +INSERT INTO LifetimeTech VALUES('utopia','E31',100.0,''); +INSERT INTO LifetimeTech VALUES('utopia','E51',100.0,''); +INSERT INTO LifetimeTech VALUES('utopia','E70',40.0,''); +INSERT INTO LifetimeTech VALUES('utopia','RHE',30.0,''); +INSERT INTO LifetimeTech VALUES('utopia','RHO',30.0,''); +INSERT INTO LifetimeTech VALUES('utopia','RL1',10.0,''); +INSERT INTO LifetimeTech VALUES('utopia','SRE',50.0,''); +INSERT INTO LifetimeTech VALUES('utopia','TXD',15.0,''); +INSERT INTO LifetimeTech VALUES('utopia','TXE',15.0,''); +INSERT INTO LifetimeTech VALUES('utopia','TXG',15.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPDSL1',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPGSL1',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPHCO1',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPOIL1',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPURN1',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPHYD',1000.0,''); +INSERT INTO LifetimeTech VALUES('utopia','IMPFEQ',1000.0,''); +CREATE TABLE Operator +( + operator TEXT PRIMARY KEY, + notes TEXT +); +INSERT INTO Operator VALUES('e','equal to'); +INSERT INTO Operator VALUES('le','less than or equal to'); +INSERT INTO Operator VALUES('ge','greater than or equal to'); +CREATE TABLE LimitGrowthCapacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitDegrowthCapacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitGrowthNewCapacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitDegrowthNewCapacity +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitGrowthNewCapacityDelta +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitDegrowthNewCapacityDelta +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + rate REAL NOT NULL DEFAULT 0, + seed REAL NOT NULL DEFAULT 0, + seed_units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +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) +); +CREATE TABLE LimitActivity +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + activity REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, tech_or_group, operator) +); +CREATE TABLE LimitActivityShare +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + sub_group TEXT, + super_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + share REAL, + notes TEXT, + PRIMARY KEY (region, period, sub_group, super_group, operator) +); +CREATE TABLE LimitAnnualCapacityFactor +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + factor REAL, + notes TEXT, + PRIMARY KEY (region, tech, vintage, operator), + CHECK (factor >= 0 AND factor <= 1) +); +CREATE TABLE LimitCapacity +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + capacity REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, tech_or_group, operator) +); +INSERT INTO LimitCapacity VALUES('utopia',1990,'E31','ge',0.1300000000000000044,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2000,'E31','ge',0.1300000000000000044,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2010,'E31','ge',0.1300000000000000044,'',''); +INSERT INTO LimitCapacity VALUES('utopia',1990,'SRE','ge',0.1000000000000000055,'',''); +INSERT INTO LimitCapacity VALUES('utopia',1990,'E31','le',0.1300000000000000044,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2000,'E31','le',0.1700000000000000122,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2010,'E31','le',0.21000000000000002,'',''); +INSERT INTO LimitCapacity VALUES('utopia',1990,'RHE','le',0.0,'',''); +INSERT INTO LimitCapacity VALUES('utopia',1990,'TXD','le',0.5999999999999999778,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2000,'TXD','le',1.760000000000000008,'',''); +INSERT INTO LimitCapacity VALUES('utopia',2010,'TXD','le',4.759999999999999787,'',''); +CREATE TABLE LimitCapacityShare +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + sub_group TEXT, + super_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + share REAL, + notes TEXT, + PRIMARY KEY (region, period, sub_group, super_group, operator) +); +CREATE TABLE LimitNewCapacity +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + new_cap REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, tech_or_group, operator) +); +CREATE TABLE LimitNewCapacityShare +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + sub_group TEXT, + super_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + share REAL, + notes TEXT, + PRIMARY KEY (region, period, sub_group, super_group, operator) +); +CREATE TABLE LimitResource +( + region TEXT, + tech_or_group TEXT, + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + cum_act REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech_or_group, operator) +); +CREATE TABLE LimitSeasonalCapacityFactor +( + region TEXT + REFERENCES Region (region), + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tech TEXT + REFERENCES Technology (tech), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + factor REAL, + notes TEXT, + PRIMARY KEY(region, period, season, tech, operator) +); +CREATE TABLE LimitTechInputSplit +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + proportion REAL, + notes TEXT, + PRIMARY KEY (region, period, input_comm, tech, operator) +); +CREATE TABLE LimitTechInputSplitAnnual +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + proportion REAL, + notes TEXT, + PRIMARY KEY (region, period, input_comm, tech, operator) +); +CREATE TABLE LimitTechOutputSplit +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech TEXT + REFERENCES Technology (tech), + output_comm TEXT + REFERENCES Commodity (name), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + proportion REAL, + notes TEXT, + PRIMARY KEY (region, period, tech, output_comm, operator) +); +INSERT INTO LimitTechOutputSplit VALUES('utopia',1990,'SRE','DSL','ge',0.6999999999999999556,''); +INSERT INTO LimitTechOutputSplit VALUES('utopia',2000,'SRE','DSL','ge',0.6999999999999999556,''); +INSERT INTO LimitTechOutputSplit VALUES('utopia',2010,'SRE','DSL','ge',0.6999999999999999556,''); +INSERT INTO LimitTechOutputSplit VALUES('utopia',1990,'SRE','GSL','ge',0.2999999999999999889,''); +INSERT INTO LimitTechOutputSplit VALUES('utopia',2000,'SRE','GSL','ge',0.2999999999999999889,''); +INSERT INTO LimitTechOutputSplit VALUES('utopia',2010,'SRE','GSL','ge',0.2999999999999999889,''); +CREATE TABLE LimitTechOutputSplitAnnual +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + tech TEXT + REFERENCES Technology (tech), + output_comm TEXT + REFERENCES Commodity (name), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + proportion REAL, + notes TEXT, + PRIMARY KEY (region, period, tech, output_comm, operator) +); +CREATE TABLE LimitEmission +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + emis_comm TEXT + REFERENCES Commodity (name), + operator TEXT NOT NULL DEFAULT "le" + REFERENCES Operator (operator), + value REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, period, emis_comm, operator) +); +CREATE TABLE LinkedTech +( + primary_region TEXT, + primary_tech TEXT + REFERENCES Technology (tech), + emis_comm TEXT + REFERENCES Commodity (name), + driven_tech TEXT + REFERENCES Technology (tech), + notes TEXT, + PRIMARY KEY (primary_region, primary_tech, emis_comm) +); +CREATE TABLE OutputCurtailment +( + scenario TEXT, + region TEXT, + sector TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES TimePeriod (period), + tod TEXT + REFERENCES TimeOfDay (tod), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + curtailment REAL, + PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) +); +CREATE TABLE OutputNetCapacity +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + period INTEGER + REFERENCES TimePeriod (period), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + capacity REAL, + PRIMARY KEY (region, scenario, period, tech, vintage) +); +CREATE TABLE OutputBuiltCapacity +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + capacity REAL, + PRIMARY KEY (region, scenario, tech, vintage) +); +CREATE TABLE OutputRetiredCapacity +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + period INTEGER + REFERENCES TimePeriod (period), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + cap_eol REAL, + cap_early REAL, + PRIMARY KEY (region, scenario, period, tech, vintage) +); +CREATE TABLE OutputFlowIn +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + flow REAL, + PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) +); +CREATE TABLE OutputFlowOut +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + input_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + output_comm TEXT + REFERENCES Commodity (name), + flow REAL, + PRIMARY KEY (region, scenario, period, season, tod, input_comm, tech, vintage, output_comm) +); +CREATE TABLE OutputStorageLevel +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + 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), + level REAL, + PRIMARY KEY (scenario, region, period, season, tod, tech, vintage) +); +CREATE TABLE PlanningReserveMargin +( + region TEXT + PRIMARY KEY + REFERENCES Region (region), + margin REAL, + notes TEXT +); +CREATE TABLE RampDownHourly +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + rate REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE RampUpHourly +( + region TEXT, + tech TEXT + REFERENCES Technology (tech), + rate REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE Region +( + region TEXT + PRIMARY KEY, + notes TEXT +); +INSERT INTO Region VALUES('utopia',NULL); +CREATE TABLE ReserveCapacityDerate +( + region TEXT, + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER, + factor REAL, + notes TEXT, + PRIMARY KEY (region, period, season, tech, vintage), + CHECK (factor >= 0 AND factor <= 1) +); +CREATE TABLE TimeSegmentFraction +( + period INTEGER + REFERENCES TimePeriod (period), + season TEXT + REFERENCES SeasonLabel (season), + tod TEXT + REFERENCES TimeOfDay (tod), + segfrac REAL, + notes TEXT, + PRIMARY KEY (period, season, tod), + CHECK (segfrac >= 0 AND segfrac <= 1) +); +INSERT INTO TimeSegmentFraction VALUES(1990,'inter','day',0.166699999999999987,'# I-D'); +INSERT INTO TimeSegmentFraction VALUES(1990,'inter','night',0.08329999999999999905,'# I-N'); +INSERT INTO TimeSegmentFraction VALUES(1990,'summer','day',0.166699999999999987,'# S-D'); +INSERT INTO TimeSegmentFraction VALUES(1990,'summer','night',0.08329999999999999905,'# S-N'); +INSERT INTO TimeSegmentFraction VALUES(1990,'winter','day',0.3332999999999999852,'# W-D'); +INSERT INTO TimeSegmentFraction VALUES(1990,'winter','night',0.166699999999999987,'# W-N'); +INSERT INTO TimeSegmentFraction VALUES(2000,'inter','day',0.166699999999999987,'# I-D'); +INSERT INTO TimeSegmentFraction VALUES(2000,'inter','night',0.08329999999999999905,'# I-N'); +INSERT INTO TimeSegmentFraction VALUES(2000,'summer','day',0.166699999999999987,'# S-D'); +INSERT INTO TimeSegmentFraction VALUES(2000,'summer','night',0.08329999999999999905,'# S-N'); +INSERT INTO TimeSegmentFraction VALUES(2000,'winter','day',0.3332999999999999852,'# W-D'); +INSERT INTO TimeSegmentFraction VALUES(2000,'winter','night',0.166699999999999987,'# W-N'); +INSERT INTO TimeSegmentFraction VALUES(2010,'inter','day',0.166699999999999987,'# I-D'); +INSERT INTO TimeSegmentFraction VALUES(2010,'inter','night',0.08329999999999999905,'# I-N'); +INSERT INTO TimeSegmentFraction VALUES(2010,'summer','day',0.166699999999999987,'# S-D'); +INSERT INTO TimeSegmentFraction VALUES(2010,'summer','night',0.08329999999999999905,'# S-N'); +INSERT INTO TimeSegmentFraction VALUES(2010,'winter','day',0.3332999999999999852,'# W-D'); +INSERT INTO TimeSegmentFraction VALUES(2010,'winter','night',0.166699999999999987,'# W-N'); +CREATE TABLE StorageDuration +( + region TEXT, + tech TEXT, + duration REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE LifetimeSurvivalCurve +( + region TEXT NOT NULL, + period INTEGER NOT NULL, + tech TEXT NOT NULL + REFERENCES Technology (tech), + vintage INTEGER NOT NULL + REFERENCES TimePeriod (period), + fraction REAL, + notes TEXT, + PRIMARY KEY (region, period, tech, vintage) +); +CREATE TABLE TechnologyType +( + label TEXT + PRIMARY KEY, + description TEXT +); +INSERT INTO TechnologyType VALUES('p','production technology'); +INSERT INTO TechnologyType VALUES('pb','baseload production technology'); +INSERT INTO TechnologyType VALUES('ps','storage production technology'); +CREATE TABLE TimeOfDay +( + sequence INTEGER UNIQUE, + tod TEXT + PRIMARY KEY +); +INSERT INTO TimeOfDay VALUES(1,'day'); +INSERT INTO TimeOfDay VALUES(2,'night'); +CREATE TABLE TimePeriod +( + sequence INTEGER UNIQUE, + period INTEGER + PRIMARY KEY, + flag TEXT + REFERENCES TimePeriodType (label) +); +INSERT INTO TimePeriod VALUES(1,1960,'e'); +INSERT INTO TimePeriod VALUES(2,1970,'e'); +INSERT INTO TimePeriod VALUES(3,1980,'e'); +INSERT INTO TimePeriod VALUES(4,1990,'f'); +INSERT INTO TimePeriod VALUES(5,2000,'f'); +INSERT INTO TimePeriod VALUES(6,2010,'f'); +INSERT INTO TimePeriod VALUES(7,2020,'f'); +CREATE TABLE TimeSeason +( + period INTEGER + REFERENCES TimePeriod (period), + sequence INTEGER, + season TEXT + REFERENCES SeasonLabel (season), + notes TEXT, + PRIMARY KEY (period, sequence, season) +); +INSERT INTO TimeSeason VALUES(1990,1,'inter',NULL); +INSERT INTO TimeSeason VALUES(1990,2,'summer',NULL); +INSERT INTO TimeSeason VALUES(1990,3,'winter',NULL); +INSERT INTO TimeSeason VALUES(2000,1,'inter',NULL); +INSERT INTO TimeSeason VALUES(2000,2,'summer',NULL); +INSERT INTO TimeSeason VALUES(2000,3,'winter',NULL); +INSERT INTO TimeSeason VALUES(2010,1,'inter',NULL); +INSERT INTO TimeSeason VALUES(2010,2,'summer',NULL); +INSERT INTO TimeSeason VALUES(2010,3,'winter',NULL); +CREATE TABLE TimeSeasonSequential +( + period INTEGER + REFERENCES TimePeriod (period), + sequence INTEGER, + seas_seq TEXT, + season TEXT + REFERENCES SeasonLabel (season), + num_days REAL NOT NULL, + notes TEXT, + PRIMARY KEY (period, sequence, seas_seq, season), + CHECK (num_days > 0) +); +CREATE TABLE TimePeriodType +( + label TEXT + PRIMARY KEY, + description TEXT +); +INSERT INTO TimePeriodType VALUES('e','existing vintages'); +INSERT INTO TimePeriodType VALUES('f','future'); +CREATE TABLE OutputEmission +( + scenario TEXT, + region TEXT, + sector TEXT + REFERENCES SectorLabel (sector), + period INTEGER + REFERENCES TimePeriod (period), + emis_comm TEXT + REFERENCES Commodity (name), + tech TEXT + REFERENCES Technology (tech), + vintage INTEGER + REFERENCES TimePeriod (period), + emission REAL, + PRIMARY KEY (region, scenario, period, emis_comm, tech, vintage) +); +CREATE TABLE RPSRequirement +( + region TEXT NOT NULL + REFERENCES Region (region), + period INTEGER NOT NULL + REFERENCES TimePeriod (period), + tech_group TEXT NOT NULL + REFERENCES TechGroup (group_name), + requirement REAL NOT NULL, + notes TEXT +); +CREATE TABLE TechGroupMember +( + group_name TEXT + REFERENCES TechGroup (group_name), + tech TEXT + REFERENCES Technology (tech), + PRIMARY KEY (group_name, tech) +); +CREATE TABLE Technology +( + tech TEXT NOT NULL PRIMARY KEY, + flag TEXT NOT NULL, + sector TEXT, + category TEXT, + sub_category TEXT, + unlim_cap INTEGER NOT NULL DEFAULT 0, + annual INTEGER NOT NULL DEFAULT 0, + reserve INTEGER NOT NULL DEFAULT 0, + curtail INTEGER NOT NULL DEFAULT 0, + retire INTEGER NOT NULL DEFAULT 0, + flex INTEGER NOT NULL DEFAULT 0, + exchange INTEGER NOT NULL DEFAULT 0, + seas_stor INTEGER NOT NULL DEFAULT 0, + description TEXT, + FOREIGN KEY (flag) REFERENCES TechnologyType (label) +); +INSERT INTO Technology VALUES('IMPDSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported diesel'); +INSERT INTO Technology VALUES('IMPGSL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported gasoline'); +INSERT INTO Technology VALUES('IMPHCO1','p','supply','coal','',1,0,0,0,0,0,0,0,' imported coal'); +INSERT INTO Technology VALUES('IMPOIL1','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported crude oil'); +INSERT INTO Technology VALUES('IMPURN1','p','supply','nuclear','',1,0,0,0,0,0,0,0,' imported uranium'); +INSERT INTO Technology VALUES('IMPFEQ','p','supply','petroleum','',1,0,0,0,0,0,0,0,' imported fossil equivalent'); +INSERT INTO Technology VALUES('IMPHYD','p','supply','hydro','',1,0,0,0,0,0,0,0,' imported water -- doesnt exist in Utopia'); +INSERT INTO Technology VALUES('E01','pb','electric','coal','',0,0,0,0,0,0,0,0,' coal power plant'); +INSERT INTO Technology VALUES('E21','pb','electric','nuclear','',0,0,0,0,0,0,0,0,' nuclear power plant'); +INSERT INTO Technology VALUES('E31','pb','electric','hydro','',0,0,0,0,0,0,0,0,' hydro power'); +INSERT INTO Technology VALUES('E51','ps','electric','electric','',0,0,0,0,0,0,0,0,' electric storage'); +INSERT INTO Technology VALUES('E70','p','electric','petroleum','',0,0,0,0,0,0,0,0,' diesel power plant'); +INSERT INTO Technology VALUES('RHE','p','residential','electric','',0,0,0,0,0,0,0,0,' electric residential heating'); +INSERT INTO Technology VALUES('RHO','p','residential','petroleum','',0,0,0,0,0,0,0,0,' diesel residential heating'); +INSERT INTO Technology VALUES('RL1','p','residential','electric','',0,0,0,0,0,0,0,0,' residential lighting'); +INSERT INTO Technology VALUES('SRE','p','supply','petroleum','',0,0,0,0,0,0,0,0,' crude oil processor'); +INSERT INTO Technology VALUES('TXD','p','transport','petroleum','',0,0,0,0,0,0,0,0,' diesel powered vehicles'); +INSERT INTO Technology VALUES('TXE','p','transport','electric','',0,0,0,0,0,0,0,0,' electric powered vehicles'); +INSERT INTO Technology VALUES('TXG','p','transport','petroleum','',0,0,0,0,0,0,0,0,' gasoline powered vehicles'); +CREATE TABLE OutputCost +( + scenario TEXT, + region TEXT, + sector TEXT REFERENCES SectorLabel (sector), + period INTEGER REFERENCES TimePeriod (period), + tech TEXT REFERENCES Technology (tech), + vintage INTEGER REFERENCES TimePeriod (period), + d_invest REAL, + d_fixed REAL, + d_var REAL, + d_emiss REAL, + invest REAL, + fixed REAL, + var REAL, + emiss REAL, + PRIMARY KEY (scenario, region, period, tech, vintage), + FOREIGN KEY (vintage) REFERENCES TimePeriod (period), + FOREIGN KEY (tech) REFERENCES Technology (tech) +); +COMMIT;